From 1ff609f78ae847fdc48531ead9a020bf2b9f2f08 Mon Sep 17 00:00:00 2001 From: David Jia Date: Wed, 18 Feb 2026 15:37:47 -0800 Subject: [PATCH 1/4] init --- .../core/camera/CameraXCameraSystemTest.kt | 29 +++++++++++++------ .../core/camera/CameraSession.kt | 5 +++- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/core/camera/src/androidTest/java/com/google/jetpackcamera/core/camera/CameraXCameraSystemTest.kt b/core/camera/src/androidTest/java/com/google/jetpackcamera/core/camera/CameraXCameraSystemTest.kt index 37a397443..1c93da4fa 100644 --- a/core/camera/src/androidTest/java/com/google/jetpackcamera/core/camera/CameraXCameraSystemTest.kt +++ b/core/camera/src/androidTest/java/com/google/jetpackcamera/core/camera/CameraXCameraSystemTest.kt @@ -33,6 +33,7 @@ import com.google.jetpackcamera.core.camera.postprocess.PostProcessModule.Compan import com.google.jetpackcamera.core.camera.utils.APP_REQUIRED_PERMISSIONS import com.google.jetpackcamera.core.camera.utils.provideUpdatingSurface import com.google.jetpackcamera.core.common.FakeFilePathGenerator +import com.google.jetpackcamera.model.CaptureMode import com.google.jetpackcamera.model.FlashMode import com.google.jetpackcamera.model.Illuminant import com.google.jetpackcamera.model.LensFacing @@ -240,8 +241,14 @@ class CameraXCameraSystemTest { runSetStabilizationModeTest(StabilizationMode.HIGH_QUALITY) } + @Test + fun setStabilizationMode_off_imageOnly_updatesCameraState(): Unit = runBlocking { + runSetStabilizationModeTest(StabilizationMode.HIGH_QUALITY, CaptureMode.IMAGE_ONLY) + } + private suspend fun CoroutineScope.runSetStabilizationModeTest( - stabilizationMode: StabilizationMode + stabilizationMode: StabilizationMode, + captureMode: CaptureMode = CaptureMode.STANDARD ) { // Arrange. val constraintsRepository = SettableConstraintsRepositoryImpl() @@ -250,14 +257,17 @@ class CameraXCameraSystemTest { appSettings = appSettings, constraintsRepository = constraintsRepository ) - val cameraConstraints = - constraintsRepository.systemConstraints.value?.forCurrentLens(appSettings) - assume().withMessage("Stabilisation $stabilizationMode not supported, skip the test.") - .that( - cameraConstraints != null && cameraConstraints.supportedStabilizationModes.contains( - stabilizationMode - ) - ).isTrue() + if (stabilizationMode != StabilizationMode.OFF) { + val cameraConstraints = + constraintsRepository.systemConstraints.value?.forCurrentLens(appSettings) + assume().withMessage("Stabilisation $stabilizationMode not supported, skip the test.") + .that( + cameraConstraints != null && + cameraConstraints.supportedStabilizationModes.contains( + stabilizationMode + ) + ).isTrue() + } val stabilizationCheck: ReceiveChannel = cameraSystem.getCurrentCameraState() .map { it.stabilizationMode } @@ -269,6 +279,7 @@ class CameraXCameraSystemTest { // Act. cameraSystem.setStabilizationMode(stabilizationMode) + cameraSystem.setCaptureMode(captureMode) // Assert. stabilizationCheck.awaitValue(stabilizationMode) diff --git a/core/camera/src/main/java/com/google/jetpackcamera/core/camera/CameraSession.kt b/core/camera/src/main/java/com/google/jetpackcamera/core/camera/CameraSession.kt index aaf147f53..398441ca7 100644 --- a/core/camera/src/main/java/com/google/jetpackcamera/core/camera/CameraSession.kt +++ b/core/camera/src/main/java/com/google/jetpackcamera/core/camera/CameraSession.kt @@ -753,7 +753,10 @@ private fun createPreviewUseCase( when (stabilizationMode) { StabilizationMode.ON -> setPreviewStabilizationEnabled(true) StabilizationMode.OPTICAL -> setOpticalStabilizationModeEnabled(true) - StabilizationMode.OFF -> setOpticalStabilizationModeEnabled(false) + StabilizationMode.OFF -> { + setOpticalStabilizationModeEnabled(false) + setPreviewStabilizationEnabled(false) + } StabilizationMode.HIGH_QUALITY -> {} // No-op. Handled by VideoCapture use case. else -> throw UnsupportedOperationException( "Unexpected stabilization mode: $stabilizationMode. Stabilization mode should always " + From caa6b66472adb067e9a647d03edb6a40ea118a1f Mon Sep 17 00:00:00 2001 From: David Jia Date: Thu, 19 Feb 2026 13:09:44 -0800 Subject: [PATCH 2/4] address comments --- .../core/camera/CameraXCameraSystemTest.kt | 26 +++++++++---------- .../core/camera/CameraSession.kt | 2 ++ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/core/camera/src/androidTest/java/com/google/jetpackcamera/core/camera/CameraXCameraSystemTest.kt b/core/camera/src/androidTest/java/com/google/jetpackcamera/core/camera/CameraXCameraSystemTest.kt index 1c93da4fa..756a37ecc 100644 --- a/core/camera/src/androidTest/java/com/google/jetpackcamera/core/camera/CameraXCameraSystemTest.kt +++ b/core/camera/src/androidTest/java/com/google/jetpackcamera/core/camera/CameraXCameraSystemTest.kt @@ -243,12 +243,12 @@ class CameraXCameraSystemTest { @Test fun setStabilizationMode_off_imageOnly_updatesCameraState(): Unit = runBlocking { - runSetStabilizationModeTest(StabilizationMode.HIGH_QUALITY, CaptureMode.IMAGE_ONLY) + runSetStabilizationModeTest(StabilizationMode.OFF, CaptureMode.IMAGE_ONLY) } private suspend fun CoroutineScope.runSetStabilizationModeTest( stabilizationMode: StabilizationMode, - captureMode: CaptureMode = CaptureMode.STANDARD + captureMode: CaptureMode? = null ) { // Arrange. val constraintsRepository = SettableConstraintsRepositoryImpl() @@ -257,17 +257,15 @@ class CameraXCameraSystemTest { appSettings = appSettings, constraintsRepository = constraintsRepository ) - if (stabilizationMode != StabilizationMode.OFF) { - val cameraConstraints = - constraintsRepository.systemConstraints.value?.forCurrentLens(appSettings) - assume().withMessage("Stabilisation $stabilizationMode not supported, skip the test.") - .that( - cameraConstraints != null && - cameraConstraints.supportedStabilizationModes.contains( - stabilizationMode - ) - ).isTrue() - } + val cameraConstraints = + constraintsRepository.systemConstraints.value?.forCurrentLens(appSettings) + assume().withMessage("Stabilisation $stabilizationMode not supported, skip the test.") + .that( + cameraConstraints != null && + cameraConstraints.supportedStabilizationModes.contains( + stabilizationMode + ) + ).isTrue() val stabilizationCheck: ReceiveChannel = cameraSystem.getCurrentCameraState() .map { it.stabilizationMode } @@ -279,7 +277,7 @@ class CameraXCameraSystemTest { // Act. cameraSystem.setStabilizationMode(stabilizationMode) - cameraSystem.setCaptureMode(captureMode) + captureMode?.let { cameraSystem.setCaptureMode(it) } // Assert. stabilizationCheck.awaitValue(stabilizationMode) diff --git a/core/camera/src/main/java/com/google/jetpackcamera/core/camera/CameraSession.kt b/core/camera/src/main/java/com/google/jetpackcamera/core/camera/CameraSession.kt index 398441ca7..3bea14136 100644 --- a/core/camera/src/main/java/com/google/jetpackcamera/core/camera/CameraSession.kt +++ b/core/camera/src/main/java/com/google/jetpackcamera/core/camera/CameraSession.kt @@ -755,6 +755,8 @@ private fun createPreviewUseCase( StabilizationMode.OPTICAL -> setOpticalStabilizationModeEnabled(true) StabilizationMode.OFF -> { setOpticalStabilizationModeEnabled(false) + // Setting this to false in Preview use case will disable video stabilization, even in + // IMAGE_ONLY mode where there isn't a video capture use case attached setPreviewStabilizationEnabled(false) } StabilizationMode.HIGH_QUALITY -> {} // No-op. Handled by VideoCapture use case. From 760b18fee23401bb90b8773d8d447b55b2563913 Mon Sep 17 00:00:00 2001 From: David Jia Date: Thu, 19 Feb 2026 13:58:58 -0800 Subject: [PATCH 3/4] spotless --- .../core/camera/CameraXCameraSystemTest.kt | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/core/camera/src/androidTest/java/com/google/jetpackcamera/core/camera/CameraXCameraSystemTest.kt b/core/camera/src/androidTest/java/com/google/jetpackcamera/core/camera/CameraXCameraSystemTest.kt index 756a37ecc..bbb66627d 100644 --- a/core/camera/src/androidTest/java/com/google/jetpackcamera/core/camera/CameraXCameraSystemTest.kt +++ b/core/camera/src/androidTest/java/com/google/jetpackcamera/core/camera/CameraXCameraSystemTest.kt @@ -252,13 +252,14 @@ class CameraXCameraSystemTest { ) { // Arrange. val constraintsRepository = SettableConstraintsRepositoryImpl() - val appSettings = CameraAppSettings(stabilizationMode = StabilizationMode.OFF) val cameraSystem = createAndInitCameraXCameraSystem( - appSettings = appSettings, + appSettings = CameraAppSettings(stabilizationMode = StabilizationMode.OFF), constraintsRepository = constraintsRepository ) val cameraConstraints = - constraintsRepository.systemConstraints.value?.forCurrentLens(appSettings) + constraintsRepository.systemConstraints.value?.forCurrentLens( + DEFAULT_CAMERA_APP_SETTINGS + ) assume().withMessage("Stabilisation $stabilizationMode not supported, skip the test.") .that( cameraConstraints != null && @@ -266,11 +267,19 @@ class CameraXCameraSystemTest { stabilizationMode ) ).isTrue() + cameraSystem.startCameraAndWaitUntilRunning() + if (stabilizationMode == StabilizationMode.OFF) { + val initialStabilizationMode = cameraConstraints?.supportedStabilizationModes + ?.firstOrNull { it != StabilizationMode.OFF } + assume().withMessage("No stabilisation other than OFF is supported, skip the test.") + .that(initialStabilizationMode != null).isTrue() + cameraSystem.setStabilizationMode(initialStabilizationMode!!) + } + val stabilizationCheck: ReceiveChannel = cameraSystem.getCurrentCameraState() .map { it.stabilizationMode } .produceIn(this) - cameraSystem.startCameraAndWaitUntilRunning() // Ensure we start in a state with stabilization mode OFF stabilizationCheck.awaitValue(StabilizationMode.OFF) From 0ef1dfa4d62900a387f7681c7bf79255e269ed90 Mon Sep 17 00:00:00 2001 From: David Jia Date: Thu, 19 Feb 2026 15:17:57 -0800 Subject: [PATCH 4/4] rewrite minor details --- .../core/camera/CameraXCameraSystemTest.kt | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/core/camera/src/androidTest/java/com/google/jetpackcamera/core/camera/CameraXCameraSystemTest.kt b/core/camera/src/androidTest/java/com/google/jetpackcamera/core/camera/CameraXCameraSystemTest.kt index bbb66627d..464c29055 100644 --- a/core/camera/src/androidTest/java/com/google/jetpackcamera/core/camera/CameraXCameraSystemTest.kt +++ b/core/camera/src/androidTest/java/com/google/jetpackcamera/core/camera/CameraXCameraSystemTest.kt @@ -267,22 +267,25 @@ class CameraXCameraSystemTest { stabilizationMode ) ).isTrue() - cameraSystem.startCameraAndWaitUntilRunning() + var initialStabilizationMode: StabilizationMode? = StabilizationMode.OFF if (stabilizationMode == StabilizationMode.OFF) { - val initialStabilizationMode = cameraConstraints?.supportedStabilizationModes + initialStabilizationMode = cameraConstraints?.supportedStabilizationModes ?.firstOrNull { it != StabilizationMode.OFF } assume().withMessage("No stabilisation other than OFF is supported, skip the test.") .that(initialStabilizationMode != null).isTrue() - cameraSystem.setStabilizationMode(initialStabilizationMode!!) + initialStabilizationMode?.let { + cameraSystem.setStabilizationMode(initialStabilizationMode) + } } + cameraSystem.startCameraAndWaitUntilRunning() val stabilizationCheck: ReceiveChannel = cameraSystem.getCurrentCameraState() .map { it.stabilizationMode } .produceIn(this) - // Ensure we start in a state with stabilization mode OFF - stabilizationCheck.awaitValue(StabilizationMode.OFF) + // Ensure we start in a state with the initial stabilization mode + stabilizationCheck.awaitValue(initialStabilizationMode) // Act. cameraSystem.setStabilizationMode(stabilizationMode)