From ea5b8c9d9a009eb867b42dcd4a2eb8265846832c Mon Sep 17 00:00:00 2001 From: David Jia Date: Tue, 20 Jan 2026 13:15:14 -0800 Subject: [PATCH 1/6] Update CameraSession.kt --- .../core/camera/CameraSession.kt | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) 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..4c35840b9 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 @@ -748,13 +748,26 @@ private fun createPreviewUseCase( targetCameraInfo = cameraInfo, captureResults = captureResults ) - + // set preview stabilization when (stabilizationMode) { - StabilizationMode.ON -> setPreviewStabilizationEnabled(true) - StabilizationMode.OPTICAL -> setOpticalStabilizationModeEnabled(true) - StabilizationMode.OFF -> setOpticalStabilizationModeEnabled(false) - StabilizationMode.HIGH_QUALITY -> {} // No-op. Handled by VideoCapture use case. + StabilizationMode.ON -> { + setPreviewStabilizationEnabled(true) + setOpticalStabilizationModeEnabled(false) + } + + StabilizationMode.OPTICAL -> { + setPreviewStabilizationEnabled(false) + setOpticalStabilizationModeEnabled(true) + } + StabilizationMode.OFF -> { + setPreviewStabilizationEnabled(false) + setOpticalStabilizationModeEnabled(false) + } + StabilizationMode.HIGH_QUALITY -> { + setPreviewStabilizationEnabled(false) + setOpticalStabilizationModeEnabled(false) + } // Handled by VideoCapture use case. else -> throw UnsupportedOperationException( "Unexpected stabilization mode: $stabilizationMode. Stabilization mode should always " + "an explicit mode, such as ON, OPTICAL, OFF or HIGH_QUALITY" From 24f1c8ccf31c85e651301065d97a67f427a24a28 Mon Sep 17 00:00:00 2001 From: David Jia Date: Tue, 20 Jan 2026 13:26:09 -0800 Subject: [PATCH 2/6] spotless --- .../java/com/google/jetpackcamera/core/camera/CameraSession.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 4c35840b9..ba32a8e59 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 @@ -748,7 +748,7 @@ private fun createPreviewUseCase( targetCameraInfo = cameraInfo, captureResults = captureResults ) - + // set preview stabilization when (stabilizationMode) { StabilizationMode.ON -> { From 80f3fef0e5c5f1b24501e73b1e6ddf779d6dcf6e Mon Sep 17 00:00:00 2001 From: David Jia Date: Wed, 21 Jan 2026 15:58:49 -0800 Subject: [PATCH 3/6] add tests --- .../core/camera/CameraXCameraSystemTest.kt | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) 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 a4f34d8a4..7b29d42c4 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 @@ -39,11 +39,13 @@ import com.google.jetpackcamera.model.FlashMode import com.google.jetpackcamera.model.Illuminant import com.google.jetpackcamera.model.LensFacing import com.google.jetpackcamera.model.SaveLocation +import com.google.jetpackcamera.model.StabilizationMode import com.google.jetpackcamera.settings.ConstraintsRepository import com.google.jetpackcamera.settings.SettableConstraintsRepository import com.google.jetpackcamera.settings.SettableConstraintsRepositoryImpl import com.google.jetpackcamera.settings.model.CameraAppSettings import com.google.jetpackcamera.settings.model.DEFAULT_CAMERA_APP_SETTINGS +import com.google.jetpackcamera.settings.model.forCurrentLens import java.io.File import java.util.AbstractMap import javax.inject.Provider @@ -225,6 +227,60 @@ class CameraXCameraSystemTest { recordingComplete.await() } + @Test + fun setStabilizationMode_on_updatesCameraState(): Unit = runBlocking { + runSetStabilizationModeTest(StabilizationMode.ON) + } + + @Test + fun setStabilizationMode_optical_updatesCameraState(): Unit = runBlocking { + runSetStabilizationModeTest(StabilizationMode.OPTICAL) + } + + @Test + fun setStabilizationMode_highQuality_updatesCameraState(): Unit = runBlocking { + runSetStabilizationModeTest(StabilizationMode.HIGH_QUALITY) + } + + private suspend fun CoroutineScope.runSetStabilizationModeTest( + stabilizationMode: StabilizationMode + ) { + // Arrange. + val constraintsRepository = SettableConstraintsRepositoryImpl() + val appSettings = DEFAULT_CAMERA_APP_SETTINGS + 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 cameraSystem = createAndInitCameraXCameraSystem( + appSettings = appSettings, + constraintsRepository = constraintsRepository + ) + cameraSystem.startCameraAndWaitUntilRunning() + + val stabilizationCheck: ReceiveChannel = cameraSystem.getCurrentCameraState() + .map { it.stabilizationMode == stabilizationMode } + .produceIn(this) + stabilizationCheck.awaitValue(false) + + // Act. + cameraSystem.setStabilizationMode(stabilizationMode) + val result = cameraSystem.takePicture(context.contentResolver, SaveLocation.Default) {} + + // Assert. + stabilizationCheck.awaitValue(true) + + // Clean-up. + if (result.savedUri != null) { + filesToDelete.add(result.savedUri!!) + } + stabilizationCheck.cancel() + } + @Test fun recordVideoWithFlashModeOn_shouldEnableTorch(): Unit = runBlocking { // Arrange. From 7d1f532a3963725bf396e9fbda88f5a7f05d99ad Mon Sep 17 00:00:00 2001 From: David Jia Date: Tue, 27 Jan 2026 16:26:06 -0800 Subject: [PATCH 4/6] Update CameraXCameraSystemTest.kt --- .../jetpackcamera/core/camera/CameraXCameraSystemTest.kt | 8 ++++---- 1 file changed, 4 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 7b29d42c4..2e12bf5ff 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 @@ -250,16 +250,16 @@ class CameraXCameraSystemTest { val appSettings = DEFAULT_CAMERA_APP_SETTINGS val cameraConstraints = constraintsRepository.systemConstraints.value?.forCurrentLens(appSettings) + val cameraSystem = createAndInitCameraXCameraSystem( + appSettings = appSettings, + constraintsRepository = constraintsRepository + ) assume().withMessage("Stabilisation $stabilizationMode not supported, skip the test.") .that( cameraConstraints != null && cameraConstraints.supportedStabilizationModes.contains( stabilizationMode ) ).isTrue() - val cameraSystem = createAndInitCameraXCameraSystem( - appSettings = appSettings, - constraintsRepository = constraintsRepository - ) cameraSystem.startCameraAndWaitUntilRunning() val stabilizationCheck: ReceiveChannel = cameraSystem.getCurrentCameraState() From 1268ac8e2e44e22841b69303068b6b023dcacdcd Mon Sep 17 00:00:00 2001 From: David Jia Date: Tue, 27 Jan 2026 17:11:23 -0800 Subject: [PATCH 5/6] Update CameraXCameraSystemTest.kt --- .../jetpackcamera/core/camera/CameraXCameraSystemTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 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 2e12bf5ff..97bb7a8c9 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 @@ -248,12 +248,12 @@ class CameraXCameraSystemTest { // Arrange. val constraintsRepository = SettableConstraintsRepositoryImpl() val appSettings = DEFAULT_CAMERA_APP_SETTINGS - val cameraConstraints = - constraintsRepository.systemConstraints.value?.forCurrentLens(appSettings) val cameraSystem = createAndInitCameraXCameraSystem( 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( From 122d27ef1aeb8599f097654a133cc4bb04913290 Mon Sep 17 00:00:00 2001 From: David Jia Date: Tue, 3 Feb 2026 12:28:51 -0800 Subject: [PATCH 6/6] update High_QUALITY case to no-op like before --- .../core/camera/CameraXCameraSystemTest.kt | 26 +++++++++++++------ .../core/camera/CameraSession.kt | 6 ++--- 2 files changed, 20 insertions(+), 12 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 97bb7a8c9..0aac6fe3f 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 @@ -247,7 +247,7 @@ class CameraXCameraSystemTest { ) { // Arrange. val constraintsRepository = SettableConstraintsRepositoryImpl() - val appSettings = DEFAULT_CAMERA_APP_SETTINGS + val appSettings = CameraAppSettings(stabilizationMode = StabilizationMode.OFF) val cameraSystem = createAndInitCameraXCameraSystem( appSettings = appSettings, constraintsRepository = constraintsRepository @@ -260,24 +260,34 @@ class CameraXCameraSystemTest { stabilizationMode ) ).isTrue() - cameraSystem.startCameraAndWaitUntilRunning() - + cameraSystem.setStabilizationMode(stabilizationMode) val stabilizationCheck: ReceiveChannel = cameraSystem.getCurrentCameraState() .map { it.stabilizationMode == stabilizationMode } .produceIn(this) stabilizationCheck.awaitValue(false) + cameraSystem.startCameraAndWaitUntilRunning() // Act. - cameraSystem.setStabilizationMode(stabilizationMode) - val result = cameraSystem.takePicture(context.contentResolver, SaveLocation.Default) {} + val recordingComplete = CompletableDeferred() + cameraSystem.startRecording { + when (it) { + is OnVideoRecorded -> { + recordingComplete.complete(Unit) + } + + is OnVideoRecordError -> recordingComplete.completeExceptionally(it.error) + } + } // Assert. stabilizationCheck.awaitValue(true) + cameraSystem.stopVideoRecording() + + stabilizationCheck.awaitValue(true) + // Clean-up. - if (result.savedUri != null) { - filesToDelete.add(result.savedUri!!) - } + recordingComplete.await() stabilizationCheck.cancel() } 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 ba32a8e59..2ae228315 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 @@ -748,7 +748,6 @@ private fun createPreviewUseCase( targetCameraInfo = cameraInfo, captureResults = captureResults ) - // set preview stabilization when (stabilizationMode) { StabilizationMode.ON -> { @@ -765,9 +764,8 @@ private fun createPreviewUseCase( setOpticalStabilizationModeEnabled(false) } StabilizationMode.HIGH_QUALITY -> { - setPreviewStabilizationEnabled(false) - setOpticalStabilizationModeEnabled(false) - } // Handled by VideoCapture use case. + // No-op. Handled by VideoCapture use case. + } else -> throw UnsupportedOperationException( "Unexpected stabilization mode: $stabilizationMode. Stabilization mode should always " + "an explicit mode, such as ON, OPTICAL, OFF or HIGH_QUALITY"