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..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 @@ -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,70 @@ 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 = CameraAppSettings(stabilizationMode = StabilizationMode.OFF) + 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( + stabilizationMode + ) + ).isTrue() + cameraSystem.setStabilizationMode(stabilizationMode) + val stabilizationCheck: ReceiveChannel = cameraSystem.getCurrentCameraState() + .map { it.stabilizationMode == stabilizationMode } + .produceIn(this) + stabilizationCheck.awaitValue(false) + cameraSystem.startCameraAndWaitUntilRunning() + + // Act. + 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. + recordingComplete.await() + stabilizationCheck.cancel() + } + @Test fun recordVideoWithFlashModeOn_shouldEnableTorch(): Unit = runBlocking { // Arrange. 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..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,13 +748,24 @@ 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 -> { + // 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"