From 09b50938d2000e44ef4b61c81f5b233279cabba1 Mon Sep 17 00:00:00 2001 From: Loewy Date: Thu, 11 Dec 2025 11:48:03 -0800 Subject: [PATCH] get orientation change from WindowManager for android --- .../com/mrousavy/camera/core/CameraSession.kt | 14 ++++++++++++ .../com/mrousavy/camera/core/PreviewView.kt | 22 ++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/package/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt b/package/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt index 6f29157..f669c7e 100644 --- a/package/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt +++ b/package/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt @@ -15,6 +15,7 @@ import android.util.Log import android.util.Size import android.view.Surface import android.view.SurfaceHolder +import android.view.WindowManager import androidx.core.content.ContextCompat import com.google.mlkit.vision.barcode.common.Barcode import com.mrousavy.camera.core.capture.RepeatingCaptureRequest @@ -425,6 +426,19 @@ class CameraSession(private val context: Context, private val cameraManager: Cam val fps = configuration?.fps ?: 30 + // Get actual device rotation from WindowManager instead of relying on + // the orientation prop from React, which may not update on Android when + // rotating between landscape-left and landscape-right. + val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager + val deviceRotation = windowManager.defaultDisplay.rotation + val actualOrientation = when (deviceRotation) { + Surface.ROTATION_0 -> Orientation.PORTRAIT + Surface.ROTATION_90 -> Orientation.LANDSCAPE_LEFT + Surface.ROTATION_180 -> Orientation.PORTRAIT_UPSIDE_DOWN + Surface.ROTATION_270 -> Orientation.LANDSCAPE_RIGHT + else -> Orientation.PORTRAIT + } + val recording = RecordingSession( context, cameraId, diff --git a/package/android/src/main/java/com/mrousavy/camera/core/PreviewView.kt b/package/android/src/main/java/com/mrousavy/camera/core/PreviewView.kt index ef46649..baa95cd 100644 --- a/package/android/src/main/java/com/mrousavy/camera/core/PreviewView.kt +++ b/package/android/src/main/java/com/mrousavy/camera/core/PreviewView.kt @@ -9,8 +9,10 @@ import android.os.Looper import android.util.Log import android.util.Size import android.view.PixelCopy +import android.view.Surface import android.view.SurfaceHolder import android.view.SurfaceView +import android.view.WindowManager import com.facebook.react.bridge.UiThreadUtil import com.mrousavy.camera.extensions.resize import com.mrousavy.camera.extensions.rotatedBy @@ -150,6 +152,8 @@ class PreviewView(context: Context, callback: SurfaceHolder.Callback) : val width = frame.width() val height = frame.height() + // Create bitmap matching surface frame dimensions for PixelCopy + // The original code swapped dimensions assuming landscape input - keep that for consistency val bitmap = Bitmap.createBitmap(height, width, Bitmap.Config.ARGB_8888) // Use a coroutine to suspend until the PixelCopy request is complete @@ -159,7 +163,23 @@ class PreviewView(context: Context, callback: SurfaceHolder.Callback) : bitmap, { copyResult -> if (copyResult == PixelCopy.SUCCESS) { - continuation.resume(rotateBitmap90CounterClockwise(bitmap)) + // Get actual device rotation from WindowManager instead of relying on + // the orientation prop, which may not update on Android when rotating + // between landscape-left and landscape-right. + val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager + val deviceRotation = windowManager.defaultDisplay.rotation + + val actualOrientation = when (deviceRotation) { + Surface.ROTATION_0 -> Orientation.PORTRAIT + Surface.ROTATION_90 -> Orientation.LANDSCAPE_LEFT + Surface.ROTATION_180 -> Orientation.PORTRAIT_UPSIDE_DOWN + Surface.ROTATION_270 -> Orientation.LANDSCAPE_RIGHT + else -> Orientation.PORTRAIT + } + + Log.i(TAG, "getBitmap: orientation prop = $orientation, deviceRotation = $deviceRotation, actualOrientation = $actualOrientation") + + continuation.resume(bitmap.transformBitmap(actualOrientation)) } else { continuation.resumeWithException( RuntimeException("PixelCopy failed with error code $copyResult")