| // Copyright 2013 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| package io.flutter.plugins.camera; |
| |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertNotNull; |
| import static org.mockito.ArgumentMatchers.any; |
| import static org.mockito.ArgumentMatchers.eq; |
| import static org.mockito.Mockito.doThrow; |
| import static org.mockito.Mockito.mock; |
| import static org.mockito.Mockito.never; |
| import static org.mockito.Mockito.times; |
| import static org.mockito.Mockito.verify; |
| import static org.mockito.Mockito.when; |
| |
| import android.app.Activity; |
| import android.hardware.camera2.CameraAccessException; |
| import android.hardware.camera2.CameraCaptureSession; |
| import android.hardware.camera2.CameraMetadata; |
| import android.hardware.camera2.CaptureRequest; |
| import android.media.CamcorderProfile; |
| import android.media.MediaRecorder; |
| import android.os.Build; |
| import androidx.annotation.NonNull; |
| import io.flutter.embedding.engine.systemchannels.PlatformChannel; |
| import io.flutter.plugin.common.MethodChannel; |
| import io.flutter.plugins.camera.features.CameraFeatureFactory; |
| import io.flutter.plugins.camera.features.Point; |
| import io.flutter.plugins.camera.features.autofocus.AutoFocusFeature; |
| import io.flutter.plugins.camera.features.autofocus.FocusMode; |
| import io.flutter.plugins.camera.features.exposurelock.ExposureLockFeature; |
| import io.flutter.plugins.camera.features.exposurelock.ExposureMode; |
| import io.flutter.plugins.camera.features.exposureoffset.ExposureOffsetFeature; |
| import io.flutter.plugins.camera.features.exposurepoint.ExposurePointFeature; |
| import io.flutter.plugins.camera.features.flash.FlashFeature; |
| import io.flutter.plugins.camera.features.flash.FlashMode; |
| import io.flutter.plugins.camera.features.focuspoint.FocusPointFeature; |
| import io.flutter.plugins.camera.features.fpsrange.FpsRangeFeature; |
| import io.flutter.plugins.camera.features.noisereduction.NoiseReductionFeature; |
| import io.flutter.plugins.camera.features.resolution.ResolutionFeature; |
| import io.flutter.plugins.camera.features.resolution.ResolutionPreset; |
| import io.flutter.plugins.camera.features.sensororientation.DeviceOrientationManager; |
| import io.flutter.plugins.camera.features.sensororientation.SensorOrientationFeature; |
| import io.flutter.plugins.camera.features.zoomlevel.ZoomLevelFeature; |
| import io.flutter.plugins.camera.utils.TestUtils; |
| import io.flutter.view.TextureRegistry; |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| |
| public class CameraTest { |
| private CameraProperties mockCameraProperties; |
| private CameraFeatureFactory mockCameraFeatureFactory; |
| private DartMessenger mockDartMessenger; |
| private Camera camera; |
| private CameraCaptureSession mockCaptureSession; |
| private CaptureRequest.Builder mockPreviewRequestBuilder; |
| |
| @Before |
| public void before() { |
| mockCameraProperties = mock(CameraProperties.class); |
| mockCameraFeatureFactory = new TestCameraFeatureFactory(); |
| mockDartMessenger = mock(DartMessenger.class); |
| mockCaptureSession = mock(CameraCaptureSession.class); |
| mockPreviewRequestBuilder = mock(CaptureRequest.Builder.class); |
| |
| final Activity mockActivity = mock(Activity.class); |
| final TextureRegistry.SurfaceTextureEntry mockFlutterTexture = |
| mock(TextureRegistry.SurfaceTextureEntry.class); |
| final String cameraName = "1"; |
| final ResolutionPreset resolutionPreset = ResolutionPreset.high; |
| final boolean enableAudio = false; |
| |
| when(mockCameraProperties.getCameraName()).thenReturn(cameraName); |
| |
| camera = |
| new Camera( |
| mockActivity, |
| mockFlutterTexture, |
| mockCameraFeatureFactory, |
| mockDartMessenger, |
| mockCameraProperties, |
| resolutionPreset, |
| enableAudio); |
| |
| TestUtils.setPrivateField(camera, "captureSession", mockCaptureSession); |
| TestUtils.setPrivateField(camera, "previewRequestBuilder", mockPreviewRequestBuilder); |
| } |
| |
| @After |
| public void after() { |
| TestUtils.setFinalStatic(Build.VERSION.class, "SDK_INT", 0); |
| } |
| |
| @Test |
| public void shouldCreateCameraPluginAndSetAllFeatures() { |
| final Activity mockActivity = mock(Activity.class); |
| final TextureRegistry.SurfaceTextureEntry mockFlutterTexture = |
| mock(TextureRegistry.SurfaceTextureEntry.class); |
| final CameraFeatureFactory mockCameraFeatureFactory = mock(CameraFeatureFactory.class); |
| final String cameraName = "1"; |
| final ResolutionPreset resolutionPreset = ResolutionPreset.high; |
| final boolean enableAudio = false; |
| |
| when(mockCameraProperties.getCameraName()).thenReturn(cameraName); |
| SensorOrientationFeature mockSensorOrientationFeature = mock(SensorOrientationFeature.class); |
| when(mockCameraFeatureFactory.createSensorOrientationFeature(any(), any(), any())) |
| .thenReturn(mockSensorOrientationFeature); |
| |
| Camera camera = |
| new Camera( |
| mockActivity, |
| mockFlutterTexture, |
| mockCameraFeatureFactory, |
| mockDartMessenger, |
| mockCameraProperties, |
| resolutionPreset, |
| enableAudio); |
| |
| verify(mockCameraFeatureFactory, times(1)) |
| .createSensorOrientationFeature(mockCameraProperties, mockActivity, mockDartMessenger); |
| verify(mockCameraFeatureFactory, times(1)).createAutoFocusFeature(mockCameraProperties, false); |
| verify(mockCameraFeatureFactory, times(1)).createExposureLockFeature(mockCameraProperties); |
| verify(mockCameraFeatureFactory, times(1)) |
| .createExposurePointFeature(eq(mockCameraProperties), eq(mockSensorOrientationFeature)); |
| verify(mockCameraFeatureFactory, times(1)).createExposureOffsetFeature(mockCameraProperties); |
| verify(mockCameraFeatureFactory, times(1)).createFlashFeature(mockCameraProperties); |
| verify(mockCameraFeatureFactory, times(1)) |
| .createFocusPointFeature(eq(mockCameraProperties), eq(mockSensorOrientationFeature)); |
| verify(mockCameraFeatureFactory, times(1)).createFpsRangeFeature(mockCameraProperties); |
| verify(mockCameraFeatureFactory, times(1)).createNoiseReductionFeature(mockCameraProperties); |
| verify(mockCameraFeatureFactory, times(1)) |
| .createResolutionFeature(mockCameraProperties, resolutionPreset, cameraName); |
| verify(mockCameraFeatureFactory, times(1)).createZoomLevelFeature(mockCameraProperties); |
| assertNotNull("should create a camera", camera); |
| } |
| |
| @Test |
| public void getDeviceOrientationManager() { |
| SensorOrientationFeature mockSensorOrientationFeature = |
| mockCameraFeatureFactory.createSensorOrientationFeature(mockCameraProperties, null, null); |
| DeviceOrientationManager mockDeviceOrientationManager = mock(DeviceOrientationManager.class); |
| |
| when(mockSensorOrientationFeature.getDeviceOrientationManager()) |
| .thenReturn(mockDeviceOrientationManager); |
| |
| DeviceOrientationManager actualDeviceOrientationManager = camera.getDeviceOrientationManager(); |
| |
| verify(mockSensorOrientationFeature, times(1)).getDeviceOrientationManager(); |
| assertEquals(mockDeviceOrientationManager, actualDeviceOrientationManager); |
| } |
| |
| @Test |
| public void getExposureOffsetStepSize() { |
| ExposureOffsetFeature mockExposureOffsetFeature = |
| mockCameraFeatureFactory.createExposureOffsetFeature(mockCameraProperties); |
| double stepSize = 2.3; |
| |
| when(mockExposureOffsetFeature.getExposureOffsetStepSize()).thenReturn(stepSize); |
| |
| double actualSize = camera.getExposureOffsetStepSize(); |
| |
| verify(mockExposureOffsetFeature, times(1)).getExposureOffsetStepSize(); |
| assertEquals(stepSize, actualSize, 0); |
| } |
| |
| @Test |
| public void getMaxExposureOffset() { |
| ExposureOffsetFeature mockExposureOffsetFeature = |
| mockCameraFeatureFactory.createExposureOffsetFeature(mockCameraProperties); |
| double expectedMaxOffset = 42.0; |
| |
| when(mockExposureOffsetFeature.getMaxExposureOffset()).thenReturn(expectedMaxOffset); |
| |
| double actualMaxOffset = camera.getMaxExposureOffset(); |
| |
| verify(mockExposureOffsetFeature, times(1)).getMaxExposureOffset(); |
| assertEquals(expectedMaxOffset, actualMaxOffset, 0); |
| } |
| |
| @Test |
| public void getMinExposureOffset() { |
| ExposureOffsetFeature mockExposureOffsetFeature = |
| mockCameraFeatureFactory.createExposureOffsetFeature(mockCameraProperties); |
| double expectedMinOffset = 21.5; |
| |
| when(mockExposureOffsetFeature.getMinExposureOffset()).thenReturn(21.5); |
| |
| double actualMinOffset = camera.getMinExposureOffset(); |
| |
| verify(mockExposureOffsetFeature, times(1)).getMinExposureOffset(); |
| assertEquals(expectedMinOffset, actualMinOffset, 0); |
| } |
| |
| @Test |
| public void getMaxZoomLevel() { |
| ZoomLevelFeature mockZoomLevelFeature = |
| mockCameraFeatureFactory.createZoomLevelFeature(mockCameraProperties); |
| float expectedMaxZoomLevel = 4.2f; |
| |
| when(mockZoomLevelFeature.getMaximumZoomLevel()).thenReturn(expectedMaxZoomLevel); |
| |
| float actualMaxZoomLevel = camera.getMaxZoomLevel(); |
| |
| verify(mockZoomLevelFeature, times(1)).getMaximumZoomLevel(); |
| assertEquals(expectedMaxZoomLevel, actualMaxZoomLevel, 0); |
| } |
| |
| @Test |
| public void getMinZoomLevel() { |
| ZoomLevelFeature mockZoomLevelFeature = |
| mockCameraFeatureFactory.createZoomLevelFeature(mockCameraProperties); |
| float expectedMinZoomLevel = 4.2f; |
| |
| when(mockZoomLevelFeature.getMinimumZoomLevel()).thenReturn(expectedMinZoomLevel); |
| |
| float actualMinZoomLevel = camera.getMinZoomLevel(); |
| |
| verify(mockZoomLevelFeature, times(1)).getMinimumZoomLevel(); |
| assertEquals(expectedMinZoomLevel, actualMinZoomLevel, 0); |
| } |
| |
| @Test |
| public void getRecordingProfile() { |
| ResolutionFeature mockResolutionFeature = |
| mockCameraFeatureFactory.createResolutionFeature(mockCameraProperties, null, null); |
| CamcorderProfile mockCamcorderProfile = mock(CamcorderProfile.class); |
| |
| when(mockResolutionFeature.getRecordingProfile()).thenReturn(mockCamcorderProfile); |
| |
| CamcorderProfile actualRecordingProfile = camera.getRecordingProfile(); |
| |
| verify(mockResolutionFeature, times(1)).getRecordingProfile(); |
| assertEquals(mockCamcorderProfile, actualRecordingProfile); |
| } |
| |
| @Test |
| public void setExposureMode_shouldUpdateExposureLockFeature() { |
| ExposureLockFeature mockExposureLockFeature = |
| mockCameraFeatureFactory.createExposureLockFeature(mockCameraProperties); |
| MethodChannel.Result mockResult = mock(MethodChannel.Result.class); |
| ExposureMode exposureMode = ExposureMode.locked; |
| |
| camera.setExposureMode(mockResult, exposureMode); |
| |
| verify(mockExposureLockFeature, times(1)).setValue(exposureMode); |
| verify(mockResult, never()).error(any(), any(), any()); |
| verify(mockResult, times(1)).success(null); |
| } |
| |
| @Test |
| public void setExposureMode_shouldUpdateBuilder() { |
| ExposureLockFeature mockExposureLockFeature = |
| mockCameraFeatureFactory.createExposureLockFeature(mockCameraProperties); |
| MethodChannel.Result mockResult = mock(MethodChannel.Result.class); |
| ExposureMode exposureMode = ExposureMode.locked; |
| |
| camera.setExposureMode(mockResult, exposureMode); |
| |
| verify(mockExposureLockFeature, times(1)).updateBuilder(any()); |
| } |
| |
| @Test |
| public void setExposureMode_shouldCallErrorOnResultOnCameraAccessException() |
| throws CameraAccessException { |
| MethodChannel.Result mockResult = mock(MethodChannel.Result.class); |
| ExposureMode exposureMode = ExposureMode.locked; |
| when(mockCaptureSession.setRepeatingRequest(any(), any(), any())) |
| .thenThrow(new CameraAccessException(0, "")); |
| |
| camera.setExposureMode(mockResult, exposureMode); |
| |
| verify(mockResult, never()).success(any()); |
| verify(mockResult, times(1)) |
| .error("setExposureModeFailed", "Could not set exposure mode.", null); |
| } |
| |
| @Test |
| public void setExposurePoint_shouldUpdateExposurePointFeature() { |
| SensorOrientationFeature mockSensorOrientationFeature = mock(SensorOrientationFeature.class); |
| ExposurePointFeature mockExposurePointFeature = |
| mockCameraFeatureFactory.createExposurePointFeature( |
| mockCameraProperties, mockSensorOrientationFeature); |
| MethodChannel.Result mockResult = mock(MethodChannel.Result.class); |
| Point point = new Point(42d, 42d); |
| |
| camera.setExposurePoint(mockResult, point); |
| |
| verify(mockExposurePointFeature, times(1)).setValue(point); |
| verify(mockResult, never()).error(any(), any(), any()); |
| verify(mockResult, times(1)).success(null); |
| } |
| |
| @Test |
| public void setExposurePoint_shouldUpdateBuilder() { |
| SensorOrientationFeature mockSensorOrientationFeature = mock(SensorOrientationFeature.class); |
| ExposurePointFeature mockExposurePointFeature = |
| mockCameraFeatureFactory.createExposurePointFeature( |
| mockCameraProperties, mockSensorOrientationFeature); |
| MethodChannel.Result mockResult = mock(MethodChannel.Result.class); |
| Point point = new Point(42d, 42d); |
| |
| camera.setExposurePoint(mockResult, point); |
| |
| verify(mockExposurePointFeature, times(1)).updateBuilder(any()); |
| } |
| |
| @Test |
| public void setExposurePoint_shouldCallErrorOnResultOnCameraAccessException() |
| throws CameraAccessException { |
| MethodChannel.Result mockResult = mock(MethodChannel.Result.class); |
| Point point = new Point(42d, 42d); |
| when(mockCaptureSession.setRepeatingRequest(any(), any(), any())) |
| .thenThrow(new CameraAccessException(0, "")); |
| |
| camera.setExposurePoint(mockResult, point); |
| |
| verify(mockResult, never()).success(any()); |
| verify(mockResult, times(1)) |
| .error("setExposurePointFailed", "Could not set exposure point.", null); |
| } |
| |
| @Test |
| public void setFlashMode_shouldUpdateFlashFeature() { |
| FlashFeature mockFlashFeature = |
| mockCameraFeatureFactory.createFlashFeature(mockCameraProperties); |
| MethodChannel.Result mockResult = mock(MethodChannel.Result.class); |
| FlashMode flashMode = FlashMode.always; |
| |
| camera.setFlashMode(mockResult, flashMode); |
| |
| verify(mockFlashFeature, times(1)).setValue(flashMode); |
| verify(mockResult, never()).error(any(), any(), any()); |
| verify(mockResult, times(1)).success(null); |
| } |
| |
| @Test |
| public void setFlashMode_shouldUpdateBuilder() { |
| FlashFeature mockFlashFeature = |
| mockCameraFeatureFactory.createFlashFeature(mockCameraProperties); |
| MethodChannel.Result mockResult = mock(MethodChannel.Result.class); |
| FlashMode flashMode = FlashMode.always; |
| |
| camera.setFlashMode(mockResult, flashMode); |
| |
| verify(mockFlashFeature, times(1)).updateBuilder(any()); |
| } |
| |
| @Test |
| public void setFlashMode_shouldCallErrorOnResultOnCameraAccessException() |
| throws CameraAccessException { |
| MethodChannel.Result mockResult = mock(MethodChannel.Result.class); |
| FlashMode flashMode = FlashMode.always; |
| when(mockCaptureSession.setRepeatingRequest(any(), any(), any())) |
| .thenThrow(new CameraAccessException(0, "")); |
| |
| camera.setFlashMode(mockResult, flashMode); |
| |
| verify(mockResult, never()).success(any()); |
| verify(mockResult, times(1)).error("setFlashModeFailed", "Could not set flash mode.", null); |
| } |
| |
| @Test |
| public void setFocusPoint_shouldUpdateFocusPointFeature() { |
| SensorOrientationFeature mockSensorOrientationFeature = mock(SensorOrientationFeature.class); |
| FocusPointFeature mockFocusPointFeature = |
| mockCameraFeatureFactory.createFocusPointFeature( |
| mockCameraProperties, mockSensorOrientationFeature); |
| AutoFocusFeature mockAutoFocusFeature = |
| mockCameraFeatureFactory.createAutoFocusFeature(mockCameraProperties, false); |
| MethodChannel.Result mockResult = mock(MethodChannel.Result.class); |
| Point point = new Point(42d, 42d); |
| when(mockAutoFocusFeature.getValue()).thenReturn(FocusMode.auto); |
| |
| camera.setFocusPoint(mockResult, point); |
| |
| verify(mockFocusPointFeature, times(1)).setValue(point); |
| verify(mockResult, never()).error(any(), any(), any()); |
| verify(mockResult, times(1)).success(null); |
| } |
| |
| @Test |
| public void setFocusPoint_shouldUpdateBuilder() { |
| SensorOrientationFeature mockSensorOrientationFeature = mock(SensorOrientationFeature.class); |
| FocusPointFeature mockFocusPointFeature = |
| mockCameraFeatureFactory.createFocusPointFeature( |
| mockCameraProperties, mockSensorOrientationFeature); |
| AutoFocusFeature mockAutoFocusFeature = |
| mockCameraFeatureFactory.createAutoFocusFeature(mockCameraProperties, false); |
| MethodChannel.Result mockResult = mock(MethodChannel.Result.class); |
| Point point = new Point(42d, 42d); |
| when(mockAutoFocusFeature.getValue()).thenReturn(FocusMode.auto); |
| |
| camera.setFocusPoint(mockResult, point); |
| |
| verify(mockFocusPointFeature, times(1)).updateBuilder(any()); |
| } |
| |
| @Test |
| public void setFocusPoint_shouldCallErrorOnResultOnCameraAccessException() |
| throws CameraAccessException { |
| AutoFocusFeature mockAutoFocusFeature = |
| mockCameraFeatureFactory.createAutoFocusFeature(mockCameraProperties, false); |
| MethodChannel.Result mockResult = mock(MethodChannel.Result.class); |
| Point point = new Point(42d, 42d); |
| when(mockAutoFocusFeature.getValue()).thenReturn(FocusMode.auto); |
| when(mockCaptureSession.setRepeatingRequest(any(), any(), any())) |
| .thenThrow(new CameraAccessException(0, "")); |
| |
| camera.setFocusPoint(mockResult, point); |
| |
| verify(mockResult, never()).success(any()); |
| verify(mockResult, times(1)).error("setFocusPointFailed", "Could not set focus point.", null); |
| } |
| |
| @Test |
| public void setZoomLevel_shouldUpdateZoomLevelFeature() throws CameraAccessException { |
| ZoomLevelFeature mockZoomLevelFeature = |
| mockCameraFeatureFactory.createZoomLevelFeature(mockCameraProperties); |
| MethodChannel.Result mockResult = mock(MethodChannel.Result.class); |
| float zoomLevel = 1.0f; |
| |
| when(mockZoomLevelFeature.getValue()).thenReturn(zoomLevel); |
| when(mockZoomLevelFeature.getMinimumZoomLevel()).thenReturn(0f); |
| when(mockZoomLevelFeature.getMaximumZoomLevel()).thenReturn(2f); |
| |
| camera.setZoomLevel(mockResult, zoomLevel); |
| |
| verify(mockZoomLevelFeature, times(1)).setValue(zoomLevel); |
| verify(mockResult, never()).error(any(), any(), any()); |
| verify(mockResult, times(1)).success(null); |
| } |
| |
| @Test |
| public void setZoomLevel_shouldUpdateBuilder() throws CameraAccessException { |
| ZoomLevelFeature mockZoomLevelFeature = |
| mockCameraFeatureFactory.createZoomLevelFeature(mockCameraProperties); |
| MethodChannel.Result mockResult = mock(MethodChannel.Result.class); |
| float zoomLevel = 1.0f; |
| |
| when(mockZoomLevelFeature.getValue()).thenReturn(zoomLevel); |
| when(mockZoomLevelFeature.getMinimumZoomLevel()).thenReturn(0f); |
| when(mockZoomLevelFeature.getMaximumZoomLevel()).thenReturn(2f); |
| |
| camera.setZoomLevel(mockResult, zoomLevel); |
| |
| verify(mockZoomLevelFeature, times(1)).updateBuilder(any()); |
| } |
| |
| @Test |
| public void setZoomLevel_shouldCallErrorOnResultOnCameraAccessException() |
| throws CameraAccessException { |
| ZoomLevelFeature mockZoomLevelFeature = |
| mockCameraFeatureFactory.createZoomLevelFeature(mockCameraProperties); |
| MethodChannel.Result mockResult = mock(MethodChannel.Result.class); |
| float zoomLevel = 1.0f; |
| |
| when(mockZoomLevelFeature.getValue()).thenReturn(zoomLevel); |
| when(mockZoomLevelFeature.getMinimumZoomLevel()).thenReturn(0f); |
| when(mockZoomLevelFeature.getMaximumZoomLevel()).thenReturn(2f); |
| when(mockCaptureSession.setRepeatingRequest(any(), any(), any())) |
| .thenThrow(new CameraAccessException(0, "")); |
| |
| camera.setZoomLevel(mockResult, zoomLevel); |
| |
| verify(mockResult, never()).success(any()); |
| verify(mockResult, times(1)).error("setZoomLevelFailed", "Could not set zoom level.", null); |
| } |
| |
| @Test |
| public void pauseVideoRecording_shouldSendNullResultWhenNotRecording() { |
| TestUtils.setPrivateField(camera, "recordingVideo", false); |
| MethodChannel.Result mockResult = mock(MethodChannel.Result.class); |
| |
| camera.pauseVideoRecording(mockResult); |
| |
| verify(mockResult, times(1)).success(null); |
| verify(mockResult, never()).error(any(), any(), any()); |
| } |
| |
| @Test |
| public void pauseVideoRecording_shouldCallPauseWhenRecordingAndOnAPIN() { |
| MethodChannel.Result mockResult = mock(MethodChannel.Result.class); |
| MediaRecorder mockMediaRecorder = mock(MediaRecorder.class); |
| TestUtils.setPrivateField(camera, "mediaRecorder", mockMediaRecorder); |
| TestUtils.setPrivateField(camera, "recordingVideo", true); |
| TestUtils.setFinalStatic(Build.VERSION.class, "SDK_INT", 24); |
| |
| camera.pauseVideoRecording(mockResult); |
| |
| verify(mockMediaRecorder, times(1)).pause(); |
| verify(mockResult, times(1)).success(null); |
| verify(mockResult, never()).error(any(), any(), any()); |
| } |
| |
| @Test |
| public void pauseVideoRecording_shouldSendVideoRecordingFailedErrorWhenVersionCodeSmallerThenN() { |
| TestUtils.setPrivateField(camera, "recordingVideo", true); |
| TestUtils.setFinalStatic(Build.VERSION.class, "SDK_INT", 23); |
| MethodChannel.Result mockResult = mock(MethodChannel.Result.class); |
| |
| camera.pauseVideoRecording(mockResult); |
| |
| verify(mockResult, times(1)) |
| .error("videoRecordingFailed", "pauseVideoRecording requires Android API +24.", null); |
| verify(mockResult, never()).success(any()); |
| } |
| |
| @Test |
| public void |
| pauseVideoRecording_shouldSendVideoRecordingFailedErrorWhenMediaRecorderPauseThrowsIllegalStateException() { |
| MediaRecorder mockMediaRecorder = mock(MediaRecorder.class); |
| TestUtils.setPrivateField(camera, "mediaRecorder", mockMediaRecorder); |
| TestUtils.setPrivateField(camera, "recordingVideo", true); |
| TestUtils.setFinalStatic(Build.VERSION.class, "SDK_INT", 24); |
| |
| IllegalStateException expectedException = new IllegalStateException("Test error message"); |
| |
| doThrow(expectedException).when(mockMediaRecorder).pause(); |
| |
| MethodChannel.Result mockResult = mock(MethodChannel.Result.class); |
| |
| camera.pauseVideoRecording(mockResult); |
| |
| verify(mockResult, times(1)).error("videoRecordingFailed", "Test error message", null); |
| verify(mockResult, never()).success(any()); |
| } |
| |
| @Test |
| public void resumeVideoRecording_shouldSendNullResultWhenNotRecording() { |
| MethodChannel.Result mockResult = mock(MethodChannel.Result.class); |
| TestUtils.setPrivateField(camera, "recordingVideo", false); |
| |
| camera.resumeVideoRecording(mockResult); |
| |
| verify(mockResult, times(1)).success(null); |
| verify(mockResult, never()).error(any(), any(), any()); |
| } |
| |
| @Test |
| public void resumeVideoRecording_shouldCallPauseWhenRecordingAndOnAPIN() { |
| MethodChannel.Result mockResult = mock(MethodChannel.Result.class); |
| MediaRecorder mockMediaRecorder = mock(MediaRecorder.class); |
| TestUtils.setPrivateField(camera, "mediaRecorder", mockMediaRecorder); |
| TestUtils.setPrivateField(camera, "recordingVideo", true); |
| TestUtils.setFinalStatic(Build.VERSION.class, "SDK_INT", 24); |
| |
| camera.resumeVideoRecording(mockResult); |
| |
| verify(mockMediaRecorder, times(1)).resume(); |
| verify(mockResult, times(1)).success(null); |
| verify(mockResult, never()).error(any(), any(), any()); |
| } |
| |
| @Test |
| public void |
| resumeVideoRecording_shouldSendVideoRecordingFailedErrorWhenVersionCodeSmallerThanN() { |
| TestUtils.setPrivateField(camera, "recordingVideo", true); |
| TestUtils.setFinalStatic(Build.VERSION.class, "SDK_INT", 23); |
| |
| MethodChannel.Result mockResult = mock(MethodChannel.Result.class); |
| |
| camera.resumeVideoRecording(mockResult); |
| |
| verify(mockResult, times(1)) |
| .error("videoRecordingFailed", "resumeVideoRecording requires Android API +24.", null); |
| verify(mockResult, never()).success(any()); |
| } |
| |
| @Test |
| public void |
| resumeVideoRecording_shouldSendVideoRecordingFailedErrorWhenMediaRecorderPauseThrowsIllegalStateException() { |
| MediaRecorder mockMediaRecorder = mock(MediaRecorder.class); |
| TestUtils.setPrivateField(camera, "mediaRecorder", mockMediaRecorder); |
| TestUtils.setPrivateField(camera, "recordingVideo", true); |
| TestUtils.setFinalStatic(Build.VERSION.class, "SDK_INT", 24); |
| |
| IllegalStateException expectedException = new IllegalStateException("Test error message"); |
| |
| doThrow(expectedException).when(mockMediaRecorder).resume(); |
| |
| MethodChannel.Result mockResult = mock(MethodChannel.Result.class); |
| |
| camera.resumeVideoRecording(mockResult); |
| |
| verify(mockResult, times(1)).error("videoRecordingFailed", "Test error message", null); |
| verify(mockResult, never()).success(any()); |
| } |
| |
| @Test |
| public void setFocusMode_shouldUpdateAutoFocusFeature() { |
| AutoFocusFeature mockAutoFocusFeature = |
| mockCameraFeatureFactory.createAutoFocusFeature(mockCameraProperties, false); |
| MethodChannel.Result mockResult = mock(MethodChannel.Result.class); |
| |
| camera.setFocusMode(mockResult, FocusMode.auto); |
| |
| verify(mockAutoFocusFeature, times(1)).setValue(FocusMode.auto); |
| verify(mockResult, never()).error(any(), any(), any()); |
| verify(mockResult, times(1)).success(null); |
| } |
| |
| @Test |
| public void setFocusMode_shouldUpdateBuilder() { |
| AutoFocusFeature mockAutoFocusFeature = |
| mockCameraFeatureFactory.createAutoFocusFeature(mockCameraProperties, false); |
| MethodChannel.Result mockResult = mock(MethodChannel.Result.class); |
| |
| camera.setFocusMode(mockResult, FocusMode.auto); |
| |
| verify(mockAutoFocusFeature, times(1)).updateBuilder(any()); |
| } |
| |
| @Test |
| public void setFocusMode_shouldUnlockAutoFocusForAutoMode() { |
| camera.setFocusMode(mock(MethodChannel.Result.class), FocusMode.auto); |
| verify(mockPreviewRequestBuilder, times(1)) |
| .set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL); |
| verify(mockPreviewRequestBuilder, times(1)) |
| .set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_IDLE); |
| } |
| |
| @Test |
| public void setFocusMode_shouldSkipUnlockAutoFocusWhenNullCaptureSession() { |
| TestUtils.setPrivateField(camera, "captureSession", null); |
| camera.setFocusMode(mock(MethodChannel.Result.class), FocusMode.auto); |
| verify(mockPreviewRequestBuilder, never()) |
| .set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL); |
| verify(mockPreviewRequestBuilder, never()) |
| .set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_IDLE); |
| } |
| |
| @Test |
| public void setFocusMode_shouldSendErrorEventOnUnlockAutoFocusCameraAccessException() |
| throws CameraAccessException { |
| when(mockCaptureSession.capture(any(), any(), any())) |
| .thenThrow(new CameraAccessException(0, "")); |
| camera.setFocusMode(mock(MethodChannel.Result.class), FocusMode.auto); |
| verify(mockDartMessenger, times(1)).sendCameraErrorEvent(any()); |
| } |
| |
| @Test |
| public void setFocusMode_shouldLockAutoFocusForLockedMode() throws CameraAccessException { |
| camera.setFocusMode(mock(MethodChannel.Result.class), FocusMode.locked); |
| verify(mockPreviewRequestBuilder, times(1)) |
| .set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START); |
| verify(mockCaptureSession, times(1)).capture(any(), any(), any()); |
| verify(mockCaptureSession, times(1)).setRepeatingRequest(any(), any(), any()); |
| } |
| |
| @Test |
| public void setFocusMode_shouldSkipLockAutoFocusWhenNullCaptureSession() { |
| TestUtils.setPrivateField(camera, "captureSession", null); |
| camera.setFocusMode(mock(MethodChannel.Result.class), FocusMode.locked); |
| verify(mockPreviewRequestBuilder, never()) |
| .set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_START); |
| } |
| |
| @Test |
| public void setFocusMode_shouldSendErrorEventOnLockAutoFocusCameraAccessException() |
| throws CameraAccessException { |
| when(mockCaptureSession.capture(any(), any(), any())) |
| .thenThrow(new CameraAccessException(0, "")); |
| camera.setFocusMode(mock(MethodChannel.Result.class), FocusMode.locked); |
| verify(mockDartMessenger, times(1)).sendCameraErrorEvent(any()); |
| } |
| |
| @Test |
| public void setFocusMode_shouldCallErrorOnResultOnCameraAccessException() |
| throws CameraAccessException { |
| MethodChannel.Result mockResult = mock(MethodChannel.Result.class); |
| when(mockCaptureSession.setRepeatingRequest(any(), any(), any())) |
| .thenThrow(new CameraAccessException(0, "")); |
| |
| camera.setFocusMode(mockResult, FocusMode.locked); |
| |
| verify(mockResult, never()).success(any()); |
| verify(mockResult, times(1)) |
| .error("setFocusModeFailed", "Error setting focus mode: null", null); |
| } |
| |
| @Test |
| public void setExposureOffset_shouldUpdateExposureOffsetFeature() { |
| ExposureOffsetFeature mockExposureOffsetFeature = |
| mockCameraFeatureFactory.createExposureOffsetFeature(mockCameraProperties); |
| MethodChannel.Result mockResult = mock(MethodChannel.Result.class); |
| |
| camera.setExposureOffset(mockResult, 1.0); |
| |
| verify(mockExposureOffsetFeature, times(1)).setValue(1.0); |
| verify(mockResult, never()).error(any(), any(), any()); |
| verify(mockResult, times(1)).success(null); |
| } |
| |
| @Test |
| public void setExposureOffset_shouldAndUpdateBuilder() { |
| ExposureOffsetFeature mockExposureOffsetFeature = |
| mockCameraFeatureFactory.createExposureOffsetFeature(mockCameraProperties); |
| MethodChannel.Result mockResult = mock(MethodChannel.Result.class); |
| |
| camera.setExposureOffset(mockResult, 1.0); |
| |
| verify(mockExposureOffsetFeature, times(1)).updateBuilder(any()); |
| } |
| |
| @Test |
| public void setExposureOffset_shouldCallErrorOnResultOnCameraAccessException() |
| throws CameraAccessException { |
| MethodChannel.Result mockResult = mock(MethodChannel.Result.class); |
| when(mockCaptureSession.setRepeatingRequest(any(), any(), any())) |
| .thenThrow(new CameraAccessException(0, "")); |
| |
| camera.setExposureOffset(mockResult, 1.0); |
| |
| verify(mockResult, never()).success(any()); |
| verify(mockResult, times(1)) |
| .error("setExposureOffsetFailed", "Could not set exposure offset.", null); |
| } |
| |
| @Test |
| public void lockCaptureOrientation_shouldLockCaptureOrientation() { |
| final Activity mockActivity = mock(Activity.class); |
| SensorOrientationFeature mockSensorOrientationFeature = |
| mockCameraFeatureFactory.createSensorOrientationFeature( |
| mockCameraProperties, mockActivity, mockDartMessenger); |
| |
| camera.lockCaptureOrientation(PlatformChannel.DeviceOrientation.PORTRAIT_UP); |
| |
| verify(mockSensorOrientationFeature, times(1)) |
| .lockCaptureOrientation(PlatformChannel.DeviceOrientation.PORTRAIT_UP); |
| } |
| |
| @Test |
| public void unlockCaptureOrientation_shouldUnlockCaptureOrientation() { |
| final Activity mockActivity = mock(Activity.class); |
| SensorOrientationFeature mockSensorOrientationFeature = |
| mockCameraFeatureFactory.createSensorOrientationFeature( |
| mockCameraProperties, mockActivity, mockDartMessenger); |
| |
| camera.unlockCaptureOrientation(); |
| |
| verify(mockSensorOrientationFeature, times(1)).unlockCaptureOrientation(); |
| } |
| |
| private static class TestCameraFeatureFactory implements CameraFeatureFactory { |
| private final AutoFocusFeature mockAutoFocusFeature; |
| private final ExposureLockFeature mockExposureLockFeature; |
| private final ExposureOffsetFeature mockExposureOffsetFeature; |
| private final ExposurePointFeature mockExposurePointFeature; |
| private final FlashFeature mockFlashFeature; |
| private final FocusPointFeature mockFocusPointFeature; |
| private final FpsRangeFeature mockFpsRangeFeature; |
| private final NoiseReductionFeature mockNoiseReductionFeature; |
| private final ResolutionFeature mockResolutionFeature; |
| private final SensorOrientationFeature mockSensorOrientationFeature; |
| private final ZoomLevelFeature mockZoomLevelFeature; |
| |
| public TestCameraFeatureFactory() { |
| this.mockAutoFocusFeature = mock(AutoFocusFeature.class); |
| this.mockExposureLockFeature = mock(ExposureLockFeature.class); |
| this.mockExposureOffsetFeature = mock(ExposureOffsetFeature.class); |
| this.mockExposurePointFeature = mock(ExposurePointFeature.class); |
| this.mockFlashFeature = mock(FlashFeature.class); |
| this.mockFocusPointFeature = mock(FocusPointFeature.class); |
| this.mockFpsRangeFeature = mock(FpsRangeFeature.class); |
| this.mockNoiseReductionFeature = mock(NoiseReductionFeature.class); |
| this.mockResolutionFeature = mock(ResolutionFeature.class); |
| this.mockSensorOrientationFeature = mock(SensorOrientationFeature.class); |
| this.mockZoomLevelFeature = mock(ZoomLevelFeature.class); |
| } |
| |
| @Override |
| public AutoFocusFeature createAutoFocusFeature( |
| @NonNull CameraProperties cameraProperties, boolean recordingVideo) { |
| return mockAutoFocusFeature; |
| } |
| |
| @Override |
| public ExposureLockFeature createExposureLockFeature( |
| @NonNull CameraProperties cameraProperties) { |
| return mockExposureLockFeature; |
| } |
| |
| @Override |
| public ExposureOffsetFeature createExposureOffsetFeature( |
| @NonNull CameraProperties cameraProperties) { |
| return mockExposureOffsetFeature; |
| } |
| |
| @Override |
| public FlashFeature createFlashFeature(@NonNull CameraProperties cameraProperties) { |
| return mockFlashFeature; |
| } |
| |
| @Override |
| public ResolutionFeature createResolutionFeature( |
| @NonNull CameraProperties cameraProperties, |
| ResolutionPreset initialSetting, |
| String cameraName) { |
| return mockResolutionFeature; |
| } |
| |
| @Override |
| public FocusPointFeature createFocusPointFeature( |
| @NonNull CameraProperties cameraProperties, |
| @NonNull SensorOrientationFeature sensorOrienttionFeature) { |
| return mockFocusPointFeature; |
| } |
| |
| @Override |
| public FpsRangeFeature createFpsRangeFeature(@NonNull CameraProperties cameraProperties) { |
| return mockFpsRangeFeature; |
| } |
| |
| @Override |
| public SensorOrientationFeature createSensorOrientationFeature( |
| @NonNull CameraProperties cameraProperties, |
| @NonNull Activity activity, |
| @NonNull DartMessenger dartMessenger) { |
| return mockSensorOrientationFeature; |
| } |
| |
| @Override |
| public ZoomLevelFeature createZoomLevelFeature(@NonNull CameraProperties cameraProperties) { |
| return mockZoomLevelFeature; |
| } |
| |
| @Override |
| public ExposurePointFeature createExposurePointFeature( |
| @NonNull CameraProperties cameraProperties, |
| @NonNull SensorOrientationFeature sensorOrientationFeature) { |
| return mockExposurePointFeature; |
| } |
| |
| @Override |
| public NoiseReductionFeature createNoiseReductionFeature( |
| @NonNull CameraProperties cameraProperties) { |
| return mockNoiseReductionFeature; |
| } |
| } |
| } |