8
8
import static org .junit .Assert .assertFalse ;
9
9
import static org .junit .Assert .assertNotNull ;
10
10
import static org .mockito .ArgumentMatchers .any ;
11
+ import static org .mockito .ArgumentMatchers .anyInt ;
11
12
import static org .mockito .ArgumentMatchers .eq ;
13
+ import static org .mockito .Mockito .doNothing ;
12
14
import static org .mockito .Mockito .doThrow ;
13
15
import static org .mockito .Mockito .mock ;
14
16
import static org .mockito .Mockito .mockStatic ;
15
17
import static org .mockito .Mockito .never ;
18
+ import static org .mockito .Mockito .spy ;
16
19
import static org .mockito .Mockito .times ;
17
20
import static org .mockito .Mockito .verify ;
18
21
import static org .mockito .Mockito .when ;
36
39
import androidx .annotation .Nullable ;
37
40
import androidx .lifecycle .LifecycleObserver ;
38
41
import io .flutter .embedding .engine .systemchannels .PlatformChannel ;
42
+ import io .flutter .plugin .common .EventChannel ;
39
43
import io .flutter .plugin .common .MethodChannel ;
40
44
import io .flutter .plugins .camera .features .CameraFeatureFactory ;
41
45
import io .flutter .plugins .camera .features .CameraFeatures ;
56
60
import io .flutter .plugins .camera .features .sensororientation .DeviceOrientationManager ;
57
61
import io .flutter .plugins .camera .features .sensororientation .SensorOrientationFeature ;
58
62
import io .flutter .plugins .camera .features .zoomlevel .ZoomLevelFeature ;
63
+ import io .flutter .plugins .camera .media .ImageStreamReader ;
59
64
import io .flutter .plugins .camera .utils .TestUtils ;
60
65
import io .flutter .view .TextureRegistry ;
66
+ import java .io .IOException ;
61
67
import java .util .ArrayList ;
62
68
import java .util .List ;
63
69
import org .junit .After ;
@@ -638,6 +644,8 @@ public void startPreview_shouldPullStreamFromVideoRenderer()
638
644
TestUtils .setPrivateField (camera , "videoRenderer" , mockVideoRenderer );
639
645
CameraDeviceWrapper fakeCamera = new FakeCameraDeviceWrapper (mockRequestBuilders );
640
646
TestUtils .setPrivateField (camera , "cameraDevice" , fakeCamera );
647
+ ImageReader mockPictureImageReader = mock (ImageReader .class );
648
+ TestUtils .setPrivateField (camera , "pictureImageReader" , mockPictureImageReader );
641
649
642
650
TextureRegistry .SurfaceTextureEntry cameraFlutterTexture =
643
651
(TextureRegistry .SurfaceTextureEntry ) TestUtils .getPrivateField (camera , "flutterTexture" );
@@ -674,9 +682,10 @@ public void startPreview_shouldPullStreamFromImageReader()
674
682
675
683
when (cameraFlutterTexture .surfaceTexture ()).thenReturn (mockSurfaceTexture );
676
684
when (resolutionFeature .getPreviewSize ()).thenReturn (mockSize );
685
+ when (mockImageReader .getSurface ()).thenReturn (mock (Surface .class ));
677
686
678
687
camera .startPreview ();
679
- verify (mockImageReader , times (1 ))
688
+ verify (mockImageReader , times (2 )) // we expect two calls to start regular preview.
680
689
.getSurface (); // stream pulled from regular imageReader's surface.
681
690
}
682
691
@@ -692,6 +701,8 @@ public void startPreview_shouldFlipRotation() throws InterruptedException, Camer
692
701
TestUtils .setPrivateField (camera , "initialCameraFacing" , CameraMetadata .LENS_FACING_BACK );
693
702
CameraDeviceWrapper fakeCamera = new FakeCameraDeviceWrapper (mockRequestBuilders );
694
703
TestUtils .setPrivateField (camera , "cameraDevice" , fakeCamera );
704
+ ImageReader mockPictureImageReader = mock (ImageReader .class );
705
+ TestUtils .setPrivateField (camera , "pictureImageReader" , mockPictureImageReader );
695
706
696
707
TextureRegistry .SurfaceTextureEntry cameraFlutterTexture =
697
708
(TextureRegistry .SurfaceTextureEntry ) TestUtils .getPrivateField (camera , "flutterTexture" );
@@ -707,6 +718,39 @@ public void startPreview_shouldFlipRotation() throws InterruptedException, Camer
707
718
verify (mockVideoRenderer , times (1 )).setRotation (180 );
708
719
}
709
720
721
+ @ Test
722
+ public void startPreviewWithImageStream_shouldPullStreamsFromImageReaders ()
723
+ throws InterruptedException , CameraAccessException {
724
+ ArrayList <CaptureRequest .Builder > mockRequestBuilders = new ArrayList <>();
725
+ mockRequestBuilders .add (mock (CaptureRequest .Builder .class ));
726
+ SurfaceTexture mockSurfaceTexture = mock (SurfaceTexture .class );
727
+ Size mockSize = mock (Size .class );
728
+ ImageReader mockPictureImageReader = mock (ImageReader .class );
729
+ ImageStreamReader mockImageStreamReader = mock (ImageStreamReader .class );
730
+ TestUtils .setPrivateField (camera , "recordingVideo" , false );
731
+ TestUtils .setPrivateField (camera , "pictureImageReader" , mockPictureImageReader );
732
+ CameraDeviceWrapper fakeCamera = new FakeCameraDeviceWrapper (mockRequestBuilders );
733
+ TestUtils .setPrivateField (camera , "cameraDevice" , fakeCamera );
734
+ camera .imageStreamReader = mockImageStreamReader ;
735
+
736
+ TextureRegistry .SurfaceTextureEntry cameraFlutterTexture =
737
+ (TextureRegistry .SurfaceTextureEntry ) TestUtils .getPrivateField (camera , "flutterTexture" );
738
+ ResolutionFeature resolutionFeature =
739
+ (ResolutionFeature )
740
+ TestUtils .getPrivateField (mockCameraFeatureFactory , "mockResolutionFeature" );
741
+
742
+ when (cameraFlutterTexture .surfaceTexture ()).thenReturn (mockSurfaceTexture );
743
+ when (resolutionFeature .getPreviewSize ()).thenReturn (mockSize );
744
+
745
+ camera .startPreviewWithImageStream (mock (EventChannel .class ));
746
+ verify (mockImageStreamReader , times (1 ))
747
+ .getSurface (); // stream pulled from image streaming imageReader's surface.
748
+ verify (
749
+ mockPictureImageReader ,
750
+ times (2 )) // we expect one call to start the capture, one to create the capture session.
751
+ .getSurface (); // stream pulled from regular imageReader's surface.
752
+ }
753
+
710
754
@ Test
711
755
public void setDescriptionWhileRecording_shouldErrorWhenNotRecording () {
712
756
MethodChannel .Result mockResult = mock (MethodChannel .Result .class );
@@ -806,6 +850,43 @@ public void setFocusMode_shouldSendErrorEventOnUnlockAutoFocusCameraAccessExcept
806
850
verify (mockDartMessenger , times (1 )).sendCameraErrorEvent (any ());
807
851
}
808
852
853
+ @ Test
854
+ public void startVideoRecording_shouldPullStreamsFromMediaRecorderAndImageReader ()
855
+ throws InterruptedException , IOException , CameraAccessException {
856
+ Camera cameraSpy = spy (camera );
857
+ ArrayList <CaptureRequest .Builder > mockRequestBuilders = new ArrayList <>();
858
+ mockRequestBuilders .add (mock (CaptureRequest .Builder .class ));
859
+ SurfaceTexture mockSurfaceTexture = mock (SurfaceTexture .class );
860
+ Size mockSize = mock (Size .class );
861
+ MediaRecorder mockMediaRecorder = mock (MediaRecorder .class );
862
+ ImageReader mockPictureImageReader = mock (ImageReader .class );
863
+ TestUtils .setPrivateField (cameraSpy , "mediaRecorder" , mockMediaRecorder );
864
+ TestUtils .setPrivateField (cameraSpy , "recordingVideo" , false );
865
+ TestUtils .setPrivateField (cameraSpy , "pictureImageReader" , mockPictureImageReader );
866
+ CameraDeviceWrapper fakeCamera = new FakeCameraDeviceWrapper (mockRequestBuilders );
867
+ TestUtils .setPrivateField (cameraSpy , "cameraDevice" , fakeCamera );
868
+ MethodChannel .Result mockResult = mock (MethodChannel .Result .class );
869
+
870
+ TextureRegistry .SurfaceTextureEntry cameraFlutterTexture =
871
+ (TextureRegistry .SurfaceTextureEntry )
872
+ TestUtils .getPrivateField (cameraSpy , "flutterTexture" );
873
+ ResolutionFeature resolutionFeature =
874
+ (ResolutionFeature )
875
+ TestUtils .getPrivateField (mockCameraFeatureFactory , "mockResolutionFeature" );
876
+
877
+ when (cameraFlutterTexture .surfaceTexture ()).thenReturn (mockSurfaceTexture );
878
+ when (resolutionFeature .getPreviewSize ()).thenReturn (mockSize );
879
+ doNothing ().when (cameraSpy ).prepareRecording (mockResult );
880
+
881
+ cameraSpy .startVideoRecording (mockResult , null );
882
+ verify (mockMediaRecorder , times (1 ))
883
+ .getSurface (); // stream pulled from media recorder's surface.
884
+ verify (
885
+ mockPictureImageReader ,
886
+ times (2 )) // we expect one call to start the capture, one to create the capture session.
887
+ .getSurface (); // stream pulled from image streaming imageReader's surface.
888
+ }
889
+
809
890
@ Test
810
891
public void setFocusMode_shouldLockAutoFocusForLockedMode () throws CameraAccessException {
811
892
camera .setFocusMode (mock (MethodChannel .Result .class ), FocusMode .locked );
@@ -1013,6 +1094,45 @@ public void createCaptureSession_doesNotCloseCaptureSession() throws CameraAcces
1013
1094
verify (mockCaptureSession , never ()).close ();
1014
1095
}
1015
1096
1097
+ @ Test
1098
+ public void createCaptureSession_shouldNotAddPictureImageSurfaceToPreviewRequest ()
1099
+ throws CameraAccessException {
1100
+ Surface mockSurface = mock (Surface .class );
1101
+ Surface mockSecondarySurface = mock (Surface .class );
1102
+ SurfaceTexture mockSurfaceTexture = mock (SurfaceTexture .class );
1103
+ ResolutionFeature mockResolutionFeature = mock (ResolutionFeature .class );
1104
+ Size mockSize = mock (Size .class );
1105
+ ArrayList <CaptureRequest .Builder > mockRequestBuilders = new ArrayList <>();
1106
+ mockRequestBuilders .add (mock (CaptureRequest .Builder .class ));
1107
+ CameraDeviceWrapper fakeCamera = spy (new FakeCameraDeviceWrapper (mockRequestBuilders ));
1108
+ ImageReader mockPictureImageReader = mock (ImageReader .class );
1109
+ TestUtils .setPrivateField (camera , "cameraDevice" , fakeCamera );
1110
+ TestUtils .setPrivateField (camera , "pictureImageReader" , mockPictureImageReader );
1111
+ CaptureRequest .Builder mockPreviewRequestBuilder = mock (CaptureRequest .Builder .class );
1112
+
1113
+ TextureRegistry .SurfaceTextureEntry cameraFlutterTexture =
1114
+ (TextureRegistry .SurfaceTextureEntry ) TestUtils .getPrivateField (camera , "flutterTexture" );
1115
+ CameraFeatures cameraFeatures =
1116
+ (CameraFeatures ) TestUtils .getPrivateField (camera , "cameraFeatures" );
1117
+ ResolutionFeature resolutionFeature =
1118
+ (ResolutionFeature )
1119
+ TestUtils .getPrivateField (mockCameraFeatureFactory , "mockResolutionFeature" );
1120
+
1121
+ when (cameraFlutterTexture .surfaceTexture ()).thenReturn (mockSurfaceTexture );
1122
+ when (resolutionFeature .getPreviewSize ()).thenReturn (mockSize );
1123
+ when (fakeCamera .createCaptureRequest (anyInt ())).thenReturn (mockPreviewRequestBuilder );
1124
+ when (mockPictureImageReader .getSurface ()).thenReturn (mockSurface );
1125
+
1126
+ // Test with preview template.
1127
+ camera .createCaptureSession (CameraDevice .TEMPLATE_PREVIEW , mockSurface , mockSecondarySurface );
1128
+ verify (mockPreviewRequestBuilder , times (0 )).addTarget (mockSurface );
1129
+
1130
+ // Test with non-preview template.
1131
+ camera .createCaptureSession (CameraDevice .TEMPLATE_RECORD , mockSurface , mockSecondarySurface );
1132
+ verify (mockPreviewRequestBuilder , times (0 )).addTarget (mockSurface );
1133
+ verify (mockPreviewRequestBuilder ).addTarget (mockSecondarySurface );
1134
+ }
1135
+
1016
1136
@ Test
1017
1137
public void close_doesCloseCaptureSessionWhenCameraDeviceNull () {
1018
1138
camera .close ();
0 commit comments