@@ -662,7 +662,9 @@ void main() {
662
662
'initializeCamera throws a CameraException when createCamera has not been called before initializedCamera' ,
663
663
() async {
664
664
final AndroidCameraCameraX camera = AndroidCameraCameraX ();
665
- expect (() => camera.initializeCamera (3 ), throwsA (isA <CameraException >()));
665
+ await expectLater (() async {
666
+ await camera.initializeCamera (3 );
667
+ }, throwsA (isA <CameraException >()));
666
668
});
667
669
668
670
test ('initializeCamera sends expected CameraInitializedEvent' , () async {
@@ -1006,26 +1008,37 @@ void main() {
1006
1008
1007
1009
group ('video recording' , () {
1008
1010
test (
1009
- 'startVideoCapturing binds video capture use case and starts the recording' ,
1011
+ 'startVideoCapturing binds video capture use case, updates saved camera instance and its properties, and starts the recording' ,
1010
1012
() async {
1011
1013
// Set up mocks and constants.
1012
1014
final AndroidCameraCameraX camera = AndroidCameraCameraX ();
1013
1015
final MockPendingRecording mockPendingRecording = MockPendingRecording ();
1014
1016
final MockRecording mockRecording = MockRecording ();
1017
+ final MockCamera mockCamera = MockCamera ();
1018
+ final MockCamera newMockCamera = MockCamera ();
1019
+ final MockCameraInfo mockCameraInfo = MockCameraInfo ();
1020
+ final MockLiveCameraState mockLiveCameraState = MockLiveCameraState ();
1021
+ final MockLiveCameraState newMockLiveCameraState = MockLiveCameraState ();
1015
1022
final TestSystemServicesHostApi mockSystemServicesApi =
1016
1023
MockTestSystemServicesHostApi ();
1017
1024
TestSystemServicesHostApi .setup (mockSystemServicesApi);
1018
1025
1019
1026
// Set directly for test versus calling createCamera.
1020
1027
camera.processCameraProvider = MockProcessCameraProvider ();
1021
- camera.camera = MockCamera () ;
1028
+ camera.camera = mockCamera ;
1022
1029
camera.recorder = MockRecorder ();
1023
1030
camera.videoCapture = MockVideoCapture ();
1024
1031
camera.cameraSelector = MockCameraSelector ();
1032
+ camera.liveCameraState = mockLiveCameraState;
1025
1033
1026
1034
// Ignore setting target rotation for this test; tested seprately.
1027
1035
camera.captureOrientationLocked = true ;
1028
1036
1037
+ // Tell plugin to create detached Observer when camera info updated.
1038
+ camera.proxy = CameraXProxy (
1039
+ createCameraStateObserver: (void Function (Object ) onChanged) =>
1040
+ Observer <CameraState >.detached (onChanged: onChanged));
1041
+
1029
1042
const int cameraId = 17 ;
1030
1043
const String outputPath = '/temp/MOV123.temp' ;
1031
1044
@@ -1039,12 +1052,30 @@ void main() {
1039
1052
.thenAnswer ((_) async => false );
1040
1053
when (camera.processCameraProvider! .bindToLifecycle (
1041
1054
camera.cameraSelector! , < UseCase > [camera.videoCapture! ]))
1042
- .thenAnswer ((_) async => camera.camera! );
1055
+ .thenAnswer ((_) async => newMockCamera);
1056
+ when (newMockCamera.getCameraInfo ())
1057
+ .thenAnswer ((_) async => mockCameraInfo);
1058
+ when (mockCameraInfo.getCameraState ())
1059
+ .thenAnswer ((_) async => newMockLiveCameraState);
1043
1060
1044
1061
await camera.startVideoCapturing (const VideoCaptureOptions (cameraId));
1045
1062
1063
+ // Verify VideoCapture UseCase is bound and camera & its properties
1064
+ // are updated.
1046
1065
verify (camera.processCameraProvider! .bindToLifecycle (
1047
1066
camera.cameraSelector! , < UseCase > [camera.videoCapture! ]));
1067
+ expect (camera.camera, equals (newMockCamera));
1068
+ expect (camera.cameraInfo, equals (mockCameraInfo));
1069
+ verify (mockLiveCameraState.removeObservers ());
1070
+ expect (
1071
+ await testCameraClosingObserver (
1072
+ camera,
1073
+ cameraId,
1074
+ verify (newMockLiveCameraState.observe (captureAny)).captured.single
1075
+ as Observer <dynamic >),
1076
+ isTrue);
1077
+
1078
+ // Verify recording is started.
1048
1079
expect (camera.pendingRecording, equals (mockPendingRecording));
1049
1080
expect (camera.recording, mockRecording);
1050
1081
});
@@ -1056,6 +1087,8 @@ void main() {
1056
1087
final AndroidCameraCameraX camera = AndroidCameraCameraX ();
1057
1088
final MockPendingRecording mockPendingRecording = MockPendingRecording ();
1058
1089
final MockRecording mockRecording = MockRecording ();
1090
+ final MockCamera mockCamera = MockCamera ();
1091
+ final MockCameraInfo mockCameraInfo = MockCameraInfo ();
1059
1092
final TestSystemServicesHostApi mockSystemServicesApi =
1060
1093
MockTestSystemServicesHostApi ();
1061
1094
TestSystemServicesHostApi .setup (mockSystemServicesApi);
@@ -1069,6 +1102,11 @@ void main() {
1069
1102
// Ignore setting target rotation for this test; tested seprately.
1070
1103
camera.captureOrientationLocked = true ;
1071
1104
1105
+ // Tell plugin to create detached Observer when camera info updated.
1106
+ camera.proxy = CameraXProxy (
1107
+ createCameraStateObserver: (void Function (Object ) onChanged) =>
1108
+ Observer <CameraState >.detached (onChanged: onChanged));
1109
+
1072
1110
const int cameraId = 17 ;
1073
1111
const String outputPath = '/temp/MOV123.temp' ;
1074
1112
@@ -1082,7 +1120,11 @@ void main() {
1082
1120
.thenAnswer ((_) async => false );
1083
1121
when (camera.processCameraProvider! .bindToLifecycle (
1084
1122
camera.cameraSelector! , < UseCase > [camera.videoCapture! ]))
1085
- .thenAnswer ((_) async => MockCamera ());
1123
+ .thenAnswer ((_) async => mockCamera);
1124
+ when (mockCamera.getCameraInfo ())
1125
+ .thenAnswer ((_) => Future <CameraInfo >.value (mockCameraInfo));
1126
+ when (mockCameraInfo.getCameraState ())
1127
+ .thenAnswer ((_) async => MockLiveCameraState ());
1086
1128
1087
1129
await camera.startVideoCapturing (const VideoCaptureOptions (cameraId));
1088
1130
@@ -1267,9 +1309,14 @@ void main() {
1267
1309
camera.videoCapture = videoCapture;
1268
1310
camera.videoOutputPath = videoOutputPath;
1269
1311
1312
+ // Tell plugin that videoCapture use case was bound to start recording.
1313
+ when (camera.processCameraProvider! .isBound (videoCapture))
1314
+ .thenAnswer ((_) async => true );
1315
+
1270
1316
final XFile file = await camera.stopVideoRecording (0 );
1271
1317
expect (file.path, videoOutputPath);
1272
1318
1319
+ // Verify that recording stops.
1273
1320
verify (recording.close ());
1274
1321
verifyNoMoreInteractions (recording);
1275
1322
});
@@ -1284,47 +1331,57 @@ void main() {
1284
1331
camera.recording = null ;
1285
1332
camera.videoOutputPath = videoOutputPath;
1286
1333
1287
- expect (
1288
- () => camera.stopVideoRecording (0 ), throwsA (isA <CameraException >()));
1334
+ await expectLater (() async {
1335
+ await camera.stopVideoRecording (0 );
1336
+ }, throwsA (isA <CameraException >()));
1289
1337
});
1338
+ });
1290
1339
1291
- test (
1292
- 'stopVideoRecording throws a camera exception if '
1293
- 'videoOutputPath is null, and sets recording to null' , () async {
1294
- final AndroidCameraCameraX camera = AndroidCameraCameraX ();
1295
- final MockRecording recording = MockRecording ();
1340
+ test (
1341
+ 'stopVideoRecording throws a camera exception if '
1342
+ 'videoOutputPath is null, and sets recording to null' , () async {
1343
+ final AndroidCameraCameraX camera = AndroidCameraCameraX ();
1344
+ final MockRecording mockRecording = MockRecording ();
1345
+ final MockVideoCapture mockVideoCapture = MockVideoCapture ();
1296
1346
1297
- // Set directly for test versus calling startVideoCapturing.
1298
- camera.recording = recording;
1299
- camera.videoOutputPath = null ;
1347
+ // Set directly for test versus calling startVideoCapturing.
1348
+ camera.processCameraProvider = MockProcessCameraProvider ();
1349
+ camera.recording = mockRecording;
1350
+ camera.videoOutputPath = null ;
1351
+ camera.videoCapture = mockVideoCapture;
1300
1352
1301
- expect (
1302
- () => camera.stopVideoRecording (0 ), throwsA (isA <CameraException >()));
1303
- expect (camera.recording, null );
1304
- });
1353
+ // Tell plugin that videoCapture use case was bound to start recording.
1354
+ when (camera.processCameraProvider! .isBound (mockVideoCapture))
1355
+ .thenAnswer ((_) async => true );
1305
1356
1306
- test (
1307
- 'calling stopVideoRecording twice stops the recording '
1308
- 'and then throws a CameraException' , () async {
1309
- final AndroidCameraCameraX camera = AndroidCameraCameraX ();
1310
- final MockRecording recording = MockRecording ();
1311
- final MockProcessCameraProvider processCameraProvider =
1312
- MockProcessCameraProvider ();
1313
- final MockVideoCapture videoCapture = MockVideoCapture ();
1314
- const String videoOutputPath = '/test/output/path' ;
1357
+ await expectLater (() async {
1358
+ await camera.stopVideoRecording (0 );
1359
+ }, throwsA (isA <CameraException >()));
1360
+ expect (camera.recording, null );
1361
+ });
1315
1362
1316
- // Set directly for test versus calling createCamera and startVideoCapturing.
1317
- camera.processCameraProvider = processCameraProvider;
1318
- camera.recording = recording;
1319
- camera.videoCapture = videoCapture;
1320
- camera.videoOutputPath = videoOutputPath;
1363
+ test (
1364
+ 'calling stopVideoRecording twice stops the recording '
1365
+ 'and then throws a CameraException' , () async {
1366
+ final AndroidCameraCameraX camera = AndroidCameraCameraX ();
1367
+ final MockRecording recording = MockRecording ();
1368
+ final MockProcessCameraProvider processCameraProvider =
1369
+ MockProcessCameraProvider ();
1370
+ final MockVideoCapture videoCapture = MockVideoCapture ();
1371
+ const String videoOutputPath = '/test/output/path' ;
1321
1372
1322
- final XFile file = await camera.stopVideoRecording (0 );
1323
- expect (file.path, videoOutputPath);
1373
+ // Set directly for test versus calling createCamera and startVideoCapturing.
1374
+ camera.processCameraProvider = processCameraProvider;
1375
+ camera.recording = recording;
1376
+ camera.videoCapture = videoCapture;
1377
+ camera.videoOutputPath = videoOutputPath;
1324
1378
1325
- expect (
1326
- () => camera.stopVideoRecording (0 ), throwsA (isA <CameraException >()));
1327
- });
1379
+ final XFile file = await camera.stopVideoRecording (0 );
1380
+ expect (file.path, videoOutputPath);
1381
+
1382
+ await expectLater (() async {
1383
+ await camera.stopVideoRecording (0 );
1384
+ }, throwsA (isA <CameraException >()));
1328
1385
});
1329
1386
1330
1387
test (
0 commit comments