diff --git a/packages/camera/camera_web/CHANGELOG.md b/packages/camera/camera_web/CHANGELOG.md index cfb980a602c1..c72e31fc0f18 100644 --- a/packages/camera/camera_web/CHANGELOG.md +++ b/packages/camera/camera_web/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.1+3 + +* Internal code cleanup for stricter analysis options. + ## 0.2.1+2 * Fixes cameraNotReadable error that prevented access to the camera on some Android devices when initializing a camera. diff --git a/packages/camera/camera_web/analysis_options.yaml b/packages/camera/camera_web/analysis_options.yaml deleted file mode 100644 index 5aeb4e7c5e21..000000000000 --- a/packages/camera/camera_web/analysis_options.yaml +++ /dev/null @@ -1 +0,0 @@ -include: ../../../analysis_options_legacy.yaml diff --git a/packages/camera/camera_web/example/integration_test/camera_error_code_test.dart b/packages/camera/camera_web/example/integration_test/camera_error_code_test.dart index a298b57dfd7f..112683bdad98 100644 --- a/packages/camera/camera_web/example/integration_test/camera_error_code_test.dart +++ b/packages/camera/camera_web/example/integration_test/camera_error_code_test.dart @@ -15,112 +15,112 @@ void main() { group('CameraErrorCode', () { group('toString returns a correct type for', () { - testWidgets('notSupported', (tester) async { + testWidgets('notSupported', (WidgetTester tester) async { expect( CameraErrorCode.notSupported.toString(), equals('cameraNotSupported'), ); }); - testWidgets('notFound', (tester) async { + testWidgets('notFound', (WidgetTester tester) async { expect( CameraErrorCode.notFound.toString(), equals('cameraNotFound'), ); }); - testWidgets('notReadable', (tester) async { + testWidgets('notReadable', (WidgetTester tester) async { expect( CameraErrorCode.notReadable.toString(), equals('cameraNotReadable'), ); }); - testWidgets('overconstrained', (tester) async { + testWidgets('overconstrained', (WidgetTester tester) async { expect( CameraErrorCode.overconstrained.toString(), equals('cameraOverconstrained'), ); }); - testWidgets('permissionDenied', (tester) async { + testWidgets('permissionDenied', (WidgetTester tester) async { expect( CameraErrorCode.permissionDenied.toString(), equals('cameraPermission'), ); }); - testWidgets('type', (tester) async { + testWidgets('type', (WidgetTester tester) async { expect( CameraErrorCode.type.toString(), equals('cameraType'), ); }); - testWidgets('abort', (tester) async { + testWidgets('abort', (WidgetTester tester) async { expect( CameraErrorCode.abort.toString(), equals('cameraAbort'), ); }); - testWidgets('security', (tester) async { + testWidgets('security', (WidgetTester tester) async { expect( CameraErrorCode.security.toString(), equals('cameraSecurity'), ); }); - testWidgets('missingMetadata', (tester) async { + testWidgets('missingMetadata', (WidgetTester tester) async { expect( CameraErrorCode.missingMetadata.toString(), equals('cameraMissingMetadata'), ); }); - testWidgets('orientationNotSupported', (tester) async { + testWidgets('orientationNotSupported', (WidgetTester tester) async { expect( CameraErrorCode.orientationNotSupported.toString(), equals('orientationNotSupported'), ); }); - testWidgets('torchModeNotSupported', (tester) async { + testWidgets('torchModeNotSupported', (WidgetTester tester) async { expect( CameraErrorCode.torchModeNotSupported.toString(), equals('torchModeNotSupported'), ); }); - testWidgets('zoomLevelNotSupported', (tester) async { + testWidgets('zoomLevelNotSupported', (WidgetTester tester) async { expect( CameraErrorCode.zoomLevelNotSupported.toString(), equals('zoomLevelNotSupported'), ); }); - testWidgets('zoomLevelInvalid', (tester) async { + testWidgets('zoomLevelInvalid', (WidgetTester tester) async { expect( CameraErrorCode.zoomLevelInvalid.toString(), equals('zoomLevelInvalid'), ); }); - testWidgets('notStarted', (tester) async { + testWidgets('notStarted', (WidgetTester tester) async { expect( CameraErrorCode.notStarted.toString(), equals('cameraNotStarted'), ); }); - testWidgets('videoRecordingNotStarted', (tester) async { + testWidgets('videoRecordingNotStarted', (WidgetTester tester) async { expect( CameraErrorCode.videoRecordingNotStarted.toString(), equals('videoRecordingNotStarted'), ); }); - testWidgets('unknown', (tester) async { + testWidgets('unknown', (WidgetTester tester) async { expect( CameraErrorCode.unknown.toString(), equals('cameraUnknown'), @@ -128,7 +128,7 @@ void main() { }); group('fromMediaError', () { - testWidgets('with aborted error code', (tester) async { + testWidgets('with aborted error code', (WidgetTester tester) async { expect( CameraErrorCode.fromMediaError( FakeMediaError(MediaError.MEDIA_ERR_ABORTED), @@ -137,7 +137,7 @@ void main() { ); }); - testWidgets('with network error code', (tester) async { + testWidgets('with network error code', (WidgetTester tester) async { expect( CameraErrorCode.fromMediaError( FakeMediaError(MediaError.MEDIA_ERR_NETWORK), @@ -146,7 +146,7 @@ void main() { ); }); - testWidgets('with decode error code', (tester) async { + testWidgets('with decode error code', (WidgetTester tester) async { expect( CameraErrorCode.fromMediaError( FakeMediaError(MediaError.MEDIA_ERR_DECODE), @@ -155,7 +155,8 @@ void main() { ); }); - testWidgets('with source not supported error code', (tester) async { + testWidgets('with source not supported error code', + (WidgetTester tester) async { expect( CameraErrorCode.fromMediaError( FakeMediaError(MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED), @@ -164,7 +165,7 @@ void main() { ); }); - testWidgets('with unknown error code', (tester) async { + testWidgets('with unknown error code', (WidgetTester tester) async { expect( CameraErrorCode.fromMediaError( FakeMediaError(5), diff --git a/packages/camera/camera_web/example/integration_test/camera_metadata_test.dart b/packages/camera/camera_web/example/integration_test/camera_metadata_test.dart index 36ecb3e47f31..07252be5c7a2 100644 --- a/packages/camera/camera_web/example/integration_test/camera_metadata_test.dart +++ b/packages/camera/camera_web/example/integration_test/camera_metadata_test.dart @@ -10,14 +10,14 @@ void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('CameraMetadata', () { - testWidgets('supports value equality', (tester) async { + testWidgets('supports value equality', (WidgetTester tester) async { expect( - CameraMetadata( + const CameraMetadata( deviceId: 'deviceId', facingMode: 'environment', ), equals( - CameraMetadata( + const CameraMetadata( deviceId: 'deviceId', facingMode: 'environment', ), diff --git a/packages/camera/camera_web/example/integration_test/camera_options_test.dart b/packages/camera/camera_web/example/integration_test/camera_options_test.dart index a74ba3088394..ee63d87e9f07 100644 --- a/packages/camera/camera_web/example/integration_test/camera_options_test.dart +++ b/packages/camera/camera_web/example/integration_test/camera_options_test.dart @@ -10,9 +10,9 @@ void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('CameraOptions', () { - testWidgets('serializes correctly', (tester) async { - final cameraOptions = CameraOptions( - audio: AudioConstraints(enabled: true), + testWidgets('serializes correctly', (WidgetTester tester) async { + final CameraOptions cameraOptions = CameraOptions( + audio: const AudioConstraints(enabled: true), video: VideoConstraints( facingMode: FacingModeConstraint.exact(CameraType.user), ), @@ -20,31 +20,35 @@ void main() { expect( cameraOptions.toJson(), - equals({ + equals({ 'audio': cameraOptions.audio.toJson(), 'video': cameraOptions.video.toJson(), }), ); }); - testWidgets('supports value equality', (tester) async { + testWidgets('supports value equality', (WidgetTester tester) async { expect( CameraOptions( - audio: AudioConstraints(enabled: false), + audio: const AudioConstraints(enabled: false), video: VideoConstraints( facingMode: FacingModeConstraint(CameraType.environment), - width: VideoSizeConstraint(minimum: 10, ideal: 15, maximum: 20), - height: VideoSizeConstraint(minimum: 15, ideal: 20, maximum: 25), + width: + const VideoSizeConstraint(minimum: 10, ideal: 15, maximum: 20), + height: + const VideoSizeConstraint(minimum: 15, ideal: 20, maximum: 25), deviceId: 'deviceId', ), ), equals( CameraOptions( - audio: AudioConstraints(enabled: false), + audio: const AudioConstraints(enabled: false), video: VideoConstraints( facingMode: FacingModeConstraint(CameraType.environment), - width: VideoSizeConstraint(minimum: 10, ideal: 15, maximum: 20), - height: VideoSizeConstraint(minimum: 15, ideal: 20, maximum: 25), + width: const VideoSizeConstraint( + minimum: 10, ideal: 15, maximum: 20), + height: const VideoSizeConstraint( + minimum: 15, ideal: 20, maximum: 25), deviceId: 'deviceId', ), ), @@ -54,56 +58,60 @@ void main() { }); group('AudioConstraints', () { - testWidgets('serializes correctly', (tester) async { + testWidgets('serializes correctly', (WidgetTester tester) async { expect( - AudioConstraints(enabled: true).toJson(), + const AudioConstraints(enabled: true).toJson(), equals(true), ); }); - testWidgets('supports value equality', (tester) async { + testWidgets('supports value equality', (WidgetTester tester) async { expect( - AudioConstraints(enabled: true), - equals(AudioConstraints(enabled: true)), + const AudioConstraints(enabled: true), + equals(const AudioConstraints(enabled: true)), ); }); }); group('VideoConstraints', () { - testWidgets('serializes correctly', (tester) async { - final videoConstraints = VideoConstraints( + testWidgets('serializes correctly', (WidgetTester tester) async { + final VideoConstraints videoConstraints = VideoConstraints( facingMode: FacingModeConstraint.exact(CameraType.user), - width: VideoSizeConstraint(ideal: 100, maximum: 100), - height: VideoSizeConstraint(ideal: 50, maximum: 50), + width: const VideoSizeConstraint(ideal: 100, maximum: 100), + height: const VideoSizeConstraint(ideal: 50, maximum: 50), deviceId: 'deviceId', ); expect( videoConstraints.toJson(), - equals({ + equals({ 'facingMode': videoConstraints.facingMode!.toJson(), 'width': videoConstraints.width!.toJson(), 'height': videoConstraints.height!.toJson(), - 'deviceId': { + 'deviceId': { 'exact': 'deviceId', } }), ); }); - testWidgets('supports value equality', (tester) async { + testWidgets('supports value equality', (WidgetTester tester) async { expect( VideoConstraints( facingMode: FacingModeConstraint.exact(CameraType.environment), - width: VideoSizeConstraint(minimum: 90, ideal: 100, maximum: 100), - height: VideoSizeConstraint(minimum: 40, ideal: 50, maximum: 50), + width: + const VideoSizeConstraint(minimum: 90, ideal: 100, maximum: 100), + height: + const VideoSizeConstraint(minimum: 40, ideal: 50, maximum: 50), deviceId: 'deviceId', ), equals( VideoConstraints( facingMode: FacingModeConstraint.exact(CameraType.environment), - width: VideoSizeConstraint(minimum: 90, ideal: 100, maximum: 100), - height: VideoSizeConstraint(minimum: 40, ideal: 50, maximum: 50), + width: const VideoSizeConstraint( + minimum: 90, ideal: 100, maximum: 100), + height: + const VideoSizeConstraint(minimum: 40, ideal: 50, maximum: 50), deviceId: 'deviceId', ), ), @@ -115,23 +123,23 @@ void main() { group('ideal', () { testWidgets( 'serializes correctly ' - 'for environment camera type', (tester) async { + 'for environment camera type', (WidgetTester tester) async { expect( FacingModeConstraint(CameraType.environment).toJson(), - equals({'ideal': 'environment'}), + equals({'ideal': 'environment'}), ); }); testWidgets( 'serializes correctly ' - 'for user camera type', (tester) async { + 'for user camera type', (WidgetTester tester) async { expect( FacingModeConstraint(CameraType.user).toJson(), - equals({'ideal': 'user'}), + equals({'ideal': 'user'}), ); }); - testWidgets('supports value equality', (tester) async { + testWidgets('supports value equality', (WidgetTester tester) async { expect( FacingModeConstraint(CameraType.user), equals(FacingModeConstraint(CameraType.user)), @@ -142,23 +150,23 @@ void main() { group('exact', () { testWidgets( 'serializes correctly ' - 'for environment camera type', (tester) async { + 'for environment camera type', (WidgetTester tester) async { expect( FacingModeConstraint.exact(CameraType.environment).toJson(), - equals({'exact': 'environment'}), + equals({'exact': 'environment'}), ); }); testWidgets( 'serializes correctly ' - 'for user camera type', (tester) async { + 'for user camera type', (WidgetTester tester) async { expect( FacingModeConstraint.exact(CameraType.user).toJson(), - equals({'exact': 'user'}), + equals({'exact': 'user'}), ); }); - testWidgets('supports value equality', (tester) async { + testWidgets('supports value equality', (WidgetTester tester) async { expect( FacingModeConstraint.exact(CameraType.environment), equals(FacingModeConstraint.exact(CameraType.environment)), @@ -168,14 +176,14 @@ void main() { }); group('VideoSizeConstraint ', () { - testWidgets('serializes correctly', (tester) async { + testWidgets('serializes correctly', (WidgetTester tester) async { expect( - VideoSizeConstraint( + const VideoSizeConstraint( minimum: 200, ideal: 400, maximum: 400, ).toJson(), - equals({ + equals({ 'min': 200, 'ideal': 400, 'max': 400, @@ -183,15 +191,15 @@ void main() { ); }); - testWidgets('supports value equality', (tester) async { + testWidgets('supports value equality', (WidgetTester tester) async { expect( - VideoSizeConstraint( + const VideoSizeConstraint( minimum: 100, ideal: 200, maximum: 300, ), equals( - VideoSizeConstraint( + const VideoSizeConstraint( minimum: 100, ideal: 200, maximum: 300, diff --git a/packages/camera/camera_web/example/integration_test/camera_service_test.dart b/packages/camera/camera_web/example/integration_test/camera_service_test.dart index 346ab26237ea..6bc03429940c 100644 --- a/packages/camera/camera_web/example/integration_test/camera_service_test.dart +++ b/packages/camera/camera_web/example/integration_test/camera_service_test.dart @@ -3,8 +3,8 @@ // found in the LICENSE file. import 'dart:html'; -import 'dart:ui'; import 'dart:js_util' as js_util; +import 'dart:ui'; import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:camera_web/src/camera.dart'; @@ -22,7 +22,7 @@ void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('CameraService', () { - const cameraId = 0; + const int cameraId = 0; late Window window; late Navigator navigator; @@ -40,10 +40,10 @@ void main() { when(() => navigator.mediaDevices).thenReturn(mediaDevices); // Mock JsUtil to return the real getProperty from dart:js_util. - when(() => jsUtil.getProperty(any(), any())).thenAnswer( - (invocation) => js_util.getProperty( - invocation.positionalArguments[0], - invocation.positionalArguments[1], + when(() => jsUtil.getProperty(any(), any())).thenAnswer( + (Invocation invocation) => js_util.getProperty( + invocation.positionalArguments[0] as Object, + invocation.positionalArguments[1] as Object, ), ); @@ -53,14 +53,14 @@ void main() { group('getMediaStreamForOptions', () { testWidgets( 'calls MediaDevices.getUserMedia ' - 'with provided options', (tester) async { + 'with provided options', (WidgetTester tester) async { when(() => mediaDevices.getUserMedia(any())) - .thenAnswer((_) async => FakeMediaStream([])); + .thenAnswer((_) async => FakeMediaStream([])); - final options = CameraOptions( + final CameraOptions options = CameraOptions( video: VideoConstraints( facingMode: FacingModeConstraint.exact(CameraType.user), - width: VideoSizeConstraint(ideal: 200), + width: const VideoSizeConstraint(ideal: 200), ), ); @@ -74,14 +74,14 @@ void main() { testWidgets( 'throws PlatformException ' 'with notSupported error ' - 'when there are no media devices', (tester) async { + 'when there are no media devices', (WidgetTester tester) async { when(() => navigator.mediaDevices).thenReturn(null); expect( - () => cameraService.getMediaStreamForOptions(CameraOptions()), + () => cameraService.getMediaStreamForOptions(const CameraOptions()), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', CameraErrorCode.notSupported.toString(), ), @@ -93,19 +93,21 @@ void main() { testWidgets( 'with notFound error ' 'when MediaDevices.getUserMedia throws DomException ' - 'with NotFoundError', (tester) async { + 'with NotFoundError', (WidgetTester tester) async { when(() => mediaDevices.getUserMedia(any())) .thenThrow(FakeDomException('NotFoundError')); expect( () => cameraService.getMediaStreamForOptions( - CameraOptions(), + const CameraOptions(), cameraId: cameraId, ), throwsA( isA() - .having((e) => e.cameraId, 'cameraId', cameraId) - .having((e) => e.code, 'code', CameraErrorCode.notFound), + .having((CameraWebException e) => e.cameraId, 'cameraId', + cameraId) + .having((CameraWebException e) => e.code, 'code', + CameraErrorCode.notFound), ), ); }); @@ -113,19 +115,21 @@ void main() { testWidgets( 'with notFound error ' 'when MediaDevices.getUserMedia throws DomException ' - 'with DevicesNotFoundError', (tester) async { + 'with DevicesNotFoundError', (WidgetTester tester) async { when(() => mediaDevices.getUserMedia(any())) .thenThrow(FakeDomException('DevicesNotFoundError')); expect( () => cameraService.getMediaStreamForOptions( - CameraOptions(), + const CameraOptions(), cameraId: cameraId, ), throwsA( isA() - .having((e) => e.cameraId, 'cameraId', cameraId) - .having((e) => e.code, 'code', CameraErrorCode.notFound), + .having((CameraWebException e) => e.cameraId, 'cameraId', + cameraId) + .having((CameraWebException e) => e.code, 'code', + CameraErrorCode.notFound), ), ); }); @@ -133,19 +137,21 @@ void main() { testWidgets( 'with notReadable error ' 'when MediaDevices.getUserMedia throws DomException ' - 'with NotReadableError', (tester) async { + 'with NotReadableError', (WidgetTester tester) async { when(() => mediaDevices.getUserMedia(any())) .thenThrow(FakeDomException('NotReadableError')); expect( () => cameraService.getMediaStreamForOptions( - CameraOptions(), + const CameraOptions(), cameraId: cameraId, ), throwsA( isA() - .having((e) => e.cameraId, 'cameraId', cameraId) - .having((e) => e.code, 'code', CameraErrorCode.notReadable), + .having((CameraWebException e) => e.cameraId, 'cameraId', + cameraId) + .having((CameraWebException e) => e.code, 'code', + CameraErrorCode.notReadable), ), ); }); @@ -153,19 +159,21 @@ void main() { testWidgets( 'with notReadable error ' 'when MediaDevices.getUserMedia throws DomException ' - 'with TrackStartError', (tester) async { + 'with TrackStartError', (WidgetTester tester) async { when(() => mediaDevices.getUserMedia(any())) .thenThrow(FakeDomException('TrackStartError')); expect( () => cameraService.getMediaStreamForOptions( - CameraOptions(), + const CameraOptions(), cameraId: cameraId, ), throwsA( isA() - .having((e) => e.cameraId, 'cameraId', cameraId) - .having((e) => e.code, 'code', CameraErrorCode.notReadable), + .having((CameraWebException e) => e.cameraId, 'cameraId', + cameraId) + .having((CameraWebException e) => e.code, 'code', + CameraErrorCode.notReadable), ), ); }); @@ -173,20 +181,21 @@ void main() { testWidgets( 'with overconstrained error ' 'when MediaDevices.getUserMedia throws DomException ' - 'with OverconstrainedError', (tester) async { + 'with OverconstrainedError', (WidgetTester tester) async { when(() => mediaDevices.getUserMedia(any())) .thenThrow(FakeDomException('OverconstrainedError')); expect( () => cameraService.getMediaStreamForOptions( - CameraOptions(), + const CameraOptions(), cameraId: cameraId, ), throwsA( isA() - .having((e) => e.cameraId, 'cameraId', cameraId) - .having( - (e) => e.code, 'code', CameraErrorCode.overconstrained), + .having((CameraWebException e) => e.cameraId, 'cameraId', + cameraId) + .having((CameraWebException e) => e.code, 'code', + CameraErrorCode.overconstrained), ), ); }); @@ -194,20 +203,21 @@ void main() { testWidgets( 'with overconstrained error ' 'when MediaDevices.getUserMedia throws DomException ' - 'with ConstraintNotSatisfiedError', (tester) async { + 'with ConstraintNotSatisfiedError', (WidgetTester tester) async { when(() => mediaDevices.getUserMedia(any())) .thenThrow(FakeDomException('ConstraintNotSatisfiedError')); expect( () => cameraService.getMediaStreamForOptions( - CameraOptions(), + const CameraOptions(), cameraId: cameraId, ), throwsA( isA() - .having((e) => e.cameraId, 'cameraId', cameraId) - .having( - (e) => e.code, 'code', CameraErrorCode.overconstrained), + .having((CameraWebException e) => e.cameraId, 'cameraId', + cameraId) + .having((CameraWebException e) => e.code, 'code', + CameraErrorCode.overconstrained), ), ); }); @@ -215,20 +225,21 @@ void main() { testWidgets( 'with permissionDenied error ' 'when MediaDevices.getUserMedia throws DomException ' - 'with NotAllowedError', (tester) async { + 'with NotAllowedError', (WidgetTester tester) async { when(() => mediaDevices.getUserMedia(any())) .thenThrow(FakeDomException('NotAllowedError')); expect( () => cameraService.getMediaStreamForOptions( - CameraOptions(), + const CameraOptions(), cameraId: cameraId, ), throwsA( isA() - .having((e) => e.cameraId, 'cameraId', cameraId) - .having( - (e) => e.code, 'code', CameraErrorCode.permissionDenied), + .having((CameraWebException e) => e.cameraId, 'cameraId', + cameraId) + .having((CameraWebException e) => e.code, 'code', + CameraErrorCode.permissionDenied), ), ); }); @@ -236,20 +247,21 @@ void main() { testWidgets( 'with permissionDenied error ' 'when MediaDevices.getUserMedia throws DomException ' - 'with PermissionDeniedError', (tester) async { + 'with PermissionDeniedError', (WidgetTester tester) async { when(() => mediaDevices.getUserMedia(any())) .thenThrow(FakeDomException('PermissionDeniedError')); expect( () => cameraService.getMediaStreamForOptions( - CameraOptions(), + const CameraOptions(), cameraId: cameraId, ), throwsA( isA() - .having((e) => e.cameraId, 'cameraId', cameraId) - .having( - (e) => e.code, 'code', CameraErrorCode.permissionDenied), + .having((CameraWebException e) => e.cameraId, 'cameraId', + cameraId) + .having((CameraWebException e) => e.code, 'code', + CameraErrorCode.permissionDenied), ), ); }); @@ -257,19 +269,21 @@ void main() { testWidgets( 'with type error ' 'when MediaDevices.getUserMedia throws DomException ' - 'with TypeError', (tester) async { + 'with TypeError', (WidgetTester tester) async { when(() => mediaDevices.getUserMedia(any())) .thenThrow(FakeDomException('TypeError')); expect( () => cameraService.getMediaStreamForOptions( - CameraOptions(), + const CameraOptions(), cameraId: cameraId, ), throwsA( isA() - .having((e) => e.cameraId, 'cameraId', cameraId) - .having((e) => e.code, 'code', CameraErrorCode.type), + .having((CameraWebException e) => e.cameraId, 'cameraId', + cameraId) + .having((CameraWebException e) => e.code, 'code', + CameraErrorCode.type), ), ); }); @@ -277,19 +291,21 @@ void main() { testWidgets( 'with abort error ' 'when MediaDevices.getUserMedia throws DomException ' - 'with AbortError', (tester) async { + 'with AbortError', (WidgetTester tester) async { when(() => mediaDevices.getUserMedia(any())) .thenThrow(FakeDomException('AbortError')); expect( () => cameraService.getMediaStreamForOptions( - CameraOptions(), + const CameraOptions(), cameraId: cameraId, ), throwsA( isA() - .having((e) => e.cameraId, 'cameraId', cameraId) - .having((e) => e.code, 'code', CameraErrorCode.abort), + .having((CameraWebException e) => e.cameraId, 'cameraId', + cameraId) + .having((CameraWebException e) => e.code, 'code', + CameraErrorCode.abort), ), ); }); @@ -297,19 +313,21 @@ void main() { testWidgets( 'with security error ' 'when MediaDevices.getUserMedia throws DomException ' - 'with SecurityError', (tester) async { + 'with SecurityError', (WidgetTester tester) async { when(() => mediaDevices.getUserMedia(any())) .thenThrow(FakeDomException('SecurityError')); expect( () => cameraService.getMediaStreamForOptions( - CameraOptions(), + const CameraOptions(), cameraId: cameraId, ), throwsA( isA() - .having((e) => e.cameraId, 'cameraId', cameraId) - .having((e) => e.code, 'code', CameraErrorCode.security), + .having((CameraWebException e) => e.cameraId, 'cameraId', + cameraId) + .having((CameraWebException e) => e.code, 'code', + CameraErrorCode.security), ), ); }); @@ -317,19 +335,21 @@ void main() { testWidgets( 'with unknown error ' 'when MediaDevices.getUserMedia throws DomException ' - 'with an unknown error', (tester) async { + 'with an unknown error', (WidgetTester tester) async { when(() => mediaDevices.getUserMedia(any())) .thenThrow(FakeDomException('Unknown')); expect( () => cameraService.getMediaStreamForOptions( - CameraOptions(), + const CameraOptions(), cameraId: cameraId, ), throwsA( isA() - .having((e) => e.cameraId, 'cameraId', cameraId) - .having((e) => e.code, 'code', CameraErrorCode.unknown), + .having((CameraWebException e) => e.cameraId, 'cameraId', + cameraId) + .having((CameraWebException e) => e.code, 'code', + CameraErrorCode.unknown), ), ); }); @@ -337,18 +357,20 @@ void main() { testWidgets( 'with unknown error ' 'when MediaDevices.getUserMedia throws an unknown exception', - (tester) async { + (WidgetTester tester) async { when(() => mediaDevices.getUserMedia(any())).thenThrow(Exception()); expect( () => cameraService.getMediaStreamForOptions( - CameraOptions(), + const CameraOptions(), cameraId: cameraId, ), throwsA( isA() - .having((e) => e.cameraId, 'cameraId', cameraId) - .having((e) => e.code, 'code', CameraErrorCode.unknown), + .having((CameraWebException e) => e.cameraId, 'cameraId', + cameraId) + .having((CameraWebException e) => e.code, 'code', + CameraErrorCode.unknown), ), ); }); @@ -361,7 +383,10 @@ void main() { setUp(() { camera = MockCamera(); - videoTracks = [MockMediaStreamTrack(), MockMediaStreamTrack()]; + videoTracks = [ + MockMediaStreamTrack(), + MockMediaStreamTrack() + ]; when(() => camera.textureId).thenReturn(0); when(() => camera.stream).thenReturn(FakeMediaStream(videoTracks)); @@ -371,20 +396,21 @@ void main() { testWidgets( 'returns the zoom level capability ' - 'based on the first video track', (tester) async { - when(mediaDevices.getSupportedConstraints).thenReturn({ + 'based on the first video track', (WidgetTester tester) async { + when(mediaDevices.getSupportedConstraints) + .thenReturn({ 'zoom': true, }); - when(videoTracks.first.getCapabilities).thenReturn({ - 'zoom': js_util.jsify({ + when(videoTracks.first.getCapabilities).thenReturn({ + 'zoom': js_util.jsify({ 'min': 100, 'max': 400, 'step': 2, }), }); - final zoomLevelCapability = + final ZoomLevelCapability zoomLevelCapability = cameraService.getZoomLevelCapabilityForCamera(camera); expect(zoomLevelCapability.minimum, equals(100.0)); @@ -395,7 +421,7 @@ void main() { group('throws CameraWebException', () { testWidgets( 'with zoomLevelNotSupported error ' - 'when there are no media devices', (tester) async { + 'when there are no media devices', (WidgetTester tester) async { when(() => navigator.mediaDevices).thenReturn(null); expect( @@ -403,12 +429,12 @@ void main() { throwsA( isA() .having( - (e) => e.cameraId, + (CameraWebException e) => e.cameraId, 'cameraId', camera.textureId, ) .having( - (e) => e.code, + (CameraWebException e) => e.code, 'code', CameraErrorCode.zoomLevelNotSupported, ), @@ -419,13 +445,14 @@ void main() { testWidgets( 'with zoomLevelNotSupported error ' 'when the zoom level is not supported ' - 'in the browser', (tester) async { - when(mediaDevices.getSupportedConstraints).thenReturn({ + 'in the browser', (WidgetTester tester) async { + when(mediaDevices.getSupportedConstraints) + .thenReturn({ 'zoom': false, }); - when(videoTracks.first.getCapabilities).thenReturn({ - 'zoom': { + when(videoTracks.first.getCapabilities).thenReturn({ + 'zoom': { 'min': 100, 'max': 400, 'step': 2, @@ -437,12 +464,12 @@ void main() { throwsA( isA() .having( - (e) => e.cameraId, + (CameraWebException e) => e.cameraId, 'cameraId', camera.textureId, ) .having( - (e) => e.code, + (CameraWebException e) => e.code, 'code', CameraErrorCode.zoomLevelNotSupported, ), @@ -453,24 +480,26 @@ void main() { testWidgets( 'with zoomLevelNotSupported error ' 'when the zoom level is not supported ' - 'by the camera', (tester) async { - when(mediaDevices.getSupportedConstraints).thenReturn({ + 'by the camera', (WidgetTester tester) async { + when(mediaDevices.getSupportedConstraints) + .thenReturn({ 'zoom': true, }); - when(videoTracks.first.getCapabilities).thenReturn({}); + when(videoTracks.first.getCapabilities) + .thenReturn({}); expect( () => cameraService.getZoomLevelCapabilityForCamera(camera), throwsA( isA() .having( - (e) => e.cameraId, + (CameraWebException e) => e.cameraId, 'cameraId', camera.textureId, ) .having( - (e) => e.code, + (CameraWebException e) => e.code, 'code', CameraErrorCode.zoomLevelNotSupported, ), @@ -480,25 +509,28 @@ void main() { testWidgets( 'with notStarted error ' - 'when the camera stream has not been initialized', (tester) async { - when(mediaDevices.getSupportedConstraints).thenReturn({ + 'when the camera stream has not been initialized', + (WidgetTester tester) async { + when(mediaDevices.getSupportedConstraints) + .thenReturn({ 'zoom': true, }); // Create a camera stream with no video tracks. - when(() => camera.stream).thenReturn(FakeMediaStream([])); + when(() => camera.stream) + .thenReturn(FakeMediaStream([])); expect( () => cameraService.getZoomLevelCapabilityForCamera(camera), throwsA( isA() .having( - (e) => e.cameraId, + (CameraWebException e) => e.cameraId, 'cameraId', camera.textureId, ) .having( - (e) => e.code, + (CameraWebException e) => e.code, 'code', CameraErrorCode.notStarted, ), @@ -516,7 +548,7 @@ void main() { testWidgets( 'throws PlatformException ' 'with notSupported error ' - 'when there are no media devices', (tester) async { + 'when there are no media devices', (WidgetTester tester) async { when(() => navigator.mediaDevices).thenReturn(null); expect( @@ -524,7 +556,7 @@ void main() { cameraService.getFacingModeForVideoTrack(MockMediaStreamTrack()), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', CameraErrorCode.notSupported.toString(), ), @@ -534,12 +566,13 @@ void main() { testWidgets( 'returns null ' - 'when the facing mode is not supported', (tester) async { - when(mediaDevices.getSupportedConstraints).thenReturn({ + 'when the facing mode is not supported', (WidgetTester tester) async { + when(mediaDevices.getSupportedConstraints) + .thenReturn({ 'facingMode': false, }); - final facingMode = + final String? facingMode = cameraService.getFacingModeForVideoTrack(MockMediaStreamTrack()); expect(facingMode, isNull); @@ -554,17 +587,19 @@ void main() { when(() => jsUtil.hasProperty(videoTrack, 'getCapabilities')) .thenReturn(true); - when(mediaDevices.getSupportedConstraints).thenReturn({ + when(mediaDevices.getSupportedConstraints) + .thenReturn({ 'facingMode': true, }); }); testWidgets( 'returns an appropriate facing mode ' - 'based on the video track settings', (tester) async { - when(videoTrack.getSettings).thenReturn({'facingMode': 'user'}); + 'based on the video track settings', (WidgetTester tester) async { + when(videoTrack.getSettings) + .thenReturn({'facingMode': 'user'}); - final facingMode = + final String? facingMode = cameraService.getFacingModeForVideoTrack(videoTrack); expect(facingMode, equals('user')); @@ -573,16 +608,17 @@ void main() { testWidgets( 'returns an appropriate facing mode ' 'based on the video track capabilities ' - 'when the facing mode setting is empty', (tester) async { - when(videoTrack.getSettings).thenReturn({}); - when(videoTrack.getCapabilities).thenReturn({ - 'facingMode': ['environment', 'left'] + 'when the facing mode setting is empty', + (WidgetTester tester) async { + when(videoTrack.getSettings).thenReturn({}); + when(videoTrack.getCapabilities).thenReturn({ + 'facingMode': ['environment', 'left'] }); when(() => jsUtil.hasProperty(videoTrack, 'getCapabilities')) .thenReturn(true); - final facingMode = + final String? facingMode = cameraService.getFacingModeForVideoTrack(videoTrack); expect(facingMode, equals('environment')); @@ -591,11 +627,12 @@ void main() { testWidgets( 'returns null ' 'when the facing mode setting ' - 'and capabilities are empty', (tester) async { - when(videoTrack.getSettings).thenReturn({}); - when(videoTrack.getCapabilities).thenReturn({'facingMode': []}); + 'and capabilities are empty', (WidgetTester tester) async { + when(videoTrack.getSettings).thenReturn({}); + when(videoTrack.getCapabilities) + .thenReturn({'facingMode': []}); - final facingMode = + final String? facingMode = cameraService.getFacingModeForVideoTrack(videoTrack); expect(facingMode, isNull); @@ -604,13 +641,14 @@ void main() { testWidgets( 'returns null ' 'when the facing mode setting is empty and ' - 'the video track capabilities are not supported', (tester) async { - when(videoTrack.getSettings).thenReturn({}); + 'the video track capabilities are not supported', + (WidgetTester tester) async { + when(videoTrack.getSettings).thenReturn({}); when(() => jsUtil.hasProperty(videoTrack, 'getCapabilities')) .thenReturn(false); - final facingMode = + final String? facingMode = cameraService.getFacingModeForVideoTrack(videoTrack); expect(facingMode, isNull); @@ -621,7 +659,7 @@ void main() { group('mapFacingModeToLensDirection', () { testWidgets( 'returns front ' - 'when the facing mode is user', (tester) async { + 'when the facing mode is user', (WidgetTester tester) async { expect( cameraService.mapFacingModeToLensDirection('user'), equals(CameraLensDirection.front), @@ -630,7 +668,7 @@ void main() { testWidgets( 'returns back ' - 'when the facing mode is environment', (tester) async { + 'when the facing mode is environment', (WidgetTester tester) async { expect( cameraService.mapFacingModeToLensDirection('environment'), equals(CameraLensDirection.back), @@ -639,7 +677,7 @@ void main() { testWidgets( 'returns external ' - 'when the facing mode is left', (tester) async { + 'when the facing mode is left', (WidgetTester tester) async { expect( cameraService.mapFacingModeToLensDirection('left'), equals(CameraLensDirection.external), @@ -648,7 +686,7 @@ void main() { testWidgets( 'returns external ' - 'when the facing mode is right', (tester) async { + 'when the facing mode is right', (WidgetTester tester) async { expect( cameraService.mapFacingModeToLensDirection('right'), equals(CameraLensDirection.external), @@ -659,7 +697,7 @@ void main() { group('mapFacingModeToCameraType', () { testWidgets( 'returns user ' - 'when the facing mode is user', (tester) async { + 'when the facing mode is user', (WidgetTester tester) async { expect( cameraService.mapFacingModeToCameraType('user'), equals(CameraType.user), @@ -668,7 +706,7 @@ void main() { testWidgets( 'returns environment ' - 'when the facing mode is environment', (tester) async { + 'when the facing mode is environment', (WidgetTester tester) async { expect( cameraService.mapFacingModeToCameraType('environment'), equals(CameraType.environment), @@ -677,7 +715,7 @@ void main() { testWidgets( 'returns user ' - 'when the facing mode is left', (tester) async { + 'when the facing mode is left', (WidgetTester tester) async { expect( cameraService.mapFacingModeToCameraType('left'), equals(CameraType.user), @@ -686,7 +724,7 @@ void main() { testWidgets( 'returns user ' - 'when the facing mode is right', (tester) async { + 'when the facing mode is right', (WidgetTester tester) async { expect( cameraService.mapFacingModeToCameraType('right'), equals(CameraType.user), @@ -697,55 +735,57 @@ void main() { group('mapResolutionPresetToSize', () { testWidgets( 'returns 4096x2160 ' - 'when the resolution preset is max', (tester) async { + 'when the resolution preset is max', (WidgetTester tester) async { expect( cameraService.mapResolutionPresetToSize(ResolutionPreset.max), - equals(Size(4096, 2160)), + equals(const Size(4096, 2160)), ); }); testWidgets( 'returns 4096x2160 ' - 'when the resolution preset is ultraHigh', (tester) async { + 'when the resolution preset is ultraHigh', + (WidgetTester tester) async { expect( cameraService.mapResolutionPresetToSize(ResolutionPreset.ultraHigh), - equals(Size(4096, 2160)), + equals(const Size(4096, 2160)), ); }); testWidgets( 'returns 1920x1080 ' - 'when the resolution preset is veryHigh', (tester) async { + 'when the resolution preset is veryHigh', + (WidgetTester tester) async { expect( cameraService.mapResolutionPresetToSize(ResolutionPreset.veryHigh), - equals(Size(1920, 1080)), + equals(const Size(1920, 1080)), ); }); testWidgets( 'returns 1280x720 ' - 'when the resolution preset is high', (tester) async { + 'when the resolution preset is high', (WidgetTester tester) async { expect( cameraService.mapResolutionPresetToSize(ResolutionPreset.high), - equals(Size(1280, 720)), + equals(const Size(1280, 720)), ); }); testWidgets( 'returns 720x480 ' - 'when the resolution preset is medium', (tester) async { + 'when the resolution preset is medium', (WidgetTester tester) async { expect( cameraService.mapResolutionPresetToSize(ResolutionPreset.medium), - equals(Size(720, 480)), + equals(const Size(720, 480)), ); }); testWidgets( 'returns 320x240 ' - 'when the resolution preset is low', (tester) async { + 'when the resolution preset is low', (WidgetTester tester) async { expect( cameraService.mapResolutionPresetToSize(ResolutionPreset.low), - equals(Size(320, 240)), + equals(const Size(320, 240)), ); }); }); @@ -753,7 +793,8 @@ void main() { group('mapDeviceOrientationToOrientationType', () { testWidgets( 'returns portraitPrimary ' - 'when the device orientation is portraitUp', (tester) async { + 'when the device orientation is portraitUp', + (WidgetTester tester) async { expect( cameraService.mapDeviceOrientationToOrientationType( DeviceOrientation.portraitUp, @@ -764,7 +805,8 @@ void main() { testWidgets( 'returns landscapePrimary ' - 'when the device orientation is landscapeLeft', (tester) async { + 'when the device orientation is landscapeLeft', + (WidgetTester tester) async { expect( cameraService.mapDeviceOrientationToOrientationType( DeviceOrientation.landscapeLeft, @@ -775,7 +817,8 @@ void main() { testWidgets( 'returns portraitSecondary ' - 'when the device orientation is portraitDown', (tester) async { + 'when the device orientation is portraitDown', + (WidgetTester tester) async { expect( cameraService.mapDeviceOrientationToOrientationType( DeviceOrientation.portraitDown, @@ -786,7 +829,8 @@ void main() { testWidgets( 'returns landscapeSecondary ' - 'when the device orientation is landscapeRight', (tester) async { + 'when the device orientation is landscapeRight', + (WidgetTester tester) async { expect( cameraService.mapDeviceOrientationToOrientationType( DeviceOrientation.landscapeRight, @@ -799,7 +843,8 @@ void main() { group('mapOrientationTypeToDeviceOrientation', () { testWidgets( 'returns portraitUp ' - 'when the orientation type is portraitPrimary', (tester) async { + 'when the orientation type is portraitPrimary', + (WidgetTester tester) async { expect( cameraService.mapOrientationTypeToDeviceOrientation( OrientationType.portraitPrimary, @@ -810,7 +855,8 @@ void main() { testWidgets( 'returns landscapeLeft ' - 'when the orientation type is landscapePrimary', (tester) async { + 'when the orientation type is landscapePrimary', + (WidgetTester tester) async { expect( cameraService.mapOrientationTypeToDeviceOrientation( OrientationType.landscapePrimary, @@ -821,7 +867,8 @@ void main() { testWidgets( 'returns portraitDown ' - 'when the orientation type is portraitSecondary', (tester) async { + 'when the orientation type is portraitSecondary', + (WidgetTester tester) async { expect( cameraService.mapOrientationTypeToDeviceOrientation( OrientationType.portraitSecondary, @@ -832,7 +879,8 @@ void main() { testWidgets( 'returns portraitDown ' - 'when the orientation type is portraitSecondary', (tester) async { + 'when the orientation type is portraitSecondary', + (WidgetTester tester) async { expect( cameraService.mapOrientationTypeToDeviceOrientation( OrientationType.portraitSecondary, @@ -843,7 +891,8 @@ void main() { testWidgets( 'returns landscapeRight ' - 'when the orientation type is landscapeSecondary', (tester) async { + 'when the orientation type is landscapeSecondary', + (WidgetTester tester) async { expect( cameraService.mapOrientationTypeToDeviceOrientation( OrientationType.landscapeSecondary, @@ -854,7 +903,7 @@ void main() { testWidgets( 'returns portraitUp ' - 'for an unknown orientation type', (tester) async { + 'for an unknown orientation type', (WidgetTester tester) async { expect( cameraService.mapOrientationTypeToDeviceOrientation( 'unknown', diff --git a/packages/camera/camera_web/example/integration_test/camera_test.dart b/packages/camera/camera_web/example/integration_test/camera_test.dart index 3a25e33c5398..4e8050eef6a8 100644 --- a/packages/camera/camera_web/example/integration_test/camera_test.dart +++ b/packages/camera/camera_web/example/integration_test/camera_test.dart @@ -21,7 +21,7 @@ void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('Camera', () { - const textureId = 1; + const int textureId = 1; late Window window; late Navigator navigator; @@ -40,7 +40,8 @@ void main() { cameraService = MockCameraService(); - final videoElement = getVideoElementWithBlankStream(Size(10, 10)); + final VideoElement videoElement = + getVideoElementWithBlankStream(const Size(10, 10)); mediaStream = videoElement.captureStream(); when( @@ -48,7 +49,7 @@ void main() { any(), cameraId: any(named: 'cameraId'), ), - ).thenAnswer((_) => Future.value(mediaStream)); + ).thenAnswer((_) => Future.value(mediaStream)); }); setUpAll(() { @@ -58,15 +59,15 @@ void main() { group('initialize', () { testWidgets( 'calls CameraService.getMediaStreamForOptions ' - 'with provided options', (tester) async { - final options = CameraOptions( + 'with provided options', (WidgetTester tester) async { + final CameraOptions options = CameraOptions( video: VideoConstraints( facingMode: FacingModeConstraint.exact(CameraType.user), - width: VideoSizeConstraint(ideal: 200), + width: const VideoSizeConstraint(ideal: 200), ), ); - final camera = Camera( + final Camera camera = Camera( textureId: textureId, options: options, cameraService: cameraService, @@ -84,15 +85,16 @@ void main() { testWidgets( 'creates a video element ' - 'with correct properties', (tester) async { - const audioConstraints = AudioConstraints(enabled: true); - final videoConstraints = VideoConstraints( + 'with correct properties', (WidgetTester tester) async { + const AudioConstraints audioConstraints = + AudioConstraints(enabled: true); + final VideoConstraints videoConstraints = VideoConstraints( facingMode: FacingModeConstraint( CameraType.user, ), ); - final camera = Camera( + final Camera camera = Camera( textureId: textureId, options: CameraOptions( audio: audioConstraints, @@ -119,14 +121,14 @@ void main() { testWidgets( 'flips the video element horizontally ' - 'for a back camera', (tester) async { - final videoConstraints = VideoConstraints( + 'for a back camera', (WidgetTester tester) async { + final VideoConstraints videoConstraints = VideoConstraints( facingMode: FacingModeConstraint( CameraType.environment, ), ); - final camera = Camera( + final Camera camera = Camera( textureId: textureId, options: CameraOptions( video: videoConstraints, @@ -141,8 +143,8 @@ void main() { testWidgets( 'creates a wrapping div element ' - 'with correct properties', (tester) async { - final camera = Camera( + 'with correct properties', (WidgetTester tester) async { + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, ); @@ -154,8 +156,8 @@ void main() { expect(camera.divElement.children, contains(camera.videoElement)); }); - testWidgets('initializes the camera stream', (tester) async { - final camera = Camera( + testWidgets('initializes the camera stream', (WidgetTester tester) async { + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, ); @@ -167,13 +169,15 @@ void main() { testWidgets( 'throws an exception ' - 'when CameraService.getMediaStreamForOptions throws', (tester) async { - final exception = Exception('A media stream exception occured.'); + 'when CameraService.getMediaStreamForOptions throws', + (WidgetTester tester) async { + final Exception exception = + Exception('A media stream exception occured.'); when(() => cameraService.getMediaStreamForOptions(any(), cameraId: any(named: 'cameraId'))).thenThrow(exception); - final camera = Camera( + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, ); @@ -186,18 +190,20 @@ void main() { }); group('play', () { - testWidgets('starts playing the video element', (tester) async { - var startedPlaying = false; + testWidgets('starts playing the video element', + (WidgetTester tester) async { + bool startedPlaying = false; - final camera = Camera( + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, ); await camera.initialize(); - final cameraPlaySubscription = - camera.videoElement.onPlay.listen((event) => startedPlaying = true); + final StreamSubscription cameraPlaySubscription = camera + .videoElement.onPlay + .listen((Event event) => startedPlaying = true); await camera.play(); @@ -209,14 +215,14 @@ void main() { testWidgets( 'initializes the camera stream ' 'from CameraService.getMediaStreamForOptions ' - 'if it does not exist', (tester) async { - final options = CameraOptions( + 'if it does not exist', (WidgetTester tester) async { + const CameraOptions options = CameraOptions( video: VideoConstraints( width: VideoSizeConstraint(ideal: 100), ), ); - final camera = Camera( + final Camera camera = Camera( textureId: textureId, options: options, cameraService: cameraService, @@ -244,8 +250,8 @@ void main() { }); group('pause', () { - testWidgets('pauses the camera stream', (tester) async { - final camera = Camera( + testWidgets('pauses the camera stream', (WidgetTester tester) async { + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, ); @@ -262,8 +268,8 @@ void main() { }); group('stop', () { - testWidgets('resets the camera stream', (tester) async { - final camera = Camera( + testWidgets('resets the camera stream', (WidgetTester tester) async { + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, ); @@ -279,8 +285,8 @@ void main() { }); group('takePicture', () { - testWidgets('returns a captured picture', (tester) async { - final camera = Camera( + testWidgets('returns a captured picture', (WidgetTester tester) async { + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, ); @@ -288,7 +294,7 @@ void main() { await camera.initialize(); await camera.play(); - final pictureFile = await camera.takePicture(); + final XFile pictureFile = await camera.takePicture(); expect(pictureFile, isNotNull); }); @@ -301,22 +307,25 @@ void main() { late VideoElement videoElement; setUp(() { - videoTracks = [MockMediaStreamTrack(), MockMediaStreamTrack()]; + videoTracks = [ + MockMediaStreamTrack(), + MockMediaStreamTrack() + ]; videoStream = FakeMediaStream(videoTracks); - videoElement = getVideoElementWithBlankStream(Size(100, 100)) + videoElement = getVideoElementWithBlankStream(const Size(100, 100)) ..muted = true; when(() => videoTracks.first.applyConstraints(any())) - .thenAnswer((_) async => {}); + .thenAnswer((_) async => {}); - when(videoTracks.first.getCapabilities).thenReturn({ + when(videoTracks.first.getCapabilities).thenReturn({ 'torch': true, }); }); - testWidgets('if the flash mode is auto', (tester) async { - final camera = Camera( + testWidgets('if the flash mode is auto', (WidgetTester tester) async { + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, ) @@ -327,31 +336,31 @@ void main() { await camera.play(); - final _ = await camera.takePicture(); + final XFile _ = await camera.takePicture(); verify( - () => videoTracks.first.applyConstraints({ - "advanced": [ - { - "torch": true, + () => videoTracks.first.applyConstraints({ + 'advanced': [ + { + 'torch': true, } ] }), ).called(1); verify( - () => videoTracks.first.applyConstraints({ - "advanced": [ - { - "torch": false, + () => videoTracks.first.applyConstraints({ + 'advanced': [ + { + 'torch': false, } ] }), ).called(1); }); - testWidgets('if the flash mode is always', (tester) async { - final camera = Camera( + testWidgets('if the flash mode is always', (WidgetTester tester) async { + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, ) @@ -362,23 +371,23 @@ void main() { await camera.play(); - final _ = await camera.takePicture(); + final XFile _ = await camera.takePicture(); verify( - () => videoTracks.first.applyConstraints({ - "advanced": [ - { - "torch": true, + () => videoTracks.first.applyConstraints({ + 'advanced': [ + { + 'torch': true, } ] }), ).called(1); verify( - () => videoTracks.first.applyConstraints({ - "advanced": [ - { - "torch": false, + () => videoTracks.first.applyConstraints({ + 'advanced': [ + { + 'torch': false, } ] }), @@ -390,13 +399,15 @@ void main() { group('getVideoSize', () { testWidgets( 'returns a size ' - 'based on the first video track settings', (tester) async { - const videoSize = Size(1280, 720); + 'based on the first video track settings', + (WidgetTester tester) async { + const Size videoSize = Size(1280, 720); - final videoElement = getVideoElementWithBlankStream(videoSize); + final VideoElement videoElement = + getVideoElementWithBlankStream(videoSize); mediaStream = videoElement.captureStream(); - final camera = Camera( + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, ); @@ -411,12 +422,12 @@ void main() { testWidgets( 'returns Size.zero ' - 'if the camera is missing video tracks', (tester) async { + 'if the camera is missing video tracks', (WidgetTester tester) async { // Create a video stream with no video tracks. - final videoElement = VideoElement(); + final VideoElement videoElement = VideoElement(); mediaStream = videoElement.captureStream(); - final camera = Camera( + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, ); @@ -435,32 +446,37 @@ void main() { late MediaStream videoStream; setUp(() { - videoTracks = [MockMediaStreamTrack(), MockMediaStreamTrack()]; + videoTracks = [ + MockMediaStreamTrack(), + MockMediaStreamTrack() + ]; videoStream = FakeMediaStream(videoTracks); when(() => videoTracks.first.applyConstraints(any())) - .thenAnswer((_) async => {}); + .thenAnswer((_) async => {}); - when(videoTracks.first.getCapabilities).thenReturn({}); + when(videoTracks.first.getCapabilities) + .thenReturn({}); }); - testWidgets('sets the camera flash mode', (tester) async { - when(mediaDevices.getSupportedConstraints).thenReturn({ + testWidgets('sets the camera flash mode', (WidgetTester tester) async { + when(mediaDevices.getSupportedConstraints) + .thenReturn({ 'torch': true, }); - when(videoTracks.first.getCapabilities).thenReturn({ + when(videoTracks.first.getCapabilities).thenReturn({ 'torch': true, }); - final camera = Camera( + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, ) ..window = window ..stream = videoStream; - const flashMode = FlashMode.always; + const FlashMode flashMode = FlashMode.always; camera.setFlashMode(flashMode); @@ -472,16 +488,17 @@ void main() { testWidgets( 'enables the torch mode ' - 'if the flash mode is torch', (tester) async { - when(mediaDevices.getSupportedConstraints).thenReturn({ + 'if the flash mode is torch', (WidgetTester tester) async { + when(mediaDevices.getSupportedConstraints) + .thenReturn({ 'torch': true, }); - when(videoTracks.first.getCapabilities).thenReturn({ + when(videoTracks.first.getCapabilities).thenReturn({ 'torch': true, }); - final camera = Camera( + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, ) @@ -491,10 +508,10 @@ void main() { camera.setFlashMode(FlashMode.torch); verify( - () => videoTracks.first.applyConstraints({ - "advanced": [ - { - "torch": true, + () => videoTracks.first.applyConstraints({ + 'advanced': [ + { + 'torch': true, } ] }), @@ -503,16 +520,17 @@ void main() { testWidgets( 'disables the torch mode ' - 'if the flash mode is not torch', (tester) async { - when(mediaDevices.getSupportedConstraints).thenReturn({ + 'if the flash mode is not torch', (WidgetTester tester) async { + when(mediaDevices.getSupportedConstraints) + .thenReturn({ 'torch': true, }); - when(videoTracks.first.getCapabilities).thenReturn({ + when(videoTracks.first.getCapabilities).thenReturn({ 'torch': true, }); - final camera = Camera( + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, ) @@ -522,10 +540,10 @@ void main() { camera.setFlashMode(FlashMode.auto); verify( - () => videoTracks.first.applyConstraints({ - "advanced": [ - { - "torch": false, + () => videoTracks.first.applyConstraints({ + 'advanced': [ + { + 'torch': false, } ] }), @@ -535,10 +553,10 @@ void main() { group('throws a CameraWebException', () { testWidgets( 'with torchModeNotSupported error ' - 'when there are no media devices', (tester) async { + 'when there are no media devices', (WidgetTester tester) async { when(() => navigator.mediaDevices).thenReturn(null); - final camera = Camera( + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, ) @@ -550,12 +568,12 @@ void main() { throwsA( isA() .having( - (e) => e.cameraId, + (CameraWebException e) => e.cameraId, 'cameraId', textureId, ) .having( - (e) => e.code, + (CameraWebException e) => e.code, 'code', CameraErrorCode.torchModeNotSupported, ), @@ -566,16 +584,17 @@ void main() { testWidgets( 'with torchModeNotSupported error ' 'when the torch mode is not supported ' - 'in the browser', (tester) async { - when(mediaDevices.getSupportedConstraints).thenReturn({ + 'in the browser', (WidgetTester tester) async { + when(mediaDevices.getSupportedConstraints) + .thenReturn({ 'torch': false, }); - when(videoTracks.first.getCapabilities).thenReturn({ + when(videoTracks.first.getCapabilities).thenReturn({ 'torch': true, }); - final camera = Camera( + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, ) @@ -587,12 +606,12 @@ void main() { throwsA( isA() .having( - (e) => e.cameraId, + (CameraWebException e) => e.cameraId, 'cameraId', textureId, ) .having( - (e) => e.code, + (CameraWebException e) => e.code, 'code', CameraErrorCode.torchModeNotSupported, ), @@ -603,16 +622,17 @@ void main() { testWidgets( 'with torchModeNotSupported error ' 'when the torch mode is not supported ' - 'by the camera', (tester) async { - when(mediaDevices.getSupportedConstraints).thenReturn({ + 'by the camera', (WidgetTester tester) async { + when(mediaDevices.getSupportedConstraints) + .thenReturn({ 'torch': true, }); - when(videoTracks.first.getCapabilities).thenReturn({ + when(videoTracks.first.getCapabilities).thenReturn({ 'torch': false, }); - final camera = Camera( + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, ) @@ -624,12 +644,12 @@ void main() { throwsA( isA() .having( - (e) => e.cameraId, + (CameraWebException e) => e.cameraId, 'cameraId', textureId, ) .having( - (e) => e.code, + (CameraWebException e) => e.code, 'code', CameraErrorCode.torchModeNotSupported, ), @@ -639,16 +659,18 @@ void main() { testWidgets( 'with notStarted error ' - 'when the camera stream has not been initialized', (tester) async { - when(mediaDevices.getSupportedConstraints).thenReturn({ + 'when the camera stream has not been initialized', + (WidgetTester tester) async { + when(mediaDevices.getSupportedConstraints) + .thenReturn({ 'torch': true, }); - when(videoTracks.first.getCapabilities).thenReturn({ + when(videoTracks.first.getCapabilities).thenReturn({ 'torch': true, }); - final camera = Camera( + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, )..window = window; @@ -658,12 +680,12 @@ void main() { throwsA( isA() .having( - (e) => e.cameraId, + (CameraWebException e) => e.cameraId, 'cameraId', textureId, ) .having( - (e) => e.code, + (CameraWebException e) => e.code, 'code', CameraErrorCode.notStarted, ), @@ -678,13 +700,13 @@ void main() { testWidgets( 'returns maximum ' 'from CameraService.getZoomLevelCapabilityForCamera', - (tester) async { - final camera = Camera( + (WidgetTester tester) async { + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, ); - final zoomLevelCapability = ZoomLevelCapability( + final ZoomLevelCapability zoomLevelCapability = ZoomLevelCapability( minimum: 50.0, maximum: 100.0, videoTrack: MockMediaStreamTrack(), @@ -693,7 +715,7 @@ void main() { when(() => cameraService.getZoomLevelCapabilityForCamera(camera)) .thenReturn(zoomLevelCapability); - final maximumZoomLevel = camera.getMaxZoomLevel(); + final double maximumZoomLevel = camera.getMaxZoomLevel(); verify(() => cameraService.getZoomLevelCapabilityForCamera(camera)) .called(1); @@ -709,13 +731,13 @@ void main() { testWidgets( 'returns minimum ' 'from CameraService.getZoomLevelCapabilityForCamera', - (tester) async { - final camera = Camera( + (WidgetTester tester) async { + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, ); - final zoomLevelCapability = ZoomLevelCapability( + final ZoomLevelCapability zoomLevelCapability = ZoomLevelCapability( minimum: 50.0, maximum: 100.0, videoTrack: MockMediaStreamTrack(), @@ -724,7 +746,7 @@ void main() { when(() => cameraService.getZoomLevelCapabilityForCamera(camera)) .thenReturn(zoomLevelCapability); - final minimumZoomLevel = camera.getMinZoomLevel(); + final double minimumZoomLevel = camera.getMinZoomLevel(); verify(() => cameraService.getZoomLevelCapabilityForCamera(camera)) .called(1); @@ -740,15 +762,15 @@ void main() { testWidgets( 'applies zoom on the video track ' 'from CameraService.getZoomLevelCapabilityForCamera', - (tester) async { - final camera = Camera( + (WidgetTester tester) async { + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, ); - final videoTrack = MockMediaStreamTrack(); + final MockMediaStreamTrack videoTrack = MockMediaStreamTrack(); - final zoomLevelCapability = ZoomLevelCapability( + final ZoomLevelCapability zoomLevelCapability = ZoomLevelCapability( minimum: 50.0, maximum: 100.0, videoTrack: videoTrack, @@ -760,14 +782,14 @@ void main() { when(() => cameraService.getZoomLevelCapabilityForCamera(camera)) .thenReturn(zoomLevelCapability); - const zoom = 75.0; + const double zoom = 75.0; camera.setZoomLevel(zoom); verify( - () => videoTrack.applyConstraints({ - "advanced": [ - { + () => videoTrack.applyConstraints({ + 'advanced': [ + { ZoomLevelCapability.constraintName: zoom, } ] @@ -778,13 +800,14 @@ void main() { group('throws a CameraWebException', () { testWidgets( 'with zoomLevelInvalid error ' - 'when the provided zoom level is below minimum', (tester) async { - final camera = Camera( + 'when the provided zoom level is below minimum', + (WidgetTester tester) async { + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, ); - final zoomLevelCapability = ZoomLevelCapability( + final ZoomLevelCapability zoomLevelCapability = ZoomLevelCapability( minimum: 50.0, maximum: 100.0, videoTrack: MockMediaStreamTrack(), @@ -798,12 +821,12 @@ void main() { throwsA( isA() .having( - (e) => e.cameraId, + (CameraWebException e) => e.cameraId, 'cameraId', textureId, ) .having( - (e) => e.code, + (CameraWebException e) => e.code, 'code', CameraErrorCode.zoomLevelInvalid, ), @@ -812,13 +835,14 @@ void main() { testWidgets( 'with zoomLevelInvalid error ' - 'when the provided zoom level is below minimum', (tester) async { - final camera = Camera( + 'when the provided zoom level is below minimum', + (WidgetTester tester) async { + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, ); - final zoomLevelCapability = ZoomLevelCapability( + final ZoomLevelCapability zoomLevelCapability = ZoomLevelCapability( minimum: 50.0, maximum: 100.0, videoTrack: MockMediaStreamTrack(), @@ -832,12 +856,12 @@ void main() { throwsA( isA() .having( - (e) => e.cameraId, + (CameraWebException e) => e.cameraId, 'cameraId', textureId, ) .having( - (e) => e.code, + (CameraWebException e) => e.code, 'code', CameraErrorCode.zoomLevelInvalid, ), @@ -851,25 +875,26 @@ void main() { group('getLensDirection', () { testWidgets( 'returns a lens direction ' - 'based on the first video track settings', (tester) async { - final videoElement = MockVideoElement(); + 'based on the first video track settings', + (WidgetTester tester) async { + final MockVideoElement videoElement = MockVideoElement(); - final camera = Camera( + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, )..videoElement = videoElement; - final firstVideoTrack = MockMediaStreamTrack(); + final MockMediaStreamTrack firstVideoTrack = MockMediaStreamTrack(); when(() => videoElement.srcObject).thenReturn( - FakeMediaStream([ + FakeMediaStream([ firstVideoTrack, MockMediaStreamTrack(), ]), ); when(firstVideoTrack.getSettings) - .thenReturn({'facingMode': 'environment'}); + .thenReturn({'facingMode': 'environment'}); when(() => cameraService.mapFacingModeToLensDirection('environment')) .thenReturn(CameraLensDirection.external); @@ -883,24 +908,24 @@ void main() { testWidgets( 'returns null ' 'if the first video track is missing the facing mode', - (tester) async { - final videoElement = MockVideoElement(); + (WidgetTester tester) async { + final MockVideoElement videoElement = MockVideoElement(); - final camera = Camera( + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, )..videoElement = videoElement; - final firstVideoTrack = MockMediaStreamTrack(); + final MockMediaStreamTrack firstVideoTrack = MockMediaStreamTrack(); when(() => videoElement.srcObject).thenReturn( - FakeMediaStream([ + FakeMediaStream([ firstVideoTrack, MockMediaStreamTrack(), ]), ); - when(firstVideoTrack.getSettings).thenReturn({}); + when(firstVideoTrack.getSettings).thenReturn({}); expect( camera.getLensDirection(), @@ -910,12 +935,12 @@ void main() { testWidgets( 'returns null ' - 'if the camera is missing video tracks', (tester) async { + 'if the camera is missing video tracks', (WidgetTester tester) async { // Create a video stream with no video tracks. - final videoElement = VideoElement(); + final VideoElement videoElement = VideoElement(); mediaStream = videoElement.captureStream(); - final camera = Camera( + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, ); @@ -930,8 +955,8 @@ void main() { }); group('getViewType', () { - testWidgets('returns a correct view type', (tester) async { - final camera = Camera( + testWidgets('returns a correct view type', (WidgetTester tester) async { + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, ); @@ -946,7 +971,7 @@ void main() { }); group('video recording', () { - const supportedVideoType = 'video/webm'; + const String supportedVideoType = 'video/webm'; late MediaRecorder mediaRecorder; @@ -956,14 +981,14 @@ void main() { mediaRecorder = MockMediaRecorder(); when(() => mediaRecorder.onError) - .thenAnswer((_) => const Stream.empty()); + .thenAnswer((_) => const Stream.empty()); }); group('startVideoRecording', () { testWidgets( 'creates a media recorder ' - 'with appropriate options', (tester) async { - final camera = Camera( + 'with appropriate options', (WidgetTester tester) async { + final Camera camera = Camera( textureId: 1, cameraService: cameraService, )..isVideoTypeSupported = isVideoTypeSupported; @@ -990,8 +1015,8 @@ void main() { }); testWidgets('listens to the media recorder data events', - (tester) async { - final camera = Camera( + (WidgetTester tester) async { + final Camera camera = Camera( textureId: 1, cameraService: cameraService, ) @@ -1009,8 +1034,8 @@ void main() { }); testWidgets('listens to the media recorder stop events', - (tester) async { - final camera = Camera( + (WidgetTester tester) async { + final Camera camera = Camera( textureId: 1, cameraService: cameraService, ) @@ -1027,8 +1052,8 @@ void main() { ).called(1); }); - testWidgets('starts a video recording', (tester) async { - final camera = Camera( + testWidgets('starts a video recording', (WidgetTester tester) async { + final Camera camera = Camera( textureId: 1, cameraService: cameraService, ) @@ -1045,10 +1070,10 @@ void main() { testWidgets( 'starts a video recording ' - 'with maxVideoDuration', (tester) async { - const maxVideoDuration = Duration(hours: 1); + 'with maxVideoDuration', (WidgetTester tester) async { + const Duration maxVideoDuration = Duration(hours: 1); - final camera = Camera( + final Camera camera = Camera( textureId: 1, cameraService: cameraService, ) @@ -1068,8 +1093,8 @@ void main() { testWidgets( 'with notSupported error ' 'when maxVideoDuration is 0 milliseconds or less', - (tester) async { - final camera = Camera( + (WidgetTester tester) async { + final Camera camera = Camera( textureId: 1, cameraService: cameraService, ) @@ -1084,12 +1109,12 @@ void main() { throwsA( isA() .having( - (e) => e.cameraId, + (CameraWebException e) => e.cameraId, 'cameraId', textureId, ) .having( - (e) => e.code, + (CameraWebException e) => e.code, 'code', CameraErrorCode.notSupported, ), @@ -1099,11 +1124,11 @@ void main() { testWidgets( 'with notSupported error ' - 'when no video types are supported', (tester) async { - final camera = Camera( + 'when no video types are supported', (WidgetTester tester) async { + final Camera camera = Camera( textureId: 1, cameraService: cameraService, - )..isVideoTypeSupported = (type) => false; + )..isVideoTypeSupported = (String type) => false; await camera.initialize(); await camera.play(); @@ -1113,12 +1138,12 @@ void main() { throwsA( isA() .having( - (e) => e.cameraId, + (CameraWebException e) => e.cameraId, 'cameraId', textureId, ) .having( - (e) => e.code, + (CameraWebException e) => e.code, 'code', CameraErrorCode.notSupported, ), @@ -1129,8 +1154,8 @@ void main() { }); group('pauseVideoRecording', () { - testWidgets('pauses a video recording', (tester) async { - final camera = Camera( + testWidgets('pauses a video recording', (WidgetTester tester) async { + final Camera camera = Camera( textureId: 1, cameraService: cameraService, )..mediaRecorder = mediaRecorder; @@ -1143,8 +1168,9 @@ void main() { testWidgets( 'throws a CameraWebException ' 'with videoRecordingNotStarted error ' - 'if the video recording was not started', (tester) async { - final camera = Camera( + 'if the video recording was not started', + (WidgetTester tester) async { + final Camera camera = Camera( textureId: 1, cameraService: cameraService, ); @@ -1154,12 +1180,12 @@ void main() { throwsA( isA() .having( - (e) => e.cameraId, + (CameraWebException e) => e.cameraId, 'cameraId', textureId, ) .having( - (e) => e.code, + (CameraWebException e) => e.code, 'code', CameraErrorCode.videoRecordingNotStarted, ), @@ -1169,8 +1195,8 @@ void main() { }); group('resumeVideoRecording', () { - testWidgets('resumes a video recording', (tester) async { - final camera = Camera( + testWidgets('resumes a video recording', (WidgetTester tester) async { + final Camera camera = Camera( textureId: 1, cameraService: cameraService, )..mediaRecorder = mediaRecorder; @@ -1183,8 +1209,9 @@ void main() { testWidgets( 'throws a CameraWebException ' 'with videoRecordingNotStarted error ' - 'if the video recording was not started', (tester) async { - final camera = Camera( + 'if the video recording was not started', + (WidgetTester tester) async { + final Camera camera = Camera( textureId: 1, cameraService: cameraService, ); @@ -1194,12 +1221,12 @@ void main() { throwsA( isA() .having( - (e) => e.cameraId, + (CameraWebException e) => e.cameraId, 'cameraId', textureId, ) .having( - (e) => e.code, + (CameraWebException e) => e.code, 'code', CameraErrorCode.videoRecordingNotStarted, ), @@ -1212,8 +1239,8 @@ void main() { testWidgets( 'stops a video recording and ' 'returns the captured file ' - 'based on all video data parts', (tester) async { - final camera = Camera( + 'based on all video data parts', (WidgetTester tester) async { + final Camera camera = Camera( textureId: 1, cameraService: cameraService, ) @@ -1228,31 +1255,33 @@ void main() { when( () => mediaRecorder.addEventListener('dataavailable', any()), - ).thenAnswer((invocation) { - videoDataAvailableListener = invocation.positionalArguments[1]; + ).thenAnswer((Invocation invocation) { + videoDataAvailableListener = + invocation.positionalArguments[1] as void Function(Event); }); when( () => mediaRecorder.addEventListener('stop', any()), - ).thenAnswer((invocation) { - videoRecordingStoppedListener = invocation.positionalArguments[1]; + ).thenAnswer((Invocation invocation) { + videoRecordingStoppedListener = + invocation.positionalArguments[1] as void Function(Event); }); Blob? finalVideo; List? videoParts; - camera.blobBuilder = (blobs, videoType) { - videoParts = [...blobs]; + camera.blobBuilder = (List blobs, String videoType) { + videoParts = [...blobs]; finalVideo = Blob(blobs, videoType); return finalVideo!; }; await camera.startVideoRecording(); - final videoFileFuture = camera.stopVideoRecording(); + final Future videoFileFuture = camera.stopVideoRecording(); - final capturedVideoPartOne = Blob([]); - final capturedVideoPartTwo = Blob([]); + final Blob capturedVideoPartOne = Blob([]); + final Blob capturedVideoPartTwo = Blob([]); - final capturedVideoParts = [ + final List capturedVideoParts = [ capturedVideoPartOne, capturedVideoPartTwo, ]; @@ -1263,7 +1292,7 @@ void main() { videoRecordingStoppedListener.call(Event('stop')); - final videoFile = await videoFileFuture; + final XFile videoFile = await videoFileFuture; verify(mediaRecorder.stop).called(1); @@ -1291,8 +1320,9 @@ void main() { testWidgets( 'throws a CameraWebException ' 'with videoRecordingNotStarted error ' - 'if the video recording was not started', (tester) async { - final camera = Camera( + 'if the video recording was not started', + (WidgetTester tester) async { + final Camera camera = Camera( textureId: 1, cameraService: cameraService, ); @@ -1302,12 +1332,12 @@ void main() { throwsA( isA() .having( - (e) => e.cameraId, + (CameraWebException e) => e.cameraId, 'cameraId', textureId, ) .having( - (e) => e.code, + (CameraWebException e) => e.code, 'code', CameraErrorCode.videoRecordingNotStarted, ), @@ -1322,18 +1352,20 @@ void main() { setUp(() { when( () => mediaRecorder.addEventListener('dataavailable', any()), - ).thenAnswer((invocation) { - videoDataAvailableListener = invocation.positionalArguments[1]; + ).thenAnswer((Invocation invocation) { + videoDataAvailableListener = + invocation.positionalArguments[1] as void Function(Event); }); }); testWidgets( 'stops a video recording ' 'if maxVideoDuration is given and ' - 'the recording was not stopped manually', (tester) async { - const maxVideoDuration = Duration(hours: 1); + 'the recording was not stopped manually', + (WidgetTester tester) async { + const Duration maxVideoDuration = Duration(hours: 1); - final camera = Camera( + final Camera camera = Camera( textureId: 1, cameraService: cameraService, ) @@ -1346,9 +1378,9 @@ void main() { when(() => mediaRecorder.state).thenReturn('recording'); - videoDataAvailableListener.call(FakeBlobEvent(Blob([]))); + videoDataAvailableListener.call(FakeBlobEvent(Blob([]))); - await Future.microtask(() {}); + await Future.microtask(() {}); verify(mediaRecorder.stop).called(1); }); @@ -1360,14 +1392,15 @@ void main() { setUp(() { when( () => mediaRecorder.addEventListener('stop', any()), - ).thenAnswer((invocation) { - videoRecordingStoppedListener = invocation.positionalArguments[1]; + ).thenAnswer((Invocation invocation) { + videoRecordingStoppedListener = + invocation.positionalArguments[1] as void Function(Event); }); }); testWidgets('stops listening to the media recorder data events', - (tester) async { - final camera = Camera( + (WidgetTester tester) async { + final Camera camera = Camera( textureId: 1, cameraService: cameraService, ) @@ -1381,7 +1414,7 @@ void main() { videoRecordingStoppedListener.call(Event('stop')); - await Future.microtask(() {}); + await Future.microtask(() {}); verify( () => mediaRecorder.removeEventListener('dataavailable', any()), @@ -1389,8 +1422,8 @@ void main() { }); testWidgets('stops listening to the media recorder stop events', - (tester) async { - final camera = Camera( + (WidgetTester tester) async { + final Camera camera = Camera( textureId: 1, cameraService: cameraService, ) @@ -1404,7 +1437,7 @@ void main() { videoRecordingStoppedListener.call(Event('stop')); - await Future.microtask(() {}); + await Future.microtask(() {}); verify( () => mediaRecorder.removeEventListener('stop', any()), @@ -1412,10 +1445,11 @@ void main() { }); testWidgets('stops listening to the media recorder errors', - (tester) async { - final onErrorStreamController = StreamController(); + (WidgetTester tester) async { + final StreamController onErrorStreamController = + StreamController(); - final camera = Camera( + final Camera camera = Camera( textureId: 1, cameraService: cameraService, ) @@ -1432,7 +1466,7 @@ void main() { videoRecordingStoppedListener.call(Event('stop')); - await Future.microtask(() {}); + await Future.microtask(() {}); expect( onErrorStreamController.hasListener, @@ -1443,8 +1477,9 @@ void main() { }); group('dispose', () { - testWidgets('resets the video element\'s source', (tester) async { - final camera = Camera( + testWidgets('resets the video element\'s source', + (WidgetTester tester) async { + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, ); @@ -1455,8 +1490,8 @@ void main() { expect(camera.videoElement.srcObject, isNull); }); - testWidgets('closes the onEnded stream', (tester) async { - final camera = Camera( + testWidgets('closes the onEnded stream', (WidgetTester tester) async { + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, ); @@ -1470,8 +1505,9 @@ void main() { ); }); - testWidgets('closes the onVideoRecordedEvent stream', (tester) async { - final camera = Camera( + testWidgets('closes the onVideoRecordedEvent stream', + (WidgetTester tester) async { + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, ); @@ -1485,8 +1521,9 @@ void main() { ); }); - testWidgets('closes the onVideoRecordingError stream', (tester) async { - final camera = Camera( + testWidgets('closes the onVideoRecordingError stream', + (WidgetTester tester) async { + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, ); @@ -1505,20 +1542,20 @@ void main() { group('onVideoRecordedEvent', () { testWidgets( 'emits a VideoRecordedEvent ' - 'when a video recording is created', (tester) async { - const maxVideoDuration = Duration(hours: 1); - const supportedVideoType = 'video/webm'; + 'when a video recording is created', (WidgetTester tester) async { + const Duration maxVideoDuration = Duration(hours: 1); + const String supportedVideoType = 'video/webm'; - final mediaRecorder = MockMediaRecorder(); + final MockMediaRecorder mediaRecorder = MockMediaRecorder(); when(() => mediaRecorder.onError) - .thenAnswer((_) => const Stream.empty()); + .thenAnswer((_) => const Stream.empty()); - final camera = Camera( + final Camera camera = Camera( textureId: 1, cameraService: cameraService, ) ..mediaRecorder = mediaRecorder - ..isVideoTypeSupported = (type) => type == 'video/webm'; + ..isVideoTypeSupported = (String type) => type == 'video/webm'; await camera.initialize(); await camera.play(); @@ -1528,27 +1565,30 @@ void main() { when( () => mediaRecorder.addEventListener('dataavailable', any()), - ).thenAnswer((invocation) { - videoDataAvailableListener = invocation.positionalArguments[1]; + ).thenAnswer((Invocation invocation) { + videoDataAvailableListener = + invocation.positionalArguments[1] as void Function(Event); }); when( () => mediaRecorder.addEventListener('stop', any()), - ).thenAnswer((invocation) { - videoRecordingStoppedListener = invocation.positionalArguments[1]; + ).thenAnswer((Invocation invocation) { + videoRecordingStoppedListener = + invocation.positionalArguments[1] as void Function(Event); }); - final streamQueue = StreamQueue(camera.onVideoRecordedEvent); + final StreamQueue streamQueue = + StreamQueue(camera.onVideoRecordedEvent); await camera.startVideoRecording(maxVideoDuration: maxVideoDuration); Blob? finalVideo; - camera.blobBuilder = (blobs, videoType) { + camera.blobBuilder = (List blobs, String videoType) { finalVideo = Blob(blobs, videoType); return finalVideo!; }; - videoDataAvailableListener.call(FakeBlobEvent(Blob([]))); + videoDataAvailableListener.call(FakeBlobEvent(Blob([]))); videoRecordingStoppedListener.call(Event('stop')); expect( @@ -1556,27 +1596,27 @@ void main() { equals( isA() .having( - (e) => e.cameraId, + (VideoRecordedEvent e) => e.cameraId, 'cameraId', textureId, ) .having( - (e) => e.file, + (VideoRecordedEvent e) => e.file, 'file', isA() .having( - (f) => f.mimeType, + (XFile f) => f.mimeType, 'mimeType', supportedVideoType, ) .having( - (f) => f.name, + (XFile f) => f.name, 'name', finalVideo.hashCode.toString(), ), ) .having( - (e) => e.maxVideoDuration, + (VideoRecordedEvent e) => e.maxVideoDuration, 'maxVideoDuration', maxVideoDuration, ), @@ -1590,18 +1630,20 @@ void main() { group('onEnded', () { testWidgets( 'emits the default video track ' - 'when it emits an ended event', (tester) async { - final camera = Camera( + 'when it emits an ended event', (WidgetTester tester) async { + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, ); - final streamQueue = StreamQueue(camera.onEnded); + final StreamQueue streamQueue = + StreamQueue(camera.onEnded); await camera.initialize(); - final videoTracks = camera.stream!.getVideoTracks(); - final defaultVideoTrack = videoTracks.first; + final List videoTracks = + camera.stream!.getVideoTracks(); + final MediaStreamTrack defaultVideoTrack = videoTracks.first; defaultVideoTrack.dispatchEvent(Event('ended')); @@ -1615,18 +1657,20 @@ void main() { testWidgets( 'emits the default video track ' - 'when the camera is stopped', (tester) async { - final camera = Camera( + 'when the camera is stopped', (WidgetTester tester) async { + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, ); - final streamQueue = StreamQueue(camera.onEnded); + final StreamQueue streamQueue = + StreamQueue(camera.onEnded); await camera.initialize(); - final videoTracks = camera.stream!.getVideoTracks(); - final defaultVideoTrack = videoTracks.first; + final List videoTracks = + camera.stream!.getVideoTracks(); + final MediaStreamTrack defaultVideoTrack = videoTracks.first; camera.stop(); @@ -1643,11 +1687,12 @@ void main() { testWidgets( 'emits an ErrorEvent ' 'when the media recorder fails ' - 'when recording a video', (tester) async { - final mediaRecorder = MockMediaRecorder(); - final errorController = StreamController(); + 'when recording a video', (WidgetTester tester) async { + final MockMediaRecorder mediaRecorder = MockMediaRecorder(); + final StreamController errorController = + StreamController(); - final camera = Camera( + final Camera camera = Camera( textureId: textureId, cameraService: cameraService, )..mediaRecorder = mediaRecorder; @@ -1655,14 +1700,15 @@ void main() { when(() => mediaRecorder.onError) .thenAnswer((_) => errorController.stream); - final streamQueue = StreamQueue(camera.onVideoRecordingError); + final StreamQueue streamQueue = + StreamQueue(camera.onVideoRecordingError); await camera.initialize(); await camera.play(); await camera.startVideoRecording(); - final errorEvent = ErrorEvent('type'); + final ErrorEvent errorEvent = ErrorEvent('type'); errorController.add(errorEvent); expect( diff --git a/packages/camera/camera_web/example/integration_test/camera_web_exception_test.dart b/packages/camera/camera_web/example/integration_test/camera_web_exception_test.dart index 6f8531b6f4af..fcb54da1aed5 100644 --- a/packages/camera/camera_web/example/integration_test/camera_web_exception_test.dart +++ b/packages/camera/camera_web/example/integration_test/camera_web_exception_test.dart @@ -10,24 +10,27 @@ void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('CameraWebException', () { - testWidgets('sets all properties', (tester) async { - final cameraId = 1; - final code = CameraErrorCode.notFound; - final description = 'The camera is not found.'; + testWidgets('sets all properties', (WidgetTester tester) async { + const int cameraId = 1; + const CameraErrorCode code = CameraErrorCode.notFound; + const String description = 'The camera is not found.'; - final exception = CameraWebException(cameraId, code, description); + final CameraWebException exception = + CameraWebException(cameraId, code, description); expect(exception.cameraId, equals(cameraId)); expect(exception.code, equals(code)); expect(exception.description, equals(description)); }); - testWidgets('toString includes all properties', (tester) async { - final cameraId = 2; - final code = CameraErrorCode.notReadable; - final description = 'The camera is not readable.'; + testWidgets('toString includes all properties', + (WidgetTester tester) async { + const int cameraId = 2; + const CameraErrorCode code = CameraErrorCode.notReadable; + const String description = 'The camera is not readable.'; - final exception = CameraWebException(cameraId, code, description); + final CameraWebException exception = + CameraWebException(cameraId, code, description); expect( exception.toString(), diff --git a/packages/camera/camera_web/example/integration_test/camera_web_test.dart b/packages/camera/camera_web/example/integration_test/camera_web_test.dart index 0943d7a94ea9..9f21eb43fb34 100644 --- a/packages/camera/camera_web/example/integration_test/camera_web_test.dart +++ b/packages/camera/camera_web/example/integration_test/camera_web_test.dart @@ -24,7 +24,7 @@ void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('CameraPlugin', () { - const cameraId = 0; + const int cameraId = 0; late Window window; late Navigator navigator; @@ -42,7 +42,7 @@ void main() { navigator = MockNavigator(); mediaDevices = MockMediaDevices(); - videoElement = getVideoElementWithBlankStream(Size(10, 10)); + videoElement = getVideoElementWithBlankStream(const Size(10, 10)); when(() => window.navigator).thenReturn(navigator); when(() => navigator.mediaDevices).thenReturn(mediaDevices); @@ -81,7 +81,8 @@ void main() { registerFallbackValue(FlashMode.off); }); - testWidgets('CameraPlugin is the live instance', (tester) async { + testWidgets('CameraPlugin is the live instance', + (WidgetTester tester) async { expect(CameraPlatform.instance, isA()); }); @@ -94,16 +95,18 @@ void main() { ).thenReturn(null); when(mediaDevices.enumerateDevices).thenAnswer( - (_) async => [], + (_) async => [], ); }); - testWidgets('requests video and audio permissions', (tester) async { - final _ = await CameraPlatform.instance.availableCameras(); + testWidgets('requests video and audio permissions', + (WidgetTester tester) async { + final List _ = + await CameraPlatform.instance.availableCameras(); verify( () => cameraService.getMediaStreamForOptions( - CameraOptions( + const CameraOptions( audio: AudioConstraints(enabled: true), ), ), @@ -112,45 +115,48 @@ void main() { testWidgets( 'releases the camera stream ' - 'used to request video and audio permissions', (tester) async { - final videoTrack = MockMediaStreamTrack(); + 'used to request video and audio permissions', + (WidgetTester tester) async { + final MockMediaStreamTrack videoTrack = MockMediaStreamTrack(); - var videoTrackStopped = false; - when(videoTrack.stop).thenAnswer((_) { + bool videoTrackStopped = false; + when(videoTrack.stop).thenAnswer((Invocation _) { videoTrackStopped = true; }); when( () => cameraService.getMediaStreamForOptions( - CameraOptions( + const CameraOptions( audio: AudioConstraints(enabled: true), ), ), ).thenAnswer( - (_) => Future.value( - FakeMediaStream([videoTrack]), + (_) => Future.value( + FakeMediaStream([videoTrack]), ), ); - final _ = await CameraPlatform.instance.availableCameras(); + final List _ = + await CameraPlatform.instance.availableCameras(); expect(videoTrackStopped, isTrue); }); testWidgets( 'gets a video stream ' - 'for a video input device', (tester) async { - final videoDevice = FakeMediaDeviceInfo( + 'for a video input device', (WidgetTester tester) async { + final FakeMediaDeviceInfo videoDevice = FakeMediaDeviceInfo( '1', 'Camera 1', MediaDeviceKind.videoInput, ); when(mediaDevices.enumerateDevices).thenAnswer( - (_) => Future.value([videoDevice]), + (_) => Future>.value([videoDevice]), ); - final _ = await CameraPlatform.instance.availableCameras(); + final List _ = + await CameraPlatform.instance.availableCameras(); verify( () => cameraService.getMediaStreamForOptions( @@ -166,18 +172,19 @@ void main() { testWidgets( 'does not get a video stream ' 'for the video input device ' - 'with an empty device id', (tester) async { - final videoDevice = FakeMediaDeviceInfo( + 'with an empty device id', (WidgetTester tester) async { + final FakeMediaDeviceInfo videoDevice = FakeMediaDeviceInfo( '', 'Camera 1', MediaDeviceKind.videoInput, ); when(mediaDevices.enumerateDevices).thenAnswer( - (_) => Future.value([videoDevice]), + (_) => Future>.value([videoDevice]), ); - final _ = await CameraPlatform.instance.availableCameras(); + final List _ = + await CameraPlatform.instance.availableCameras(); verifyNever( () => cameraService.getMediaStreamForOptions( @@ -193,15 +200,15 @@ void main() { testWidgets( 'gets the facing mode ' 'from the first available video track ' - 'of the video input device', (tester) async { - final videoDevice = FakeMediaDeviceInfo( + 'of the video input device', (WidgetTester tester) async { + final FakeMediaDeviceInfo videoDevice = FakeMediaDeviceInfo( '1', 'Camera 1', MediaDeviceKind.videoInput, ); - final videoStream = - FakeMediaStream([MockMediaStreamTrack(), MockMediaStreamTrack()]); + final FakeMediaStream videoStream = FakeMediaStream( + [MockMediaStreamTrack(), MockMediaStreamTrack()]); when( () => cameraService.getMediaStreamForOptions( @@ -209,13 +216,14 @@ void main() { video: VideoConstraints(deviceId: videoDevice.deviceId), ), ), - ).thenAnswer((_) => Future.value(videoStream)); + ).thenAnswer((Invocation _) => Future.value(videoStream)); when(mediaDevices.enumerateDevices).thenAnswer( - (_) => Future.value([videoDevice]), + (_) => Future>.value([videoDevice]), ); - final _ = await CameraPlatform.instance.availableCameras(); + final List _ = + await CameraPlatform.instance.availableCameras(); verify( () => cameraService.getFacingModeForVideoTrack( @@ -227,30 +235,31 @@ void main() { testWidgets( 'returns appropriate camera descriptions ' 'for multiple video devices ' - 'based on video streams', (tester) async { - final firstVideoDevice = FakeMediaDeviceInfo( + 'based on video streams', (WidgetTester tester) async { + final FakeMediaDeviceInfo firstVideoDevice = FakeMediaDeviceInfo( '1', 'Camera 1', MediaDeviceKind.videoInput, ); - final secondVideoDevice = FakeMediaDeviceInfo( + final FakeMediaDeviceInfo secondVideoDevice = FakeMediaDeviceInfo( '4', 'Camera 4', MediaDeviceKind.videoInput, ); // Create a video stream for the first video device. - final firstVideoStream = - FakeMediaStream([MockMediaStreamTrack(), MockMediaStreamTrack()]); + final FakeMediaStream firstVideoStream = FakeMediaStream( + [MockMediaStreamTrack(), MockMediaStreamTrack()]); // Create a video stream for the second video device. - final secondVideoStream = FakeMediaStream([MockMediaStreamTrack()]); + final FakeMediaStream secondVideoStream = + FakeMediaStream([MockMediaStreamTrack()]); // Mock media devices to return two video input devices // and two audio devices. when(mediaDevices.enumerateDevices).thenAnswer( - (_) => Future.value([ + (_) => Future>.value([ firstVideoDevice, FakeMediaDeviceInfo( '2', @@ -274,7 +283,8 @@ void main() { video: VideoConstraints(deviceId: firstVideoDevice.deviceId), ), ), - ).thenAnswer((_) => Future.value(firstVideoStream)); + ).thenAnswer( + (Invocation _) => Future.value(firstVideoStream)); // Mock camera service to return the second video stream // for the second video device. @@ -284,7 +294,8 @@ void main() { video: VideoConstraints(deviceId: secondVideoDevice.deviceId), ), ), - ).thenAnswer((_) => Future.value(secondVideoStream)); + ).thenAnswer( + (Invocation _) => Future.value(secondVideoStream)); // Mock camera service to return a user facing mode // for the first video stream. @@ -308,12 +319,13 @@ void main() { when(() => cameraService.mapFacingModeToLensDirection('environment')) .thenReturn(CameraLensDirection.back); - final cameras = await CameraPlatform.instance.availableCameras(); + final List cameras = + await CameraPlatform.instance.availableCameras(); // Expect two cameras and ignore two audio devices. expect( cameras, - equals([ + equals([ CameraDescription( name: firstVideoDevice.label!, lensDirection: CameraLensDirection.front, @@ -330,18 +342,18 @@ void main() { testWidgets( 'sets camera metadata ' - 'for the camera description', (tester) async { - final videoDevice = FakeMediaDeviceInfo( + 'for the camera description', (WidgetTester tester) async { + final FakeMediaDeviceInfo videoDevice = FakeMediaDeviceInfo( '1', 'Camera 1', MediaDeviceKind.videoInput, ); - final videoStream = - FakeMediaStream([MockMediaStreamTrack(), MockMediaStreamTrack()]); + final FakeMediaStream videoStream = FakeMediaStream( + [MockMediaStreamTrack(), MockMediaStreamTrack()]); when(mediaDevices.enumerateDevices).thenAnswer( - (_) => Future.value([videoDevice]), + (_) => Future>.value([videoDevice]), ); when( @@ -350,7 +362,7 @@ void main() { video: VideoConstraints(deviceId: videoDevice.deviceId), ), ), - ).thenAnswer((_) => Future.value(videoStream)); + ).thenAnswer((Invocation _) => Future.value(videoStream)); when( () => cameraService.getFacingModeForVideoTrack( @@ -361,11 +373,12 @@ void main() { when(() => cameraService.mapFacingModeToLensDirection('left')) .thenReturn(CameraLensDirection.external); - final camera = (await CameraPlatform.instance.availableCameras()).first; + final CameraDescription camera = + (await CameraPlatform.instance.availableCameras()).first; expect( (CameraPlatform.instance as CameraPlugin).camerasMetadata, - equals({ + equals({ camera: CameraMetadata( deviceId: videoDevice.deviceId!, facingMode: 'left', @@ -376,18 +389,18 @@ void main() { testWidgets( 'releases the video stream ' - 'of a video input device', (tester) async { - final videoDevice = FakeMediaDeviceInfo( + 'of a video input device', (WidgetTester tester) async { + final FakeMediaDeviceInfo videoDevice = FakeMediaDeviceInfo( '1', 'Camera 1', MediaDeviceKind.videoInput, ); - final videoStream = - FakeMediaStream([MockMediaStreamTrack(), MockMediaStreamTrack()]); + final FakeMediaStream videoStream = FakeMediaStream( + [MockMediaStreamTrack(), MockMediaStreamTrack()]); when(mediaDevices.enumerateDevices).thenAnswer( - (_) => Future.value([videoDevice]), + (_) => Future>.value([videoDevice]), ); when( @@ -396,11 +409,13 @@ void main() { video: VideoConstraints(deviceId: videoDevice.deviceId), ), ), - ).thenAnswer((_) => Future.value(videoStream)); + ).thenAnswer((Invocation _) => Future.value(videoStream)); - final _ = await CameraPlatform.instance.availableCameras(); + final List _ = + await CameraPlatform.instance.availableCameras(); - for (var videoTrack in videoStream.getVideoTracks()) { + for (final MediaStreamTrack videoTrack + in videoStream.getVideoTracks()) { verify(videoTrack.stop).called(1); } }); @@ -408,14 +423,14 @@ void main() { group('throws CameraException', () { testWidgets( 'with notSupported error ' - 'when there are no media devices', (tester) async { + 'when there are no media devices', (WidgetTester tester) async { when(() => navigator.mediaDevices).thenReturn(null); expect( () => CameraPlatform.instance.availableCameras(), throwsA( isA().having( - (e) => e.code, + (CameraException e) => e.code, 'code', CameraErrorCode.notSupported.toString(), ), @@ -424,8 +439,9 @@ void main() { }); testWidgets('when MediaDevices.enumerateDevices throws DomException', - (tester) async { - final exception = FakeDomException(DomException.UNKNOWN); + (WidgetTester tester) async { + final FakeDomException exception = + FakeDomException(DomException.UNKNOWN); when(mediaDevices.enumerateDevices).thenThrow(exception); @@ -433,7 +449,7 @@ void main() { () => CameraPlatform.instance.availableCameras(), throwsA( isA().having( - (e) => e.code, + (CameraException e) => e.code, 'code', exception.name, ), @@ -443,8 +459,8 @@ void main() { testWidgets( 'when CameraService.getMediaStreamForOptions ' - 'throws CameraWebException', (tester) async { - final exception = CameraWebException( + 'throws CameraWebException', (WidgetTester tester) async { + final CameraWebException exception = CameraWebException( cameraId, CameraErrorCode.security, 'description', @@ -457,7 +473,7 @@ void main() { () => CameraPlatform.instance.availableCameras(), throwsA( isA().having( - (e) => e.code, + (CameraException e) => e.code, 'code', exception.code.toString(), ), @@ -467,8 +483,8 @@ void main() { testWidgets( 'when CameraService.getMediaStreamForOptions ' - 'throws PlatformException', (tester) async { - final exception = PlatformException( + 'throws PlatformException', (WidgetTester tester) async { + final PlatformException exception = PlatformException( code: CameraErrorCode.notSupported.toString(), message: 'message', ); @@ -480,7 +496,7 @@ void main() { () => CameraPlatform.instance.availableCameras(), throwsA( isA().having( - (e) => e.code, + (CameraException e) => e.code, 'code', exception.code.toString(), ), @@ -492,16 +508,16 @@ void main() { group('createCamera', () { group('creates a camera', () { - const ultraHighResolutionSize = Size(3840, 2160); - const maxResolutionSize = Size(3840, 2160); + const Size ultraHighResolutionSize = Size(3840, 2160); + const Size maxResolutionSize = Size(3840, 2160); - final cameraDescription = CameraDescription( + const CameraDescription cameraDescription = CameraDescription( name: 'name', lensDirection: CameraLensDirection.front, sensorOrientation: 0, ); - final cameraMetadata = CameraMetadata( + const CameraMetadata cameraMetadata = CameraMetadata( deviceId: 'deviceId', facingMode: 'user', ); @@ -516,13 +532,13 @@ void main() { ).thenReturn(CameraType.user); }); - testWidgets('with appropriate options', (tester) async { + testWidgets('with appropriate options', (WidgetTester tester) async { when( () => cameraService .mapResolutionPresetToSize(ResolutionPreset.ultraHigh), ).thenReturn(ultraHighResolutionSize); - final cameraId = await CameraPlatform.instance.createCamera( + final int cameraId = await CameraPlatform.instance.createCamera( cameraDescription, ResolutionPreset.ultraHigh, enableAudio: true, @@ -532,15 +548,15 @@ void main() { (CameraPlatform.instance as CameraPlugin).cameras[cameraId], isA() .having( - (camera) => camera.textureId, + (Camera camera) => camera.textureId, 'textureId', cameraId, ) .having( - (camera) => camera.options, + (Camera camera) => camera.options, 'options', CameraOptions( - audio: AudioConstraints(enabled: true), + audio: const AudioConstraints(enabled: true), video: VideoConstraints( facingMode: FacingModeConstraint(CameraType.user), width: VideoSizeConstraint( @@ -559,12 +575,12 @@ void main() { testWidgets( 'with a max resolution preset ' 'and enabled audio set to false ' - 'when no options are specified', (tester) async { + 'when no options are specified', (WidgetTester tester) async { when( () => cameraService.mapResolutionPresetToSize(ResolutionPreset.max), ).thenReturn(maxResolutionSize); - final cameraId = await CameraPlatform.instance.createCamera( + final int cameraId = await CameraPlatform.instance.createCamera( cameraDescription, null, ); @@ -572,10 +588,10 @@ void main() { expect( (CameraPlatform.instance as CameraPlugin).cameras[cameraId], isA().having( - (camera) => camera.options, + (Camera camera) => camera.options, 'options', CameraOptions( - audio: AudioConstraints(enabled: false), + audio: const AudioConstraints(enabled: false), video: VideoConstraints( facingMode: FacingModeConstraint(CameraType.user), width: VideoSizeConstraint( @@ -596,10 +612,10 @@ void main() { 'throws CameraException ' 'with missingMetadata error ' 'if there is no metadata ' - 'for the given camera description', (tester) async { + 'for the given camera description', (WidgetTester tester) async { expect( () => CameraPlatform.instance.createCamera( - CameraDescription( + const CameraDescription( name: 'name', lensDirection: CameraLensDirection.back, sensorOrientation: 0, @@ -608,7 +624,7 @@ void main() { ), throwsA( isA().having( - (e) => e.code, + (CameraException e) => e.code, 'code', CameraErrorCode.missingMetadata.toString(), ), @@ -632,21 +648,23 @@ void main() { abortStreamController = StreamController(); endedStreamController = StreamController(); - when(camera.getVideoSize).thenReturn(Size(10, 10)); - when(camera.initialize).thenAnswer((_) => Future.value()); - when(camera.play).thenAnswer((_) => Future.value()); + when(camera.getVideoSize).thenReturn(const Size(10, 10)); + when(camera.initialize) + .thenAnswer((Invocation _) => Future.value()); + when(camera.play).thenAnswer((Invocation _) => Future.value()); when(() => camera.videoElement).thenReturn(videoElement); - when(() => videoElement.onError) - .thenAnswer((_) => FakeElementStream(errorStreamController.stream)); - when(() => videoElement.onAbort) - .thenAnswer((_) => FakeElementStream(abortStreamController.stream)); + when(() => videoElement.onError).thenAnswer((Invocation _) => + FakeElementStream(errorStreamController.stream)); + when(() => videoElement.onAbort).thenAnswer((Invocation _) => + FakeElementStream(abortStreamController.stream)); when(() => camera.onEnded) - .thenAnswer((_) => endedStreamController.stream); + .thenAnswer((Invocation _) => endedStreamController.stream); }); - testWidgets('initializes and plays the camera', (tester) async { + testWidgets('initializes and plays the camera', + (WidgetTester tester) async { // Save the camera in the camera plugin. (CameraPlatform.instance as CameraPlugin).cameras[cameraId] = camera; @@ -657,7 +675,7 @@ void main() { }); testWidgets('starts listening to the camera video error and abort events', - (tester) async { + (WidgetTester tester) async { // Save the camera in the camera plugin. (CameraPlatform.instance as CameraPlugin).cameras[cameraId] = camera; @@ -671,7 +689,7 @@ void main() { }); testWidgets('starts listening to the camera ended events', - (tester) async { + (WidgetTester tester) async { // Save the camera in the camera plugin. (CameraPlatform.instance as CameraPlugin).cameras[cameraId] = camera; @@ -685,12 +703,12 @@ void main() { group('throws PlatformException', () { testWidgets( 'with notFound error ' - 'if the camera does not exist', (tester) async { + 'if the camera does not exist', (WidgetTester tester) async { expect( () => CameraPlatform.instance.initializeCamera(cameraId), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', CameraErrorCode.notFound.toString(), ), @@ -698,8 +716,9 @@ void main() { ); }); - testWidgets('when camera throws CameraWebException', (tester) async { - final exception = CameraWebException( + testWidgets('when camera throws CameraWebException', + (WidgetTester tester) async { + final CameraWebException exception = CameraWebException( cameraId, CameraErrorCode.permissionDenied, 'description', @@ -714,7 +733,7 @@ void main() { () => CameraPlatform.instance.initializeCamera(cameraId), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', exception.code.toString(), ), @@ -722,10 +741,13 @@ void main() { ); }); - testWidgets('when camera throws DomException', (tester) async { - final exception = FakeDomException(DomException.NOT_ALLOWED); + testWidgets('when camera throws DomException', + (WidgetTester tester) async { + final FakeDomException exception = + FakeDomException(DomException.NOT_ALLOWED); - when(camera.initialize).thenAnswer((_) => Future.value()); + when(camera.initialize) + .thenAnswer((Invocation _) => Future.value()); when(camera.play).thenThrow(exception); // Save the camera in the camera plugin. @@ -735,7 +757,7 @@ void main() { () => CameraPlatform.instance.initializeCamera(cameraId), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', exception.name.toString(), ), @@ -754,7 +776,7 @@ void main() { testWidgets( 'requests full-screen mode ' - 'on documentElement', (tester) async { + 'on documentElement', (WidgetTester tester) async { await CameraPlatform.instance.lockCaptureOrientation( cameraId, DeviceOrientation.portraitUp, @@ -765,7 +787,7 @@ void main() { testWidgets( 'locks the capture orientation ' - 'based on the given device orientation', (tester) async { + 'based on the given device orientation', (WidgetTester tester) async { when( () => cameraService.mapDeviceOrientationToOrientationType( DeviceOrientation.landscapeRight, @@ -793,7 +815,7 @@ void main() { group('throws PlatformException', () { testWidgets( 'with orientationNotSupported error ' - 'when screen is not supported', (tester) async { + 'when screen is not supported', (WidgetTester tester) async { when(() => window.screen).thenReturn(null); expect( @@ -803,7 +825,7 @@ void main() { ), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', CameraErrorCode.orientationNotSupported.toString(), ), @@ -813,7 +835,8 @@ void main() { testWidgets( 'with orientationNotSupported error ' - 'when screen orientation is not supported', (tester) async { + 'when screen orientation is not supported', + (WidgetTester tester) async { when(() => screen.orientation).thenReturn(null); expect( @@ -823,7 +846,7 @@ void main() { ), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', CameraErrorCode.orientationNotSupported.toString(), ), @@ -833,7 +856,8 @@ void main() { testWidgets( 'with orientationNotSupported error ' - 'when documentElement is not available', (tester) async { + 'when documentElement is not available', + (WidgetTester tester) async { when(() => document.documentElement).thenReturn(null); expect( @@ -843,7 +867,7 @@ void main() { ), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', CameraErrorCode.orientationNotSupported.toString(), ), @@ -851,8 +875,10 @@ void main() { ); }); - testWidgets('when lock throws DomException', (tester) async { - final exception = FakeDomException(DomException.NOT_ALLOWED); + testWidgets('when lock throws DomException', + (WidgetTester tester) async { + final FakeDomException exception = + FakeDomException(DomException.NOT_ALLOWED); when(() => screenOrientation.lock(any())).thenThrow(exception); @@ -863,7 +889,7 @@ void main() { ), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', exception.name, ), @@ -880,7 +906,8 @@ void main() { ).thenReturn(OrientationType.portraitPrimary); }); - testWidgets('unlocks the capture orientation', (tester) async { + testWidgets('unlocks the capture orientation', + (WidgetTester tester) async { await CameraPlatform.instance.unlockCaptureOrientation( cameraId, ); @@ -891,7 +918,7 @@ void main() { group('throws PlatformException', () { testWidgets( 'with orientationNotSupported error ' - 'when screen is not supported', (tester) async { + 'when screen is not supported', (WidgetTester tester) async { when(() => window.screen).thenReturn(null); expect( @@ -900,7 +927,7 @@ void main() { ), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', CameraErrorCode.orientationNotSupported.toString(), ), @@ -910,7 +937,8 @@ void main() { testWidgets( 'with orientationNotSupported error ' - 'when screen orientation is not supported', (tester) async { + 'when screen orientation is not supported', + (WidgetTester tester) async { when(() => screen.orientation).thenReturn(null); expect( @@ -919,7 +947,7 @@ void main() { ), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', CameraErrorCode.orientationNotSupported.toString(), ), @@ -929,7 +957,8 @@ void main() { testWidgets( 'with orientationNotSupported error ' - 'when documentElement is not available', (tester) async { + 'when documentElement is not available', + (WidgetTester tester) async { when(() => document.documentElement).thenReturn(null); expect( @@ -938,7 +967,7 @@ void main() { ), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', CameraErrorCode.orientationNotSupported.toString(), ), @@ -946,8 +975,10 @@ void main() { ); }); - testWidgets('when unlock throws DomException', (tester) async { - final exception = FakeDomException(DomException.NOT_ALLOWED); + testWidgets('when unlock throws DomException', + (WidgetTester tester) async { + final FakeDomException exception = + FakeDomException(DomException.NOT_ALLOWED); when(screenOrientation.unlock).thenThrow(exception); @@ -957,7 +988,7 @@ void main() { ), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', exception.name, ), @@ -968,17 +999,18 @@ void main() { }); group('takePicture', () { - testWidgets('captures a picture', (tester) async { - final camera = MockCamera(); - final capturedPicture = MockXFile(); + testWidgets('captures a picture', (WidgetTester tester) async { + final MockCamera camera = MockCamera(); + final MockXFile capturedPicture = MockXFile(); when(camera.takePicture) - .thenAnswer((_) => Future.value(capturedPicture)); + .thenAnswer((Invocation _) => Future.value(capturedPicture)); // Save the camera in the camera plugin. (CameraPlatform.instance as CameraPlugin).cameras[cameraId] = camera; - final picture = await CameraPlatform.instance.takePicture(cameraId); + final XFile picture = + await CameraPlatform.instance.takePicture(cameraId); verify(camera.takePicture).called(1); @@ -988,12 +1020,12 @@ void main() { group('throws PlatformException', () { testWidgets( 'with notFound error ' - 'if the camera does not exist', (tester) async { + 'if the camera does not exist', (WidgetTester tester) async { expect( () => CameraPlatform.instance.takePicture(cameraId), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', CameraErrorCode.notFound.toString(), ), @@ -1001,9 +1033,11 @@ void main() { ); }); - testWidgets('when takePicture throws DomException', (tester) async { - final camera = MockCamera(); - final exception = FakeDomException(DomException.NOT_SUPPORTED); + testWidgets('when takePicture throws DomException', + (WidgetTester tester) async { + final MockCamera camera = MockCamera(); + final FakeDomException exception = + FakeDomException(DomException.NOT_SUPPORTED); when(camera.takePicture).thenThrow(exception); @@ -1014,7 +1048,7 @@ void main() { () => CameraPlatform.instance.takePicture(cameraId), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', exception.name, ), @@ -1023,9 +1057,9 @@ void main() { }); testWidgets('when takePicture throws CameraWebException', - (tester) async { - final camera = MockCamera(); - final exception = CameraWebException( + (WidgetTester tester) async { + final MockCamera camera = MockCamera(); + final CameraWebException exception = CameraWebException( cameraId, CameraErrorCode.notStarted, 'description', @@ -1040,7 +1074,7 @@ void main() { () => CameraPlatform.instance.takePicture(cameraId), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', exception.code.toString(), ), @@ -1056,13 +1090,13 @@ void main() { setUp(() { camera = MockCamera(); - when(camera.startVideoRecording).thenAnswer((_) async {}); + when(camera.startVideoRecording).thenAnswer((Invocation _) async {}); when(() => camera.onVideoRecordingError) - .thenAnswer((_) => const Stream.empty()); + .thenAnswer((Invocation _) => const Stream.empty()); }); - testWidgets('starts a video recording', (tester) async { + testWidgets('starts a video recording', (WidgetTester tester) async { // Save the camera in the camera plugin. (CameraPlatform.instance as CameraPlugin).cameras[cameraId] = camera; @@ -1072,11 +1106,12 @@ void main() { }); testWidgets('listens to the onVideoRecordingError stream', - (tester) async { - final videoRecordingErrorController = StreamController(); + (WidgetTester tester) async { + final StreamController videoRecordingErrorController = + StreamController(); when(() => camera.onVideoRecordingError) - .thenAnswer((_) => videoRecordingErrorController.stream); + .thenAnswer((Invocation _) => videoRecordingErrorController.stream); // Save the camera in the camera plugin. (CameraPlatform.instance as CameraPlugin).cameras[cameraId] = camera; @@ -1092,12 +1127,12 @@ void main() { group('throws PlatformException', () { testWidgets( 'with notFound error ' - 'if the camera does not exist', (tester) async { + 'if the camera does not exist', (WidgetTester tester) async { expect( () => CameraPlatform.instance.startVideoRecording(cameraId), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', CameraErrorCode.notFound.toString(), ), @@ -1106,8 +1141,9 @@ void main() { }); testWidgets('when startVideoRecording throws DomException', - (tester) async { - final exception = FakeDomException(DomException.INVALID_STATE); + (WidgetTester tester) async { + final FakeDomException exception = + FakeDomException(DomException.INVALID_STATE); when(camera.startVideoRecording).thenThrow(exception); @@ -1118,7 +1154,7 @@ void main() { () => CameraPlatform.instance.startVideoRecording(cameraId), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', exception.name, ), @@ -1127,8 +1163,8 @@ void main() { }); testWidgets('when startVideoRecording throws CameraWebException', - (tester) async { - final exception = CameraWebException( + (WidgetTester tester) async { + final CameraWebException exception = CameraWebException( cameraId, CameraErrorCode.notStarted, 'description', @@ -1143,7 +1179,7 @@ void main() { () => CameraPlatform.instance.startVideoRecording(cameraId), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', exception.code.toString(), ), @@ -1154,17 +1190,17 @@ void main() { }); group('stopVideoRecording', () { - testWidgets('stops a video recording', (tester) async { - final camera = MockCamera(); - final capturedVideo = MockXFile(); + testWidgets('stops a video recording', (WidgetTester tester) async { + final MockCamera camera = MockCamera(); + final MockXFile capturedVideo = MockXFile(); when(camera.stopVideoRecording) - .thenAnswer((_) => Future.value(capturedVideo)); + .thenAnswer((Invocation _) => Future.value(capturedVideo)); // Save the camera in the camera plugin. (CameraPlatform.instance as CameraPlugin).cameras[cameraId] = camera; - final video = + final XFile video = await CameraPlatform.instance.stopVideoRecording(cameraId); verify(camera.stopVideoRecording).called(1); @@ -1173,23 +1209,25 @@ void main() { }); testWidgets('stops listening to the onVideoRecordingError stream', - (tester) async { - final camera = MockCamera(); - final videoRecordingErrorController = StreamController(); + (WidgetTester tester) async { + final MockCamera camera = MockCamera(); + final StreamController videoRecordingErrorController = + StreamController(); - when(camera.startVideoRecording).thenAnswer((_) async => {}); + when(camera.startVideoRecording).thenAnswer((Invocation _) async {}); when(camera.stopVideoRecording) - .thenAnswer((_) => Future.value(MockXFile())); + .thenAnswer((Invocation _) => Future.value(MockXFile())); when(() => camera.onVideoRecordingError) - .thenAnswer((_) => videoRecordingErrorController.stream); + .thenAnswer((Invocation _) => videoRecordingErrorController.stream); // Save the camera in the camera plugin. (CameraPlatform.instance as CameraPlugin).cameras[cameraId] = camera; await CameraPlatform.instance.startVideoRecording(cameraId); - final _ = await CameraPlatform.instance.stopVideoRecording(cameraId); + final XFile _ = + await CameraPlatform.instance.stopVideoRecording(cameraId); expect( videoRecordingErrorController.hasListener, @@ -1200,12 +1238,12 @@ void main() { group('throws PlatformException', () { testWidgets( 'with notFound error ' - 'if the camera does not exist', (tester) async { + 'if the camera does not exist', (WidgetTester tester) async { expect( () => CameraPlatform.instance.stopVideoRecording(cameraId), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', CameraErrorCode.notFound.toString(), ), @@ -1214,9 +1252,10 @@ void main() { }); testWidgets('when stopVideoRecording throws DomException', - (tester) async { - final camera = MockCamera(); - final exception = FakeDomException(DomException.INVALID_STATE); + (WidgetTester tester) async { + final MockCamera camera = MockCamera(); + final FakeDomException exception = + FakeDomException(DomException.INVALID_STATE); when(camera.stopVideoRecording).thenThrow(exception); @@ -1227,7 +1266,7 @@ void main() { () => CameraPlatform.instance.stopVideoRecording(cameraId), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', exception.name, ), @@ -1236,9 +1275,9 @@ void main() { }); testWidgets('when stopVideoRecording throws CameraWebException', - (tester) async { - final camera = MockCamera(); - final exception = CameraWebException( + (WidgetTester tester) async { + final MockCamera camera = MockCamera(); + final CameraWebException exception = CameraWebException( cameraId, CameraErrorCode.notStarted, 'description', @@ -1253,7 +1292,7 @@ void main() { () => CameraPlatform.instance.stopVideoRecording(cameraId), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', exception.code.toString(), ), @@ -1264,10 +1303,10 @@ void main() { }); group('pauseVideoRecording', () { - testWidgets('pauses a video recording', (tester) async { - final camera = MockCamera(); + testWidgets('pauses a video recording', (WidgetTester tester) async { + final MockCamera camera = MockCamera(); - when(camera.pauseVideoRecording).thenAnswer((_) async {}); + when(camera.pauseVideoRecording).thenAnswer((Invocation _) async {}); // Save the camera in the camera plugin. (CameraPlatform.instance as CameraPlugin).cameras[cameraId] = camera; @@ -1280,12 +1319,12 @@ void main() { group('throws PlatformException', () { testWidgets( 'with notFound error ' - 'if the camera does not exist', (tester) async { + 'if the camera does not exist', (WidgetTester tester) async { expect( () => CameraPlatform.instance.pauseVideoRecording(cameraId), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', CameraErrorCode.notFound.toString(), ), @@ -1294,9 +1333,10 @@ void main() { }); testWidgets('when pauseVideoRecording throws DomException', - (tester) async { - final camera = MockCamera(); - final exception = FakeDomException(DomException.INVALID_STATE); + (WidgetTester tester) async { + final MockCamera camera = MockCamera(); + final FakeDomException exception = + FakeDomException(DomException.INVALID_STATE); when(camera.pauseVideoRecording).thenThrow(exception); @@ -1307,7 +1347,7 @@ void main() { () => CameraPlatform.instance.pauseVideoRecording(cameraId), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', exception.name, ), @@ -1316,9 +1356,9 @@ void main() { }); testWidgets('when pauseVideoRecording throws CameraWebException', - (tester) async { - final camera = MockCamera(); - final exception = CameraWebException( + (WidgetTester tester) async { + final MockCamera camera = MockCamera(); + final CameraWebException exception = CameraWebException( cameraId, CameraErrorCode.notStarted, 'description', @@ -1333,7 +1373,7 @@ void main() { () => CameraPlatform.instance.pauseVideoRecording(cameraId), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', exception.code.toString(), ), @@ -1344,10 +1384,10 @@ void main() { }); group('resumeVideoRecording', () { - testWidgets('resumes a video recording', (tester) async { - final camera = MockCamera(); + testWidgets('resumes a video recording', (WidgetTester tester) async { + final MockCamera camera = MockCamera(); - when(camera.resumeVideoRecording).thenAnswer((_) async {}); + when(camera.resumeVideoRecording).thenAnswer((Invocation _) async {}); // Save the camera in the camera plugin. (CameraPlatform.instance as CameraPlugin).cameras[cameraId] = camera; @@ -1360,12 +1400,12 @@ void main() { group('throws PlatformException', () { testWidgets( 'with notFound error ' - 'if the camera does not exist', (tester) async { + 'if the camera does not exist', (WidgetTester tester) async { expect( () => CameraPlatform.instance.resumeVideoRecording(cameraId), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', CameraErrorCode.notFound.toString(), ), @@ -1374,9 +1414,10 @@ void main() { }); testWidgets('when resumeVideoRecording throws DomException', - (tester) async { - final camera = MockCamera(); - final exception = FakeDomException(DomException.INVALID_STATE); + (WidgetTester tester) async { + final MockCamera camera = MockCamera(); + final FakeDomException exception = + FakeDomException(DomException.INVALID_STATE); when(camera.resumeVideoRecording).thenThrow(exception); @@ -1387,7 +1428,7 @@ void main() { () => CameraPlatform.instance.resumeVideoRecording(cameraId), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', exception.name, ), @@ -1396,9 +1437,9 @@ void main() { }); testWidgets('when resumeVideoRecording throws CameraWebException', - (tester) async { - final camera = MockCamera(); - final exception = CameraWebException( + (WidgetTester tester) async { + final MockCamera camera = MockCamera(); + final CameraWebException exception = CameraWebException( cameraId, CameraErrorCode.notStarted, 'description', @@ -1413,7 +1454,7 @@ void main() { () => CameraPlatform.instance.resumeVideoRecording(cameraId), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', exception.code.toString(), ), @@ -1424,9 +1465,10 @@ void main() { }); group('setFlashMode', () { - testWidgets('calls setFlashMode on the camera', (tester) async { - final camera = MockCamera(); - const flashMode = FlashMode.always; + testWidgets('calls setFlashMode on the camera', + (WidgetTester tester) async { + final MockCamera camera = MockCamera(); + const FlashMode flashMode = FlashMode.always; // Save the camera in the camera plugin. (CameraPlatform.instance as CameraPlugin).cameras[cameraId] = camera; @@ -1442,7 +1484,7 @@ void main() { group('throws PlatformException', () { testWidgets( 'with notFound error ' - 'if the camera does not exist', (tester) async { + 'if the camera does not exist', (WidgetTester tester) async { expect( () => CameraPlatform.instance.setFlashMode( cameraId, @@ -1450,7 +1492,7 @@ void main() { ), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', CameraErrorCode.notFound.toString(), ), @@ -1458,9 +1500,11 @@ void main() { ); }); - testWidgets('when setFlashMode throws DomException', (tester) async { - final camera = MockCamera(); - final exception = FakeDomException(DomException.NOT_SUPPORTED); + testWidgets('when setFlashMode throws DomException', + (WidgetTester tester) async { + final MockCamera camera = MockCamera(); + final FakeDomException exception = + FakeDomException(DomException.NOT_SUPPORTED); when(() => camera.setFlashMode(any())).thenThrow(exception); @@ -1474,7 +1518,7 @@ void main() { ), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', exception.name, ), @@ -1483,9 +1527,9 @@ void main() { }); testWidgets('when setFlashMode throws CameraWebException', - (tester) async { - final camera = MockCamera(); - final exception = CameraWebException( + (WidgetTester tester) async { + final MockCamera camera = MockCamera(); + final CameraWebException exception = CameraWebException( cameraId, CameraErrorCode.notStarted, 'description', @@ -1503,7 +1547,7 @@ void main() { ), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', exception.code.toString(), ), @@ -1513,7 +1557,8 @@ void main() { }); }); - testWidgets('setExposureMode throws UnimplementedError', (tester) async { + testWidgets('setExposureMode throws UnimplementedError', + (WidgetTester tester) async { expect( () => CameraPlatform.instance.setExposureMode( cameraId, @@ -1523,18 +1568,19 @@ void main() { ); }); - testWidgets('setExposurePoint throws UnimplementedError', (tester) async { + testWidgets('setExposurePoint throws UnimplementedError', + (WidgetTester tester) async { expect( () => CameraPlatform.instance.setExposurePoint( cameraId, - const Point(0, 0), + const Point(0, 0), ), throwsUnimplementedError, ); }); testWidgets('getMinExposureOffset throws UnimplementedError', - (tester) async { + (WidgetTester tester) async { expect( () => CameraPlatform.instance.getMinExposureOffset(cameraId), throwsUnimplementedError, @@ -1542,7 +1588,7 @@ void main() { }); testWidgets('getMaxExposureOffset throws UnimplementedError', - (tester) async { + (WidgetTester tester) async { expect( () => CameraPlatform.instance.getMaxExposureOffset(cameraId), throwsUnimplementedError, @@ -1550,14 +1596,15 @@ void main() { }); testWidgets('getExposureOffsetStepSize throws UnimplementedError', - (tester) async { + (WidgetTester tester) async { expect( () => CameraPlatform.instance.getExposureOffsetStepSize(cameraId), throwsUnimplementedError, ); }); - testWidgets('setExposureOffset throws UnimplementedError', (tester) async { + testWidgets('setExposureOffset throws UnimplementedError', + (WidgetTester tester) async { expect( () => CameraPlatform.instance.setExposureOffset( cameraId, @@ -1567,7 +1614,8 @@ void main() { ); }); - testWidgets('setFocusMode throws UnimplementedError', (tester) async { + testWidgets('setFocusMode throws UnimplementedError', + (WidgetTester tester) async { expect( () => CameraPlatform.instance.setFocusMode( cameraId, @@ -1577,20 +1625,22 @@ void main() { ); }); - testWidgets('setFocusPoint throws UnimplementedError', (tester) async { + testWidgets('setFocusPoint throws UnimplementedError', + (WidgetTester tester) async { expect( () => CameraPlatform.instance.setFocusPoint( cameraId, - const Point(0, 0), + const Point(0, 0), ), throwsUnimplementedError, ); }); group('getMaxZoomLevel', () { - testWidgets('calls getMaxZoomLevel on the camera', (tester) async { - final camera = MockCamera(); - const maximumZoomLevel = 100.0; + testWidgets('calls getMaxZoomLevel on the camera', + (WidgetTester tester) async { + final MockCamera camera = MockCamera(); + const double maximumZoomLevel = 100.0; when(camera.getMaxZoomLevel).thenReturn(maximumZoomLevel); @@ -1610,14 +1660,14 @@ void main() { group('throws PlatformException', () { testWidgets( 'with notFound error ' - 'if the camera does not exist', (tester) async { + 'if the camera does not exist', (WidgetTester tester) async { expect( () async => await CameraPlatform.instance.getMaxZoomLevel( cameraId, ), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', CameraErrorCode.notFound.toString(), ), @@ -1625,9 +1675,11 @@ void main() { ); }); - testWidgets('when getMaxZoomLevel throws DomException', (tester) async { - final camera = MockCamera(); - final exception = FakeDomException(DomException.NOT_SUPPORTED); + testWidgets('when getMaxZoomLevel throws DomException', + (WidgetTester tester) async { + final MockCamera camera = MockCamera(); + final FakeDomException exception = + FakeDomException(DomException.NOT_SUPPORTED); when(camera.getMaxZoomLevel).thenThrow(exception); @@ -1640,7 +1692,7 @@ void main() { ), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', exception.name, ), @@ -1649,9 +1701,9 @@ void main() { }); testWidgets('when getMaxZoomLevel throws CameraWebException', - (tester) async { - final camera = MockCamera(); - final exception = CameraWebException( + (WidgetTester tester) async { + final MockCamera camera = MockCamera(); + final CameraWebException exception = CameraWebException( cameraId, CameraErrorCode.notStarted, 'description', @@ -1668,7 +1720,7 @@ void main() { ), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', exception.code.toString(), ), @@ -1679,9 +1731,10 @@ void main() { }); group('getMinZoomLevel', () { - testWidgets('calls getMinZoomLevel on the camera', (tester) async { - final camera = MockCamera(); - const minimumZoomLevel = 100.0; + testWidgets('calls getMinZoomLevel on the camera', + (WidgetTester tester) async { + final MockCamera camera = MockCamera(); + const double minimumZoomLevel = 100.0; when(camera.getMinZoomLevel).thenReturn(minimumZoomLevel); @@ -1701,14 +1754,14 @@ void main() { group('throws PlatformException', () { testWidgets( 'with notFound error ' - 'if the camera does not exist', (tester) async { + 'if the camera does not exist', (WidgetTester tester) async { expect( () async => await CameraPlatform.instance.getMinZoomLevel( cameraId, ), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', CameraErrorCode.notFound.toString(), ), @@ -1716,9 +1769,11 @@ void main() { ); }); - testWidgets('when getMinZoomLevel throws DomException', (tester) async { - final camera = MockCamera(); - final exception = FakeDomException(DomException.NOT_SUPPORTED); + testWidgets('when getMinZoomLevel throws DomException', + (WidgetTester tester) async { + final MockCamera camera = MockCamera(); + final FakeDomException exception = + FakeDomException(DomException.NOT_SUPPORTED); when(camera.getMinZoomLevel).thenThrow(exception); @@ -1731,7 +1786,7 @@ void main() { ), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', exception.name, ), @@ -1740,9 +1795,9 @@ void main() { }); testWidgets('when getMinZoomLevel throws CameraWebException', - (tester) async { - final camera = MockCamera(); - final exception = CameraWebException( + (WidgetTester tester) async { + final MockCamera camera = MockCamera(); + final CameraWebException exception = CameraWebException( cameraId, CameraErrorCode.notStarted, 'description', @@ -1759,7 +1814,7 @@ void main() { ), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', exception.code.toString(), ), @@ -1770,13 +1825,14 @@ void main() { }); group('setZoomLevel', () { - testWidgets('calls setZoomLevel on the camera', (tester) async { - final camera = MockCamera(); + testWidgets('calls setZoomLevel on the camera', + (WidgetTester tester) async { + final MockCamera camera = MockCamera(); // Save the camera in the camera plugin. (CameraPlatform.instance as CameraPlugin).cameras[cameraId] = camera; - const zoom = 100.0; + const double zoom = 100.0; await CameraPlatform.instance.setZoomLevel(cameraId, zoom); @@ -1786,7 +1842,7 @@ void main() { group('throws CameraException', () { testWidgets( 'with notFound error ' - 'if the camera does not exist', (tester) async { + 'if the camera does not exist', (WidgetTester tester) async { expect( () async => await CameraPlatform.instance.setZoomLevel( cameraId, @@ -1794,7 +1850,7 @@ void main() { ), throwsA( isA().having( - (e) => e.code, + (CameraException e) => e.code, 'code', CameraErrorCode.notFound.toString(), ), @@ -1802,9 +1858,11 @@ void main() { ); }); - testWidgets('when setZoomLevel throws DomException', (tester) async { - final camera = MockCamera(); - final exception = FakeDomException(DomException.NOT_SUPPORTED); + testWidgets('when setZoomLevel throws DomException', + (WidgetTester tester) async { + final MockCamera camera = MockCamera(); + final FakeDomException exception = + FakeDomException(DomException.NOT_SUPPORTED); when(() => camera.setZoomLevel(any())).thenThrow(exception); @@ -1818,7 +1876,7 @@ void main() { ), throwsA( isA().having( - (e) => e.code, + (CameraException e) => e.code, 'code', exception.name, ), @@ -1827,9 +1885,9 @@ void main() { }); testWidgets('when setZoomLevel throws PlatformException', - (tester) async { - final camera = MockCamera(); - final exception = PlatformException( + (WidgetTester tester) async { + final MockCamera camera = MockCamera(); + final PlatformException exception = PlatformException( code: CameraErrorCode.notSupported.toString(), message: 'message', ); @@ -1846,7 +1904,7 @@ void main() { ), throwsA( isA().having( - (e) => e.code, + (CameraException e) => e.code, 'code', exception.code, ), @@ -1855,9 +1913,9 @@ void main() { }); testWidgets('when setZoomLevel throws CameraWebException', - (tester) async { - final camera = MockCamera(); - final exception = CameraWebException( + (WidgetTester tester) async { + final MockCamera camera = MockCamera(); + final CameraWebException exception = CameraWebException( cameraId, CameraErrorCode.notStarted, 'description', @@ -1875,7 +1933,7 @@ void main() { ), throwsA( isA().having( - (e) => e.code, + (CameraException e) => e.code, 'code', exception.code.toString(), ), @@ -1886,8 +1944,8 @@ void main() { }); group('pausePreview', () { - testWidgets('calls pause on the camera', (tester) async { - final camera = MockCamera(); + testWidgets('calls pause on the camera', (WidgetTester tester) async { + final MockCamera camera = MockCamera(); // Save the camera in the camera plugin. (CameraPlatform.instance as CameraPlugin).cameras[cameraId] = camera; @@ -1900,12 +1958,12 @@ void main() { group('throws PlatformException', () { testWidgets( 'with notFound error ' - 'if the camera does not exist', (tester) async { + 'if the camera does not exist', (WidgetTester tester) async { expect( () async => await CameraPlatform.instance.pausePreview(cameraId), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', CameraErrorCode.notFound.toString(), ), @@ -1913,9 +1971,11 @@ void main() { ); }); - testWidgets('when pause throws DomException', (tester) async { - final camera = MockCamera(); - final exception = FakeDomException(DomException.NOT_SUPPORTED); + testWidgets('when pause throws DomException', + (WidgetTester tester) async { + final MockCamera camera = MockCamera(); + final FakeDomException exception = + FakeDomException(DomException.NOT_SUPPORTED); when(camera.pause).thenThrow(exception); @@ -1926,7 +1986,7 @@ void main() { () async => await CameraPlatform.instance.pausePreview(cameraId), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', exception.name, ), @@ -1937,10 +1997,10 @@ void main() { }); group('resumePreview', () { - testWidgets('calls play on the camera', (tester) async { - final camera = MockCamera(); + testWidgets('calls play on the camera', (WidgetTester tester) async { + final MockCamera camera = MockCamera(); - when(camera.play).thenAnswer((_) async => {}); + when(camera.play).thenAnswer((Invocation _) async {}); // Save the camera in the camera plugin. (CameraPlatform.instance as CameraPlugin).cameras[cameraId] = camera; @@ -1953,12 +2013,12 @@ void main() { group('throws PlatformException', () { testWidgets( 'with notFound error ' - 'if the camera does not exist', (tester) async { + 'if the camera does not exist', (WidgetTester tester) async { expect( () async => await CameraPlatform.instance.resumePreview(cameraId), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', CameraErrorCode.notFound.toString(), ), @@ -1966,9 +2026,11 @@ void main() { ); }); - testWidgets('when play throws DomException', (tester) async { - final camera = MockCamera(); - final exception = FakeDomException(DomException.NOT_SUPPORTED); + testWidgets('when play throws DomException', + (WidgetTester tester) async { + final MockCamera camera = MockCamera(); + final FakeDomException exception = + FakeDomException(DomException.NOT_SUPPORTED); when(camera.play).thenThrow(exception); @@ -1979,7 +2041,7 @@ void main() { () async => await CameraPlatform.instance.resumePreview(cameraId), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', exception.name, ), @@ -1987,9 +2049,10 @@ void main() { ); }); - testWidgets('when play throws CameraWebException', (tester) async { - final camera = MockCamera(); - final exception = CameraWebException( + testWidgets('when play throws CameraWebException', + (WidgetTester tester) async { + final MockCamera camera = MockCamera(); + final CameraWebException exception = CameraWebException( cameraId, CameraErrorCode.unknown, 'description', @@ -2004,7 +2067,7 @@ void main() { () async => await CameraPlatform.instance.resumePreview(cameraId), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', exception.code.toString(), ), @@ -2016,8 +2079,8 @@ void main() { testWidgets( 'buildPreview returns an HtmlElementView ' - 'with an appropriate view type', (tester) async { - final camera = Camera( + 'with an appropriate view type', (WidgetTester tester) async { + final Camera camera = Camera( textureId: cameraId, cameraService: cameraService, ); @@ -2028,7 +2091,7 @@ void main() { expect( CameraPlatform.instance.buildPreview(cameraId), isA().having( - (view) => view.viewType, + (widgets.HtmlElementView view) => view.viewType, 'viewType', camera.getViewType(), ), @@ -2052,38 +2115,41 @@ void main() { endedStreamController = StreamController(); videoRecordingErrorController = StreamController(); - when(camera.getVideoSize).thenReturn(Size(10, 10)); - when(camera.initialize).thenAnswer((_) => Future.value()); - when(camera.play).thenAnswer((_) => Future.value()); - when(camera.dispose).thenAnswer((_) => Future.value()); + when(camera.getVideoSize).thenReturn(const Size(10, 10)); + when(camera.initialize) + .thenAnswer((Invocation _) => Future.value()); + when(camera.play).thenAnswer((Invocation _) => Future.value()); + when(camera.dispose).thenAnswer((Invocation _) => Future.value()); when(() => camera.videoElement).thenReturn(videoElement); - when(() => videoElement.onError) - .thenAnswer((_) => FakeElementStream(errorStreamController.stream)); - when(() => videoElement.onAbort) - .thenAnswer((_) => FakeElementStream(abortStreamController.stream)); + when(() => videoElement.onError).thenAnswer((Invocation _) => + FakeElementStream(errorStreamController.stream)); + when(() => videoElement.onAbort).thenAnswer((Invocation _) => + FakeElementStream(abortStreamController.stream)); when(() => camera.onEnded) - .thenAnswer((_) => endedStreamController.stream); + .thenAnswer((Invocation _) => endedStreamController.stream); when(() => camera.onVideoRecordingError) - .thenAnswer((_) => videoRecordingErrorController.stream); + .thenAnswer((Invocation _) => videoRecordingErrorController.stream); - when(camera.startVideoRecording).thenAnswer((_) async {}); + when(camera.startVideoRecording).thenAnswer((Invocation _) async {}); }); - testWidgets('disposes the correct camera', (tester) async { - const firstCameraId = 0; - const secondCameraId = 1; + testWidgets('disposes the correct camera', (WidgetTester tester) async { + const int firstCameraId = 0; + const int secondCameraId = 1; - final firstCamera = MockCamera(); - final secondCamera = MockCamera(); + final MockCamera firstCamera = MockCamera(); + final MockCamera secondCamera = MockCamera(); - when(firstCamera.dispose).thenAnswer((_) => Future.value()); - when(secondCamera.dispose).thenAnswer((_) => Future.value()); + when(firstCamera.dispose) + .thenAnswer((Invocation _) => Future.value()); + when(secondCamera.dispose) + .thenAnswer((Invocation _) => Future.value()); // Save cameras in the camera plugin. - (CameraPlatform.instance as CameraPlugin).cameras.addAll({ + (CameraPlatform.instance as CameraPlugin).cameras.addAll({ firstCameraId: firstCamera, secondCameraId: secondCamera, }); @@ -2098,14 +2164,14 @@ void main() { // The first camera should be removed from the camera plugin. expect( (CameraPlatform.instance as CameraPlugin).cameras, - equals({ + equals({ secondCameraId: secondCamera, }), ); }); testWidgets('cancels the camera video error and abort subscriptions', - (tester) async { + (WidgetTester tester) async { // Save the camera in the camera plugin. (CameraPlatform.instance as CameraPlugin).cameras[cameraId] = camera; @@ -2116,7 +2182,8 @@ void main() { expect(abortStreamController.hasListener, isFalse); }); - testWidgets('cancels the camera ended subscriptions', (tester) async { + testWidgets('cancels the camera ended subscriptions', + (WidgetTester tester) async { // Save the camera in the camera plugin. (CameraPlatform.instance as CameraPlugin).cameras[cameraId] = camera; @@ -2127,7 +2194,7 @@ void main() { }); testWidgets('cancels the camera video recording error subscriptions', - (tester) async { + (WidgetTester tester) async { // Save the camera in the camera plugin. (CameraPlatform.instance as CameraPlugin).cameras[cameraId] = camera; @@ -2141,12 +2208,12 @@ void main() { group('throws PlatformException', () { testWidgets( 'with notFound error ' - 'if the camera does not exist', (tester) async { + 'if the camera does not exist', (WidgetTester tester) async { expect( () => CameraPlatform.instance.dispose(cameraId), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', CameraErrorCode.notFound.toString(), ), @@ -2154,9 +2221,11 @@ void main() { ); }); - testWidgets('when dispose throws DomException', (tester) async { - final camera = MockCamera(); - final exception = FakeDomException(DomException.INVALID_ACCESS); + testWidgets('when dispose throws DomException', + (WidgetTester tester) async { + final MockCamera camera = MockCamera(); + final FakeDomException exception = + FakeDomException(DomException.INVALID_ACCESS); when(camera.dispose).thenThrow(exception); @@ -2167,7 +2236,7 @@ void main() { () => CameraPlatform.instance.dispose(cameraId), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', exception.name, ), @@ -2178,8 +2247,8 @@ void main() { }); group('getCamera', () { - testWidgets('returns the correct camera', (tester) async { - final camera = Camera( + testWidgets('returns the correct camera', (WidgetTester tester) async { + final Camera camera = Camera( textureId: cameraId, cameraService: cameraService, ); @@ -2196,12 +2265,12 @@ void main() { testWidgets( 'throws PlatformException ' 'with notFound error ' - 'if the camera does not exist', (tester) async { + 'if the camera does not exist', (WidgetTester tester) async { expect( () => (CameraPlatform.instance as CameraPlugin).getCamera(cameraId), throwsA( isA().having( - (e) => e.code, + (PlatformException e) => e.code, 'code', CameraErrorCode.notFound.toString(), ), @@ -2227,30 +2296,32 @@ void main() { endedStreamController = StreamController(); videoRecordingErrorController = StreamController(); - when(camera.getVideoSize).thenReturn(Size(10, 10)); - when(camera.initialize).thenAnswer((_) => Future.value()); - when(camera.play).thenAnswer((_) => Future.value()); + when(camera.getVideoSize).thenReturn(const Size(10, 10)); + when(camera.initialize) + .thenAnswer((Invocation _) => Future.value()); + when(camera.play).thenAnswer((Invocation _) => Future.value()); when(() => camera.videoElement).thenReturn(videoElement); - when(() => videoElement.onError) - .thenAnswer((_) => FakeElementStream(errorStreamController.stream)); - when(() => videoElement.onAbort) - .thenAnswer((_) => FakeElementStream(abortStreamController.stream)); + when(() => videoElement.onError).thenAnswer((Invocation _) => + FakeElementStream(errorStreamController.stream)); + when(() => videoElement.onAbort).thenAnswer((Invocation _) => + FakeElementStream(abortStreamController.stream)); when(() => camera.onEnded) - .thenAnswer((_) => endedStreamController.stream); + .thenAnswer((Invocation _) => endedStreamController.stream); when(() => camera.onVideoRecordingError) - .thenAnswer((_) => videoRecordingErrorController.stream); + .thenAnswer((Invocation _) => videoRecordingErrorController.stream); - when(() => camera.startVideoRecording()).thenAnswer((_) async => {}); + when(() => camera.startVideoRecording()) + .thenAnswer((Invocation _) async {}); }); testWidgets( 'onCameraInitialized emits a CameraInitializedEvent ' - 'on initializeCamera', (tester) async { + 'on initializeCamera', (WidgetTester tester) async { // Mock the camera to use a blank video stream of size 1280x720. - const videoSize = Size(1280, 720); + const Size videoSize = Size(1280, 720); videoElement = getVideoElementWithBlankStream(videoSize); @@ -2259,9 +2330,9 @@ void main() { any(), cameraId: cameraId, ), - ).thenAnswer((_) async => videoElement.captureStream()); + ).thenAnswer((Invocation _) async => videoElement.captureStream()); - final camera = Camera( + final Camera camera = Camera( textureId: cameraId, cameraService: cameraService, ); @@ -2272,7 +2343,8 @@ void main() { final Stream eventStream = CameraPlatform.instance.onCameraInitialized(cameraId); - final streamQueue = StreamQueue(eventStream); + final StreamQueue streamQueue = + StreamQueue(eventStream); await CameraPlatform.instance.initializeCamera(cameraId); @@ -2295,7 +2367,7 @@ void main() { }); testWidgets('onCameraResolutionChanged emits an empty stream', - (tester) async { + (WidgetTester tester) async { expect( CameraPlatform.instance.onCameraResolutionChanged(cameraId), emits(isEmpty), @@ -2304,14 +2376,15 @@ void main() { testWidgets( 'onCameraClosing emits a CameraClosingEvent ' - 'on the camera ended event', (tester) async { + 'on the camera ended event', (WidgetTester tester) async { // Save the camera in the camera plugin. (CameraPlatform.instance as CameraPlugin).cameras[cameraId] = camera; final Stream eventStream = CameraPlatform.instance.onCameraClosing(cameraId); - final streamQueue = StreamQueue(eventStream); + final StreamQueue streamQueue = + StreamQueue(eventStream); await CameraPlatform.instance.initializeCamera(cameraId); @@ -2320,7 +2393,7 @@ void main() { expect( await streamQueue.next, equals( - CameraClosingEvent(cameraId), + const CameraClosingEvent(cameraId), ), ); @@ -2336,20 +2409,22 @@ void main() { testWidgets( 'emits a CameraErrorEvent ' 'on the camera video error event ' - 'with a message', (tester) async { + 'with a message', (WidgetTester tester) async { final Stream eventStream = CameraPlatform.instance.onCameraError(cameraId); - final streamQueue = StreamQueue(eventStream); + final StreamQueue streamQueue = + StreamQueue(eventStream); await CameraPlatform.instance.initializeCamera(cameraId); - final error = FakeMediaError( + final FakeMediaError error = FakeMediaError( MediaError.MEDIA_ERR_NETWORK, 'A network error occured.', ); - final errorCode = CameraErrorCode.fromMediaError(error); + final CameraErrorCode errorCode = + CameraErrorCode.fromMediaError(error); when(() => videoElement.error).thenReturn(error); @@ -2360,7 +2435,7 @@ void main() { equals( CameraErrorEvent( cameraId, - 'Error code: ${errorCode}, error message: ${error.message}', + 'Error code: $errorCode, error message: ${error.message}', ), ), ); @@ -2371,16 +2446,19 @@ void main() { testWidgets( 'emits a CameraErrorEvent ' 'on the camera video error event ' - 'with no message', (tester) async { + 'with no message', (WidgetTester tester) async { final Stream eventStream = CameraPlatform.instance.onCameraError(cameraId); - final streamQueue = StreamQueue(eventStream); + final StreamQueue streamQueue = + StreamQueue(eventStream); await CameraPlatform.instance.initializeCamera(cameraId); - final error = FakeMediaError(MediaError.MEDIA_ERR_NETWORK); - final errorCode = CameraErrorCode.fromMediaError(error); + final FakeMediaError error = + FakeMediaError(MediaError.MEDIA_ERR_NETWORK); + final CameraErrorCode errorCode = + CameraErrorCode.fromMediaError(error); when(() => videoElement.error).thenReturn(error); @@ -2391,7 +2469,7 @@ void main() { equals( CameraErrorEvent( cameraId, - 'Error code: ${errorCode}, error message: No further diagnostic information can be determined or provided.', + 'Error code: $errorCode, error message: No further diagnostic information can be determined or provided.', ), ), ); @@ -2401,11 +2479,12 @@ void main() { testWidgets( 'emits a CameraErrorEvent ' - 'on the camera video abort event', (tester) async { + 'on the camera video abort event', (WidgetTester tester) async { final Stream eventStream = CameraPlatform.instance.onCameraError(cameraId); - final streamQueue = StreamQueue(eventStream); + final StreamQueue streamQueue = + StreamQueue(eventStream); await CameraPlatform.instance.initializeCamera(cameraId); @@ -2426,8 +2505,8 @@ void main() { testWidgets( 'emits a CameraErrorEvent ' - 'on takePicture error', (tester) async { - final exception = CameraWebException( + 'on takePicture error', (WidgetTester tester) async { + final CameraWebException exception = CameraWebException( cameraId, CameraErrorCode.notStarted, 'description', @@ -2438,7 +2517,8 @@ void main() { final Stream eventStream = CameraPlatform.instance.onCameraError(cameraId); - final streamQueue = StreamQueue(eventStream); + final StreamQueue streamQueue = + StreamQueue(eventStream); expect( () async => await CameraPlatform.instance.takePicture(cameraId), @@ -2462,8 +2542,8 @@ void main() { testWidgets( 'emits a CameraErrorEvent ' - 'on setFlashMode error', (tester) async { - final exception = CameraWebException( + 'on setFlashMode error', (WidgetTester tester) async { + final CameraWebException exception = CameraWebException( cameraId, CameraErrorCode.notStarted, 'description', @@ -2474,7 +2554,8 @@ void main() { final Stream eventStream = CameraPlatform.instance.onCameraError(cameraId); - final streamQueue = StreamQueue(eventStream); + final StreamQueue streamQueue = + StreamQueue(eventStream); expect( () async => await CameraPlatform.instance.setFlashMode( @@ -2501,8 +2582,8 @@ void main() { testWidgets( 'emits a CameraErrorEvent ' - 'on getMaxZoomLevel error', (tester) async { - final exception = CameraWebException( + 'on getMaxZoomLevel error', (WidgetTester tester) async { + final CameraWebException exception = CameraWebException( cameraId, CameraErrorCode.zoomLevelNotSupported, 'description', @@ -2513,7 +2594,8 @@ void main() { final Stream eventStream = CameraPlatform.instance.onCameraError(cameraId); - final streamQueue = StreamQueue(eventStream); + final StreamQueue streamQueue = + StreamQueue(eventStream); expect( () async => await CameraPlatform.instance.getMaxZoomLevel( @@ -2539,8 +2621,8 @@ void main() { testWidgets( 'emits a CameraErrorEvent ' - 'on getMinZoomLevel error', (tester) async { - final exception = CameraWebException( + 'on getMinZoomLevel error', (WidgetTester tester) async { + final CameraWebException exception = CameraWebException( cameraId, CameraErrorCode.zoomLevelNotSupported, 'description', @@ -2551,7 +2633,8 @@ void main() { final Stream eventStream = CameraPlatform.instance.onCameraError(cameraId); - final streamQueue = StreamQueue(eventStream); + final StreamQueue streamQueue = + StreamQueue(eventStream); expect( () async => await CameraPlatform.instance.getMinZoomLevel( @@ -2577,8 +2660,8 @@ void main() { testWidgets( 'emits a CameraErrorEvent ' - 'on setZoomLevel error', (tester) async { - final exception = CameraWebException( + 'on setZoomLevel error', (WidgetTester tester) async { + final CameraWebException exception = CameraWebException( cameraId, CameraErrorCode.zoomLevelNotSupported, 'description', @@ -2589,7 +2672,8 @@ void main() { final Stream eventStream = CameraPlatform.instance.onCameraError(cameraId); - final streamQueue = StreamQueue(eventStream); + final StreamQueue streamQueue = + StreamQueue(eventStream); expect( () async => await CameraPlatform.instance.setZoomLevel( @@ -2616,8 +2700,8 @@ void main() { testWidgets( 'emits a CameraErrorEvent ' - 'on resumePreview error', (tester) async { - final exception = CameraWebException( + 'on resumePreview error', (WidgetTester tester) async { + final CameraWebException exception = CameraWebException( cameraId, CameraErrorCode.unknown, 'description', @@ -2628,7 +2712,8 @@ void main() { final Stream eventStream = CameraPlatform.instance.onCameraError(cameraId); - final streamQueue = StreamQueue(eventStream); + final StreamQueue streamQueue = + StreamQueue(eventStream); expect( () async => await CameraPlatform.instance.resumePreview(cameraId), @@ -2652,15 +2737,15 @@ void main() { testWidgets( 'emits a CameraErrorEvent ' - 'on startVideoRecording error', (tester) async { - final exception = CameraWebException( + 'on startVideoRecording error', (WidgetTester tester) async { + final CameraWebException exception = CameraWebException( cameraId, CameraErrorCode.notStarted, 'description', ); when(() => camera.onVideoRecordingError) - .thenAnswer((_) => const Stream.empty()); + .thenAnswer((Invocation _) => const Stream.empty()); when( () => camera.startVideoRecording( @@ -2671,7 +2756,8 @@ void main() { final Stream eventStream = CameraPlatform.instance.onCameraError(cameraId); - final streamQueue = StreamQueue(eventStream); + final StreamQueue streamQueue = + StreamQueue(eventStream); expect( () async => @@ -2696,16 +2782,18 @@ void main() { testWidgets( 'emits a CameraErrorEvent ' - 'on the camera video recording error event', (tester) async { + 'on the camera video recording error event', + (WidgetTester tester) async { final Stream eventStream = CameraPlatform.instance.onCameraError(cameraId); - final streamQueue = StreamQueue(eventStream); + final StreamQueue streamQueue = + StreamQueue(eventStream); await CameraPlatform.instance.initializeCamera(cameraId); await CameraPlatform.instance.startVideoRecording(cameraId); - final errorEvent = FakeErrorEvent('type', 'message'); + final FakeErrorEvent errorEvent = FakeErrorEvent('type', 'message'); videoRecordingErrorController.add(errorEvent); @@ -2724,8 +2812,8 @@ void main() { testWidgets( 'emits a CameraErrorEvent ' - 'on stopVideoRecording error', (tester) async { - final exception = CameraWebException( + 'on stopVideoRecording error', (WidgetTester tester) async { + final CameraWebException exception = CameraWebException( cameraId, CameraErrorCode.notStarted, 'description', @@ -2736,7 +2824,8 @@ void main() { final Stream eventStream = CameraPlatform.instance.onCameraError(cameraId); - final streamQueue = StreamQueue(eventStream); + final StreamQueue streamQueue = + StreamQueue(eventStream); expect( () async => @@ -2761,8 +2850,8 @@ void main() { testWidgets( 'emits a CameraErrorEvent ' - 'on pauseVideoRecording error', (tester) async { - final exception = CameraWebException( + 'on pauseVideoRecording error', (WidgetTester tester) async { + final CameraWebException exception = CameraWebException( cameraId, CameraErrorCode.notStarted, 'description', @@ -2773,7 +2862,8 @@ void main() { final Stream eventStream = CameraPlatform.instance.onCameraError(cameraId); - final streamQueue = StreamQueue(eventStream); + final StreamQueue streamQueue = + StreamQueue(eventStream); expect( () async => @@ -2798,8 +2888,8 @@ void main() { testWidgets( 'emits a CameraErrorEvent ' - 'on resumeVideoRecording error', (tester) async { - final exception = CameraWebException( + 'on resumeVideoRecording error', (WidgetTester tester) async { + final CameraWebException exception = CameraWebException( cameraId, CameraErrorCode.notStarted, 'description', @@ -2810,7 +2900,8 @@ void main() { final Stream eventStream = CameraPlatform.instance.onCameraError(cameraId); - final streamQueue = StreamQueue(eventStream); + final StreamQueue streamQueue = + StreamQueue(eventStream); expect( () async => @@ -2835,18 +2926,21 @@ void main() { }); testWidgets('onVideoRecordedEvent emits a VideoRecordedEvent', - (tester) async { - final camera = MockCamera(); - final capturedVideo = MockXFile(); - final stream = Stream.value( - VideoRecordedEvent(cameraId, capturedVideo, Duration.zero)); - when(() => camera.onVideoRecordedEvent).thenAnswer((_) => stream); + (WidgetTester tester) async { + final MockCamera camera = MockCamera(); + final MockXFile capturedVideo = MockXFile(); + final Stream stream = + Stream.value( + VideoRecordedEvent(cameraId, capturedVideo, Duration.zero)); + when(() => camera.onVideoRecordedEvent) + .thenAnswer((Invocation _) => stream); // Save the camera in the camera plugin. (CameraPlatform.instance as CameraPlugin).cameras[cameraId] = camera; - final streamQueue = - StreamQueue(CameraPlatform.instance.onVideoRecordedEvent(cameraId)); + final StreamQueue streamQueue = + StreamQueue( + CameraPlatform.instance.onVideoRecordedEvent(cameraId)); expect( await streamQueue.next, @@ -2858,7 +2952,8 @@ void main() { group('onDeviceOrientationChanged', () { group('emits an empty stream', () { - testWidgets('when screen is not supported', (tester) async { + testWidgets('when screen is not supported', + (WidgetTester tester) async { when(() => window.screen).thenReturn(null); expect( @@ -2868,7 +2963,7 @@ void main() { }); testWidgets('when screen orientation is not supported', - (tester) async { + (WidgetTester tester) async { when(() => screen.orientation).thenReturn(null); expect( @@ -2879,7 +2974,7 @@ void main() { }); testWidgets('emits the initial DeviceOrientationChangedEvent', - (tester) async { + (WidgetTester tester) async { when( () => cameraService.mapOrientationTypeToDeviceOrientation( OrientationType.portraitPrimary, @@ -2890,20 +2985,22 @@ void main() { when(() => screenOrientation.type) .thenReturn(OrientationType.portraitPrimary); - final eventStreamController = StreamController(); + final StreamController eventStreamController = + StreamController(); when(() => screenOrientation.onChange) - .thenAnswer((_) => eventStreamController.stream); + .thenAnswer((Invocation _) => eventStreamController.stream); final Stream eventStream = CameraPlatform.instance.onDeviceOrientationChanged(); - final streamQueue = StreamQueue(eventStream); + final StreamQueue streamQueue = + StreamQueue(eventStream); expect( await streamQueue.next, equals( - DeviceOrientationChangedEvent( + const DeviceOrientationChangedEvent( DeviceOrientation.portraitUp, ), ), @@ -2914,7 +3011,8 @@ void main() { testWidgets( 'emits a DeviceOrientationChangedEvent ' - 'when the screen orientation is changed', (tester) async { + 'when the screen orientation is changed', + (WidgetTester tester) async { when( () => cameraService.mapOrientationTypeToDeviceOrientation( OrientationType.landscapePrimary, @@ -2927,15 +3025,17 @@ void main() { ), ).thenReturn(DeviceOrientation.portraitDown); - final eventStreamController = StreamController(); + final StreamController eventStreamController = + StreamController(); when(() => screenOrientation.onChange) - .thenAnswer((_) => eventStreamController.stream); + .thenAnswer((Invocation _) => eventStreamController.stream); final Stream eventStream = CameraPlatform.instance.onDeviceOrientationChanged(); - final streamQueue = StreamQueue(eventStream); + final StreamQueue streamQueue = + StreamQueue(eventStream); // Change the screen orientation to landscapePrimary and // emit an event on the screenOrientation.onChange stream. @@ -2947,7 +3047,7 @@ void main() { expect( await streamQueue.next, equals( - DeviceOrientationChangedEvent( + const DeviceOrientationChangedEvent( DeviceOrientation.landscapeLeft, ), ), @@ -2963,7 +3063,7 @@ void main() { expect( await streamQueue.next, equals( - DeviceOrientationChangedEvent( + const DeviceOrientationChangedEvent( DeviceOrientation.portraitDown, ), ), diff --git a/packages/camera/camera_web/example/integration_test/helpers/mocks.dart b/packages/camera/camera_web/example/integration_test/helpers/mocks.dart index 77e9077356f7..3d9550fb7ab8 100644 --- a/packages/camera/camera_web/example/integration_test/helpers/mocks.dart +++ b/packages/camera/camera_web/example/integration_test/helpers/mocks.dart @@ -160,12 +160,12 @@ class FakeErrorEvent extends Fake implements ErrorEvent { /// final videoStream = videoElement.captureStream(); /// ``` VideoElement getVideoElementWithBlankStream(Size videoSize) { - final canvasElement = CanvasElement( + final CanvasElement canvasElement = CanvasElement( width: videoSize.width.toInt(), height: videoSize.height.toInt(), )..context2D.fillRect(0, 0, videoSize.width, videoSize.height); - final videoElement = VideoElement() + final VideoElement videoElement = VideoElement() ..srcObject = canvasElement.captureStream(); return videoElement; diff --git a/packages/camera/camera_web/example/integration_test/zoom_level_capability_test.dart b/packages/camera/camera_web/example/integration_test/zoom_level_capability_test.dart index 09de03100871..8614cd95880f 100644 --- a/packages/camera/camera_web/example/integration_test/zoom_level_capability_test.dart +++ b/packages/camera/camera_web/example/integration_test/zoom_level_capability_test.dart @@ -12,12 +12,12 @@ void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('ZoomLevelCapability', () { - testWidgets('sets all properties', (tester) async { - const minimum = 100.0; - const maximum = 400.0; - final videoTrack = MockMediaStreamTrack(); + testWidgets('sets all properties', (WidgetTester tester) async { + const double minimum = 100.0; + const double maximum = 400.0; + final MockMediaStreamTrack videoTrack = MockMediaStreamTrack(); - final capability = ZoomLevelCapability( + final ZoomLevelCapability capability = ZoomLevelCapability( minimum: minimum, maximum: maximum, videoTrack: videoTrack, @@ -28,8 +28,8 @@ void main() { expect(capability.videoTrack, equals(videoTrack)); }); - testWidgets('supports value equality', (tester) async { - final videoTrack = MockMediaStreamTrack(); + testWidgets('supports value equality', (WidgetTester tester) async { + final MockMediaStreamTrack videoTrack = MockMediaStreamTrack(); expect( ZoomLevelCapability( diff --git a/packages/camera/camera_web/example/lib/main.dart b/packages/camera/camera_web/example/lib/main.dart index 6e8f85e74f40..ab04ce2ca2c7 100644 --- a/packages/camera/camera_web/example/lib/main.dart +++ b/packages/camera/camera_web/example/lib/main.dart @@ -10,7 +10,7 @@ void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { - return Directionality( + return const Directionality( textDirection: TextDirection.ltr, child: Text('Testing... Look at the console output for results!'), ); diff --git a/packages/camera/camera_web/example/pubspec.yaml b/packages/camera/camera_web/example/pubspec.yaml index 1e075712325e..0457e8fdfcf2 100644 --- a/packages/camera/camera_web/example/pubspec.yaml +++ b/packages/camera/camera_web/example/pubspec.yaml @@ -10,7 +10,6 @@ dependencies: sdk: flutter dev_dependencies: - mocktail: ^0.1.4 camera_web: path: ../ flutter_driver: @@ -19,3 +18,4 @@ dev_dependencies: sdk: flutter integration_test: sdk: flutter + mocktail: ^0.1.4 diff --git a/packages/camera/camera_web/lib/src/camera.dart b/packages/camera/camera_web/lib/src/camera.dart index cf0187057188..71368c65e99d 100644 --- a/packages/camera/camera_web/lib/src/camera.dart +++ b/packages/camera/camera_web/lib/src/camera.dart @@ -49,7 +49,7 @@ class Camera { // A torch mode constraint name. // See: https://w3c.github.io/mediacapture-image/#dom-mediatracksupportedconstraints-torch - static const _torchModeKey = "torch"; + static const String _torchModeKey = 'torch'; /// The texture id used to register the camera view. final int textureId; @@ -82,7 +82,8 @@ class Camera { /// The stream controller for the [onEnded] stream. @visibleForTesting - final onEndedController = StreamController.broadcast(); + final StreamController onEndedController = + StreamController.broadcast(); StreamSubscription? _onEndedSubscription; @@ -98,7 +99,7 @@ class Camera { /// The stream controller for the [onVideoRecordingError] stream. @visibleForTesting - final videoRecordingErrorController = + final StreamController videoRecordingErrorController = StreamController.broadcast(); StreamSubscription? _onVideoRecordingErrorSubscription; @@ -124,7 +125,7 @@ class Camera { html.MediaRecorder.isTypeSupported; /// The list of consecutive video data files recorded with [mediaRecorder]. - List _videoData = []; + final List _videoData = []; /// Completes when the video recording is stopped/finished. Completer? _videoAvailableCompleter; @@ -138,7 +139,7 @@ class Camera { /// A builder to merge a list of blobs into a single blob. @visibleForTesting html.Blob Function(List blobs, String type) blobBuilder = - (blobs, type) => html.Blob(blobs, type); + (List blobs, String type) => html.Blob(blobs, type); /// The stream that emits a [VideoRecordedEvent] when a video recording is created. Stream get onVideoRecordedEvent => @@ -177,10 +178,10 @@ class Camera { _applyDefaultVideoStyles(videoElement); - final videoTracks = stream!.getVideoTracks(); + final List videoTracks = stream!.getVideoTracks(); if (videoTracks.isNotEmpty) { - final defaultVideoTrack = videoTracks.first; + final html.MediaStreamTrack defaultVideoTrack = videoTracks.first; _onEndedSubscription = defaultVideoTrack.onEnded.listen((html.Event _) { onEndedController.add(defaultVideoTrack); @@ -209,14 +210,14 @@ class Camera { /// Stops the camera stream and resets the camera source. void stop() { - final videoTracks = stream!.getVideoTracks(); + final List videoTracks = stream!.getVideoTracks(); if (videoTracks.isNotEmpty) { onEndedController.add(videoTracks.first); } - final tracks = stream?.getTracks(); + final List? tracks = stream?.getTracks(); if (tracks != null) { - for (final track in tracks) { + for (final html.MediaStreamTrack track in tracks) { track.stop(); } } @@ -229,17 +230,18 @@ class Camera { /// Enables the camera flash (torch mode) for a period of taking a picture /// if the flash mode is either [FlashMode.auto] or [FlashMode.always]. Future takePicture() async { - final shouldEnableTorchMode = + final bool shouldEnableTorchMode = flashMode == FlashMode.auto || flashMode == FlashMode.always; if (shouldEnableTorchMode) { _setTorchMode(enabled: true); } - final videoWidth = videoElement.videoWidth; - final videoHeight = videoElement.videoHeight; - final canvas = html.CanvasElement(width: videoWidth, height: videoHeight); - final isBackCamera = getLensDirection() == CameraLensDirection.back; + final int videoWidth = videoElement.videoWidth; + final int videoHeight = videoElement.videoHeight; + final html.CanvasElement canvas = + html.CanvasElement(width: videoWidth, height: videoHeight); + final bool isBackCamera = getLensDirection() == CameraLensDirection.back; // Flip the picture horizontally if it is not taken from a back camera. if (!isBackCamera) { @@ -251,7 +253,7 @@ class Camera { canvas.context2D .drawImageScaled(videoElement, 0, 0, videoWidth, videoHeight); - final blob = await canvas.toBlob('image/jpeg'); + final html.Blob blob = await canvas.toBlob('image/jpeg'); if (shouldEnableTorchMode) { _setTorchMode(enabled: false); @@ -265,17 +267,19 @@ class Camera { /// Returns [Size.zero] if the camera is missing a video track or /// the video track does not include the width or height setting. Size getVideoSize() { - final videoTracks = videoElement.srcObject?.getVideoTracks() ?? []; + final List videoTracks = + videoElement.srcObject?.getVideoTracks() ?? []; if (videoTracks.isEmpty) { return Size.zero; } - final defaultVideoTrack = videoTracks.first; - final defaultVideoTrackSettings = defaultVideoTrack.getSettings(); + final html.MediaStreamTrack defaultVideoTrack = videoTracks.first; + final Map defaultVideoTrackSettings = + defaultVideoTrack.getSettings(); - final width = defaultVideoTrackSettings['width']; - final height = defaultVideoTrackSettings['height']; + final double? width = defaultVideoTrackSettings['width'] as double?; + final double? height = defaultVideoTrackSettings['height'] as double?; if (width != null && height != null) { return Size(width, height); @@ -296,9 +300,11 @@ class Camera { /// Throws a [CameraWebException] if the torch mode is not supported /// or the camera has not been initialized or started. void setFlashMode(FlashMode mode) { - final mediaDevices = window?.navigator.mediaDevices; - final supportedConstraints = mediaDevices?.getSupportedConstraints(); - final torchModeSupported = supportedConstraints?[_torchModeKey] ?? false; + final html.MediaDevices? mediaDevices = window?.navigator.mediaDevices; + final Map? supportedConstraints = + mediaDevices?.getSupportedConstraints(); + final bool torchModeSupported = + supportedConstraints?[_torchModeKey] as bool? ?? false; if (!torchModeSupported) { throw CameraWebException( @@ -320,18 +326,19 @@ class Camera { /// Throws a [CameraWebException] if the torch mode is not supported /// or the camera has not been initialized or started. void _setTorchMode({required bool enabled}) { - final videoTracks = stream?.getVideoTracks() ?? []; + final List videoTracks = + stream?.getVideoTracks() ?? []; if (videoTracks.isNotEmpty) { - final defaultVideoTrack = videoTracks.first; + final html.MediaStreamTrack defaultVideoTrack = videoTracks.first; final bool canEnableTorchMode = - defaultVideoTrack.getCapabilities()[_torchModeKey] ?? false; + defaultVideoTrack.getCapabilities()[_torchModeKey] as bool? ?? false; if (canEnableTorchMode) { - defaultVideoTrack.applyConstraints({ - "advanced": [ - { + defaultVideoTrack.applyConstraints({ + 'advanced': [ + { _torchModeKey: enabled, } ] @@ -371,7 +378,7 @@ class Camera { /// Throws a [CameraWebException] if the zoom level is invalid, /// not supported or the camera has not been initialized or started. void setZoomLevel(double zoom) { - final zoomLevelCapability = + final ZoomLevelCapability zoomLevelCapability = _cameraService.getZoomLevelCapabilityForCamera(this); if (zoom < zoomLevelCapability.minimum || @@ -383,9 +390,9 @@ class Camera { ); } - zoomLevelCapability.videoTrack.applyConstraints({ - "advanced": [ - { + zoomLevelCapability.videoTrack.applyConstraints({ + 'advanced': [ + { ZoomLevelCapability.constraintName: zoom, } ] @@ -397,16 +404,19 @@ class Camera { /// Returns null if the camera is missing a video track or /// the video track does not include the facing mode setting. CameraLensDirection? getLensDirection() { - final videoTracks = videoElement.srcObject?.getVideoTracks() ?? []; + final List videoTracks = + videoElement.srcObject?.getVideoTracks() ?? []; if (videoTracks.isEmpty) { return null; } - final defaultVideoTrack = videoTracks.first; - final defaultVideoTrackSettings = defaultVideoTrack.getSettings(); + final html.MediaStreamTrack defaultVideoTrack = videoTracks.first; + final Map defaultVideoTrackSettings = + defaultVideoTrack.getSettings(); - final facingMode = defaultVideoTrackSettings['facingMode']; + final String? facingMode = + defaultVideoTrackSettings['facingMode'] as String?; if (facingMode != null) { return _cameraService.mapFacingModeToLensDirection(facingMode); @@ -432,17 +442,18 @@ class Camera { ); } - mediaRecorder ??= html.MediaRecorder(videoElement.srcObject!, { + mediaRecorder ??= + html.MediaRecorder(videoElement.srcObject!, { 'mimeType': _videoMimeType, }); _videoAvailableCompleter = Completer(); _videoDataAvailableListener = - (event) => _onVideoDataAvailable(event, maxVideoDuration); + (html.Event event) => _onVideoDataAvailable(event, maxVideoDuration); _videoRecordingStoppedListener = - (event) => _onVideoRecordingStopped(event, maxVideoDuration); + (html.Event event) => _onVideoRecordingStopped(event, maxVideoDuration); mediaRecorder!.addEventListener( 'dataavailable', @@ -456,7 +467,7 @@ class Camera { _onVideoRecordingErrorSubscription = mediaRecorder!.onError.listen((html.Event event) { - final error = event as html.ErrorEvent; + final html.ErrorEvent error = event as html.ErrorEvent; if (error != null) { videoRecordingErrorController.add(error); } @@ -474,7 +485,7 @@ class Camera { html.Event event, [ Duration? maxVideoDuration, ]) { - final blob = (event as html.BlobEvent).data; + final html.Blob? blob = (event as html.BlobEvent).data; // Append the recorded part of the video to the list of all video data files. if (blob != null) { @@ -494,11 +505,11 @@ class Camera { ]) async { if (_videoData.isNotEmpty) { // Concatenate all video data files into a single blob. - final videoType = _videoData.first.type; - final videoBlob = blobBuilder(_videoData, videoType); + final String videoType = _videoData.first.type; + final html.Blob videoBlob = blobBuilder(_videoData, videoType); // Create a file containing the video blob. - final file = XFile( + final XFile file = XFile( html.Url.createObjectUrl(videoBlob), mimeType: _videoMimeType, name: videoBlob.hashCode.toString(), @@ -506,7 +517,7 @@ class Camera { // Emit an event containing the recorded video file. videoRecorderController.add( - VideoRecordedEvent(this.textureId, file, maxVideoDuration), + VideoRecordedEvent(textureId, file, maxVideoDuration), ); _videoAvailableCompleter?.complete(file); @@ -594,13 +605,13 @@ class Camera { /// Throws a [CameraWebException] if the browser does not support /// any of the available video mime types. String get _videoMimeType { - const types = [ + const List types = [ 'video/mp4', 'video/webm', ]; return types.firstWhere( - (type) => isVideoTypeSupported(type), + (String type) => isVideoTypeSupported(type), orElse: () => throw CameraWebException( textureId, CameraErrorCode.notSupported, @@ -618,7 +629,7 @@ class Camera { /// Applies default styles to the video [element]. void _applyDefaultVideoStyles(html.VideoElement element) { - final isBackCamera = getLensDirection() == CameraLensDirection.back; + final bool isBackCamera = getLensDirection() == CameraLensDirection.back; // Flip the video horizontally if it is not taken from a back camera. if (!isBackCamera) { diff --git a/packages/camera/camera_web/lib/src/camera_service.dart b/packages/camera/camera_web/lib/src/camera_service.dart index 5ba5c80395cc..f15845cf823b 100644 --- a/packages/camera/camera_web/lib/src/camera_service.dart +++ b/packages/camera/camera_web/lib/src/camera_service.dart @@ -16,7 +16,7 @@ import 'package:flutter/services.dart'; /// obtain the camera stream. class CameraService { // A facing mode constraint name. - static const _facingModeKey = "facingMode"; + static const String _facingModeKey = 'facingMode'; /// The current browser window used to access media devices. @visibleForTesting @@ -32,7 +32,7 @@ class CameraService { CameraOptions options, { int cameraId = 0, }) async { - final mediaDevices = window?.navigator.mediaDevices; + final html.MediaDevices? mediaDevices = window?.navigator.mediaDevices; // Throw a not supported exception if the current browser window // does not support any media devices. @@ -44,7 +44,7 @@ class CameraService { } try { - final constraints = await options.toJson(); + final Map constraints = options.toJson(); return await mediaDevices.getUserMedia(constraints); } on html.DomException catch (e) { switch (e.name) { @@ -120,10 +120,12 @@ class CameraService { ZoomLevelCapability getZoomLevelCapabilityForCamera( Camera camera, ) { - final mediaDevices = window?.navigator.mediaDevices; - final supportedConstraints = mediaDevices?.getSupportedConstraints(); - final zoomLevelSupported = - supportedConstraints?[ZoomLevelCapability.constraintName] ?? false; + final html.MediaDevices? mediaDevices = window?.navigator.mediaDevices; + final Map? supportedConstraints = + mediaDevices?.getSupportedConstraints(); + final bool zoomLevelSupported = + supportedConstraints?[ZoomLevelCapability.constraintName] as bool? ?? + false; if (!zoomLevelSupported) { throw CameraWebException( @@ -133,22 +135,26 @@ class CameraService { ); } - final videoTracks = camera.stream?.getVideoTracks() ?? []; + final List videoTracks = + camera.stream?.getVideoTracks() ?? []; if (videoTracks.isNotEmpty) { - final defaultVideoTrack = videoTracks.first; + final html.MediaStreamTrack defaultVideoTrack = videoTracks.first; /// The zoom level capability is represented by MediaSettingsRange. /// See: https://developer.mozilla.org/en-US/docs/Web/API/MediaSettingsRange - final zoomLevelCapability = defaultVideoTrack - .getCapabilities()[ZoomLevelCapability.constraintName] ?? - {}; + final Object zoomLevelCapability = defaultVideoTrack + .getCapabilities()[ZoomLevelCapability.constraintName] + as Object? ?? + {}; // The zoom level capability is a nested JS object, therefore // we need to access its properties with the js_util library. // See: https://api.dart.dev/stable/2.13.4/dart-js_util/getProperty.html - final minimumZoomLevel = jsUtil.getProperty(zoomLevelCapability, 'min'); - final maximumZoomLevel = jsUtil.getProperty(zoomLevelCapability, 'max'); + final num? minimumZoomLevel = + jsUtil.getProperty(zoomLevelCapability, 'min') as num?; + final num? maximumZoomLevel = + jsUtil.getProperty(zoomLevelCapability, 'max') as num?; if (minimumZoomLevel != null && maximumZoomLevel != null) { return ZoomLevelCapability( @@ -175,7 +181,7 @@ class CameraService { /// Returns a facing mode of the [videoTrack] /// (null if the facing mode is not available). String? getFacingModeForVideoTrack(html.MediaStreamTrack videoTrack) { - final mediaDevices = window?.navigator.mediaDevices; + final html.MediaDevices? mediaDevices = window?.navigator.mediaDevices; // Throw a not supported exception if the current browser window // does not support any media devices. @@ -187,8 +193,10 @@ class CameraService { } // Check if the camera facing mode is supported by the current browser. - final supportedConstraints = mediaDevices.getSupportedConstraints(); - final facingModeSupported = supportedConstraints[_facingModeKey] ?? false; + final Map supportedConstraints = + mediaDevices.getSupportedConstraints(); + final bool facingModeSupported = + supportedConstraints[_facingModeKey] as bool? ?? false; // Return null if the facing mode is not supported. if (!facingModeSupported) { @@ -201,8 +209,8 @@ class CameraService { // // MediaTrackSettings: // https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackSettings - final videoTrackSettings = videoTrack.getSettings(); - final facingMode = videoTrackSettings[_facingModeKey]; + final Map videoTrackSettings = videoTrack.getSettings(); + final String? facingMode = videoTrackSettings[_facingModeKey] as String?; if (facingMode == null) { // If the facing mode does not exist in the video track settings, @@ -220,15 +228,18 @@ class CameraService { return null; } - final videoTrackCapabilities = videoTrack.getCapabilities(); + final Map videoTrackCapabilities = + videoTrack.getCapabilities(); // A list of facing mode capabilities as // the camera may support multiple facing modes. - final facingModeCapabilities = - List.from(videoTrackCapabilities[_facingModeKey] ?? []); + final List facingModeCapabilities = List.from( + (videoTrackCapabilities[_facingModeKey] as List?) + ?.cast() ?? + []); if (facingModeCapabilities.isNotEmpty) { - final facingModeCapability = facingModeCapabilities.first; + final String facingModeCapability = facingModeCapabilities.first; return facingModeCapability; } else { // Return null if there are no facing mode capabilities. @@ -277,16 +288,16 @@ class CameraService { switch (resolutionPreset) { case ResolutionPreset.max: case ResolutionPreset.ultraHigh: - return Size(4096, 2160); + return const Size(4096, 2160); case ResolutionPreset.veryHigh: - return Size(1920, 1080); + return const Size(1920, 1080); case ResolutionPreset.high: - return Size(1280, 720); + return const Size(1280, 720); case ResolutionPreset.medium: - return Size(720, 480); + return const Size(720, 480); case ResolutionPreset.low: default: - return Size(320, 240); + return const Size(320, 240); } } diff --git a/packages/camera/camera_web/lib/src/camera_web.dart b/packages/camera/camera_web/lib/src/camera_web.dart index f183b787fb6c..6f9f10d68f84 100644 --- a/packages/camera/camera_web/lib/src/camera_web.dart +++ b/packages/camera/camera_web/lib/src/camera_web.dart @@ -40,37 +40,41 @@ class CameraPlugin extends CameraPlatform { /// The cameras managed by the [CameraPlugin]. @visibleForTesting - final cameras = {}; - var _textureCounter = 1; + final Map cameras = {}; + int _textureCounter = 1; /// Metadata associated with each camera description. /// Populated in [availableCameras]. @visibleForTesting - final camerasMetadata = {}; + final Map camerasMetadata = + {}; /// The controller used to broadcast different camera events. /// /// It is `broadcast` as multiple controllers may subscribe /// to different stream views of this controller. @visibleForTesting - final cameraEventStreamController = StreamController.broadcast(); + final StreamController cameraEventStreamController = + StreamController.broadcast(); - final _cameraVideoErrorSubscriptions = - >{}; + final Map> + _cameraVideoErrorSubscriptions = >{}; - final _cameraVideoAbortSubscriptions = - >{}; + final Map> + _cameraVideoAbortSubscriptions = >{}; - final _cameraEndedSubscriptions = + final Map> + _cameraEndedSubscriptions = >{}; - final _cameraVideoRecordingErrorSubscriptions = + final Map> + _cameraVideoRecordingErrorSubscriptions = >{}; /// Returns a stream of camera events for the given [cameraId]. Stream _cameraEvents(int cameraId) => cameraEventStreamController.stream - .where((event) => event.cameraId == cameraId); + .where((CameraEvent event) => event.cameraId == cameraId); /// The current browser window used to access media devices. @visibleForTesting @@ -79,8 +83,8 @@ class CameraPlugin extends CameraPlatform { @override Future> availableCameras() async { try { - final mediaDevices = window?.navigator.mediaDevices; - final cameras = []; + final html.MediaDevices? mediaDevices = window?.navigator.mediaDevices; + final List cameras = []; // Throw a not supported exception if the current browser window // does not support any media devices. @@ -92,50 +96,56 @@ class CameraPlugin extends CameraPlatform { } // Request video and audio permissions. - final cameraStream = await _cameraService.getMediaStreamForOptions( - CameraOptions( + final html.MediaStream cameraStream = + await _cameraService.getMediaStreamForOptions( + const CameraOptions( audio: AudioConstraints(enabled: true), ), ); // Release the camera stream used to request video and audio permissions. - cameraStream.getVideoTracks().forEach((videoTrack) => videoTrack.stop()); + cameraStream + .getVideoTracks() + .forEach((html.MediaStreamTrack videoTrack) => videoTrack.stop()); // Request available media devices. - final devices = await mediaDevices.enumerateDevices(); + final List devices = await mediaDevices.enumerateDevices(); // Filter video input devices. - final videoInputDevices = devices + final Iterable videoInputDevices = devices .whereType() - .where((device) => device.kind == MediaDeviceKind.videoInput) + .where((html.MediaDeviceInfo device) => + device.kind == MediaDeviceKind.videoInput) /// The device id property is currently not supported on Internet Explorer: /// https://developer.mozilla.org/en-US/docs/Web/API/MediaDeviceInfo/deviceId#browser_compatibility .where( - (device) => device.deviceId != null && device.deviceId!.isNotEmpty, + (html.MediaDeviceInfo device) => + device.deviceId != null && device.deviceId!.isNotEmpty, ); // Map video input devices to camera descriptions. - for (final videoInputDevice in videoInputDevices) { + for (final html.MediaDeviceInfo videoInputDevice in videoInputDevices) { // Get the video stream for the current video input device // to later use for the available video tracks. - final videoStream = await _getVideoStreamForDevice( + final html.MediaStream videoStream = await _getVideoStreamForDevice( videoInputDevice.deviceId!, ); // Get all video tracks in the video stream // to later extract the lens direction from the first track. - final videoTracks = videoStream.getVideoTracks(); + final List videoTracks = + videoStream.getVideoTracks(); if (videoTracks.isNotEmpty) { // Get the facing mode from the first available video track. - final facingMode = + final String? facingMode = _cameraService.getFacingModeForVideoTrack(videoTracks.first); // Get the lens direction based on the facing mode. // Fallback to the external lens direction // if the facing mode is not available. - final lensDirection = facingMode != null + final CameraLensDirection lensDirection = facingMode != null ? _cameraService.mapFacingModeToLensDirection(facingMode) : CameraLensDirection.external; @@ -148,14 +158,14 @@ class CameraPlugin extends CameraPlatform { // https://developer.mozilla.org/en-US/docs/Web/API/MediaDeviceInfo/label // // Sensor orientation is currently not supported. - final cameraLabel = videoInputDevice.label ?? ''; - final camera = CameraDescription( + final String cameraLabel = videoInputDevice.label ?? ''; + final CameraDescription camera = CameraDescription( name: cameraLabel, lensDirection: lensDirection, sensorOrientation: 0, ); - final cameraMetadata = CameraMetadata( + final CameraMetadata cameraMetadata = CameraMetadata( deviceId: videoInputDevice.deviceId!, facingMode: facingMode, ); @@ -165,7 +175,9 @@ class CameraPlugin extends CameraPlatform { camerasMetadata[camera] = cameraMetadata; // Release the camera stream of the current video input device. - videoTracks.forEach((videoTrack) => videoTrack.stop()); + for (final html.MediaStreamTrack videoTrack in videoTracks) { + videoTrack.stop(); + } } else { // Ignore as no video tracks exist in the current video input device. continue; @@ -198,22 +210,22 @@ class CameraPlugin extends CameraPlatform { ); } - final textureId = _textureCounter++; + final int textureId = _textureCounter++; - final cameraMetadata = camerasMetadata[cameraDescription]!; + final CameraMetadata cameraMetadata = camerasMetadata[cameraDescription]!; - final cameraType = cameraMetadata.facingMode != null + final CameraType? cameraType = cameraMetadata.facingMode != null ? _cameraService.mapFacingModeToCameraType(cameraMetadata.facingMode!) : null; // Use the highest resolution possible // if the resolution preset is not specified. - final videoSize = _cameraService + final Size videoSize = _cameraService .mapResolutionPresetToSize(resolutionPreset ?? ResolutionPreset.max); // Create a camera with the given audio and video constraints. // Sensor orientation is currently not supported. - final camera = Camera( + final Camera camera = Camera( textureId: textureId, cameraService: _cameraService, options: CameraOptions( @@ -247,7 +259,7 @@ class CameraPlugin extends CameraPlatform { ImageFormatGroup imageFormatGroup = ImageFormatGroup.unknown, }) async { try { - final camera = getCamera(cameraId); + final Camera camera = getCamera(cameraId); await camera.initialize(); @@ -258,15 +270,15 @@ class CameraPlugin extends CameraPlatform { // The Event itself (_) doesn't contain information about the actual error. // We need to look at the HTMLMediaElement.error. // See: https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/error - final error = camera.videoElement.error!; - final errorCode = CameraErrorCode.fromMediaError(error); - final errorMessage = + final html.MediaError error = camera.videoElement.error!; + final CameraErrorCode errorCode = CameraErrorCode.fromMediaError(error); + final String? errorMessage = error.message != '' ? error.message : _kDefaultErrorMessage; cameraEventStreamController.add( CameraErrorEvent( cameraId, - 'Error code: ${errorCode}, error message: ${errorMessage}', + 'Error code: $errorCode, error message: $errorMessage', ), ); }); @@ -294,17 +306,17 @@ class CameraPlugin extends CameraPlatform { ); }); - final cameraSize = camera.getVideoSize(); + final Size cameraSize = camera.getVideoSize(); cameraEventStreamController.add( CameraInitializedEvent( cameraId, cameraSize.width, cameraSize.height, - // TODO(camera_web): Add support for exposure mode and point (https://github.com/flutter/flutter/issues/86857). + // TODO(bselwe): Add support for exposure mode and point (https://github.com/flutter/flutter/issues/86857). ExposureMode.auto, false, - // TODO(camera_web): Add support for focus mode and point (https://github.com/flutter/flutter/issues/86858). + // TODO(bselwe): Add support for focus mode and point (https://github.com/flutter/flutter/issues/86858). FocusMode.auto, false, ), @@ -329,7 +341,7 @@ class CameraPlugin extends CameraPlatform { /// [CameraOptions.video] constraints has to be created and initialized. @override Stream onCameraResolutionChanged(int cameraId) { - return const Stream.empty(); + return const Stream.empty(); } @override @@ -349,37 +361,38 @@ class CameraPlugin extends CameraPlatform { @override Stream onDeviceOrientationChanged() { - final orientation = window?.screen?.orientation; + final html.ScreenOrientation? orientation = window?.screen?.orientation; if (orientation != null) { // Create an initial orientation event that emits the device orientation // as soon as subscribed to this stream. - final initialOrientationEvent = html.Event("change"); + final html.Event initialOrientationEvent = html.Event('change'); return orientation.onChange.startWith(initialOrientationEvent).map( (html.Event _) { - final deviceOrientation = _cameraService + final DeviceOrientation deviceOrientation = _cameraService .mapOrientationTypeToDeviceOrientation(orientation.type!); return DeviceOrientationChangedEvent(deviceOrientation); }, ); } else { - return const Stream.empty(); + return const Stream.empty(); } } @override Future lockCaptureOrientation( int cameraId, - DeviceOrientation deviceOrientation, + DeviceOrientation orientation, ) async { try { - final orientation = window?.screen?.orientation; - final documentElement = window?.document.documentElement; + final html.ScreenOrientation? screenOrientation = + window?.screen?.orientation; + final html.Element? documentElement = window?.document.documentElement; - if (orientation != null && documentElement != null) { - final orientationType = _cameraService - .mapDeviceOrientationToOrientationType(deviceOrientation); + if (screenOrientation != null && documentElement != null) { + final String orientationType = + _cameraService.mapDeviceOrientationToOrientationType(orientation); // Full-screen mode may be required to modify the device orientation. // See: https://w3c.github.io/screen-orientation/#interaction-with-fullscreen-api @@ -387,7 +400,7 @@ class CameraPlugin extends CameraPlatform { // This wrapper allows use of both the old and new APIs. dynamic fullScreen() => documentElement.requestFullscreen(); await fullScreen(); - await orientation.lock(orientationType.toString()); + await screenOrientation.lock(orientationType.toString()); } else { throw PlatformException( code: CameraErrorCode.orientationNotSupported.toString(), @@ -402,8 +415,8 @@ class CameraPlugin extends CameraPlatform { @override Future unlockCaptureOrientation(int cameraId) async { try { - final orientation = window?.screen?.orientation; - final documentElement = window?.document.documentElement; + final html.ScreenOrientation? orientation = window?.screen?.orientation; + final html.Element? documentElement = window?.document.documentElement; if (orientation != null && documentElement != null) { orientation.unlock(); @@ -438,7 +451,7 @@ class CameraPlugin extends CameraPlatform { @override Future startVideoRecording(int cameraId, {Duration? maxVideoDuration}) { try { - final camera = getCamera(cameraId); + final Camera camera = getCamera(cameraId); // Add camera's video recording errors to the camera events stream. // The error event fires when the video recording is not allowed or an unsupported @@ -465,7 +478,8 @@ class CameraPlugin extends CameraPlatform { @override Future stopVideoRecording(int cameraId) async { try { - final videoRecording = await getCamera(cameraId).stopVideoRecording(); + final XFile videoRecording = + await getCamera(cameraId).stopVideoRecording(); await _cameraVideoRecordingErrorSubscriptions[cameraId]?.cancel(); return videoRecording; } on html.DomException catch (e) { @@ -641,7 +655,7 @@ class CameraPlugin extends CameraPlatform { String deviceId, ) { // Create camera options with the desired device id. - final cameraOptions = CameraOptions( + final CameraOptions cameraOptions = CameraOptions( video: VideoConstraints(deviceId: deviceId), ); @@ -653,7 +667,7 @@ class CameraPlugin extends CameraPlatform { /// Throws a [CameraException] if the camera does not exist. @visibleForTesting Camera getCamera(int cameraId) { - final camera = cameras[cameraId]; + final Camera? camera = cameras[cameraId]; if (camera == null) { throw PlatformException( diff --git a/packages/camera/camera_web/lib/src/shims/dart_js_util.dart b/packages/camera/camera_web/lib/src/shims/dart_js_util.dart index 6601bec6f529..7d766e8c269e 100644 --- a/packages/camera/camera_web/lib/src/shims/dart_js_util.dart +++ b/packages/camera/camera_web/lib/src/shims/dart_js_util.dart @@ -10,5 +10,6 @@ class JsUtil { bool hasProperty(Object o, Object name) => js_util.hasProperty(o, name); /// Returns the value of the property [name] in the object [o]. - dynamic getProperty(Object o, Object name) => js_util.getProperty(o, name); + dynamic getProperty(Object o, Object name) => + js_util.getProperty(o, name); } diff --git a/packages/camera/camera_web/lib/src/shims/dart_ui.dart b/packages/camera/camera_web/lib/src/shims/dart_ui.dart index 5eacec5fe867..3a32721cb9c8 100644 --- a/packages/camera/camera_web/lib/src/shims/dart_ui.dart +++ b/packages/camera/camera_web/lib/src/shims/dart_ui.dart @@ -5,6 +5,6 @@ /// This file shims dart:ui in web-only scenarios, getting rid of the need to /// suppress analyzer warnings. -// TODO(flutter/flutter#55000) Remove this file once web-only dart:ui APIs -// are exposed from a dedicated place. +// TODO(ditman): Remove this file once web-only dart:ui APIs are exposed from +// a dedicated place. https://github.com/flutter/flutter/issues/55000 export 'dart_ui_fake.dart' if (dart.library.html) 'dart_ui_real.dart'; diff --git a/packages/camera/camera_web/lib/src/shims/dart_ui_fake.dart b/packages/camera/camera_web/lib/src/shims/dart_ui_fake.dart index f2862af8b704..8757ca22be17 100644 --- a/packages/camera/camera_web/lib/src/shims/dart_ui_fake.dart +++ b/packages/camera/camera_web/lib/src/shims/dart_ui_fake.dart @@ -7,13 +7,18 @@ import 'dart:html' as html; // Fake interface for the logic that this package needs from (web-only) dart:ui. // This is conditionally exported so the analyzer sees these methods as available. +// ignore_for_file: avoid_classes_with_only_static_members +// ignore_for_file: camel_case_types + /// Shim for web_ui engine.PlatformViewRegistry /// https://github.com/flutter/engine/blob/master/lib/web_ui/lib/ui.dart#L62 class platformViewRegistry { /// Shim for registerViewFactory /// https://github.com/flutter/engine/blob/master/lib/web_ui/lib/ui.dart#L72 - static registerViewFactory( - String viewTypeId, html.Element Function(int viewId) viewFactory) {} + static bool registerViewFactory( + String viewTypeId, html.Element Function(int viewId) viewFactory) { + return false; + } } /// Shim for web_ui engine.AssetManager. @@ -21,7 +26,7 @@ class platformViewRegistry { class webOnlyAssetManager { /// Shim for getAssetUrl. /// https://github.com/flutter/engine/blob/master/lib/web_ui/lib/src/engine/assets.dart#L45 - static getAssetUrl(String asset) {} + static String getAssetUrl(String asset) => ''; } /// Signature of callbacks that have no arguments and return no data. diff --git a/packages/camera/camera_web/lib/src/types/camera_error_code.dart b/packages/camera/camera_web/lib/src/types/camera_error_code.dart index f70925b4bede..2e8a49b63873 100644 --- a/packages/camera/camera_web/lib/src/types/camera_error_code.dart +++ b/packages/camera/camera_web/lib/src/types/camera_error_code.dart @@ -81,15 +81,15 @@ class CameraErrorCode { static CameraErrorCode fromMediaError(html.MediaError error) { switch (error.code) { case html.MediaError.MEDIA_ERR_ABORTED: - return CameraErrorCode._('mediaErrorAborted'); + return const CameraErrorCode._('mediaErrorAborted'); case html.MediaError.MEDIA_ERR_NETWORK: - return CameraErrorCode._('mediaErrorNetwork'); + return const CameraErrorCode._('mediaErrorNetwork'); case html.MediaError.MEDIA_ERR_DECODE: - return CameraErrorCode._('mediaErrorDecode'); + return const CameraErrorCode._('mediaErrorDecode'); case html.MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED: - return CameraErrorCode._('mediaErrorSourceNotSupported'); + return const CameraErrorCode._('mediaErrorSourceNotSupported'); default: - return CameraErrorCode._('mediaErrorUnknown'); + return const CameraErrorCode._('mediaErrorUnknown'); } } } diff --git a/packages/camera/camera_web/lib/src/types/camera_metadata.dart b/packages/camera/camera_web/lib/src/types/camera_metadata.dart index c9998e58a52c..c42dd3ad8b75 100644 --- a/packages/camera/camera_web/lib/src/types/camera_metadata.dart +++ b/packages/camera/camera_web/lib/src/types/camera_metadata.dart @@ -4,8 +4,11 @@ import 'dart:ui' show hashValues; +import 'package:flutter/foundation.dart'; + /// Metadata used along the camera description /// to store additional web-specific camera details. +@immutable class CameraMetadata { /// Creates a new instance of [CameraMetadata] /// with the given [deviceId] and [facingMode]. @@ -25,7 +28,9 @@ class CameraMetadata { @override bool operator ==(Object other) { - if (identical(this, other)) return true; + if (identical(this, other)) { + return true; + } return other is CameraMetadata && other.deviceId == deviceId && diff --git a/packages/camera/camera_web/lib/src/types/camera_options.dart b/packages/camera/camera_web/lib/src/types/camera_options.dart index 2a4cdbf15348..8fa40bdc1bb8 100644 --- a/packages/camera/camera_web/lib/src/types/camera_options.dart +++ b/packages/camera/camera_web/lib/src/types/camera_options.dart @@ -4,6 +4,8 @@ import 'dart:ui' show hashValues; +import 'package:flutter/foundation.dart'; + /// Options used to create a camera with the given /// [audio] and [video] media constraints. /// @@ -12,6 +14,7 @@ import 'dart:ui' show hashValues; /// with audio and video tracks containing the requested types of media. /// /// https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamConstraints +@immutable class CameraOptions { /// Creates a new instance of [CameraOptions] /// with the given [audio] and [video] constraints. @@ -29,7 +32,7 @@ class CameraOptions { /// Converts the current instance to a Map. Map toJson() { - return { + return { 'audio': audio.toJson(), 'video': video.toJson(), }; @@ -37,7 +40,9 @@ class CameraOptions { @override bool operator ==(Object other) { - if (identical(this, other)) return true; + if (identical(this, other)) { + return true; + } return other is CameraOptions && other.audio == audio && @@ -51,6 +56,7 @@ class CameraOptions { /// Indicates whether the audio track is requested. /// /// By default, the audio track is not requested. +@immutable class AudioConstraints { /// Creates a new instance of [AudioConstraints] /// with the given [enabled] constraint. @@ -64,7 +70,9 @@ class AudioConstraints { @override bool operator ==(Object other) { - if (identical(this, other)) return true; + if (identical(this, other)) { + return true; + } return other is AudioConstraints && other.enabled == enabled; } @@ -75,6 +83,7 @@ class AudioConstraints { /// Defines constraints that the video track must have /// to be considered acceptable. +@immutable class VideoConstraints { /// Creates a new instance of [VideoConstraints] /// with the given constraints. @@ -99,19 +108,29 @@ class VideoConstraints { /// Converts the current instance to a Map. Object toJson() { - final json = {}; - - if (width != null) json['width'] = width!.toJson(); - if (height != null) json['height'] = height!.toJson(); - if (facingMode != null) json['facingMode'] = facingMode!.toJson(); - if (deviceId != null) json['deviceId'] = {'exact': deviceId!}; + final Map json = {}; + + if (width != null) { + json['width'] = width!.toJson(); + } + if (height != null) { + json['height'] = height!.toJson(); + } + if (facingMode != null) { + json['facingMode'] = facingMode!.toJson(); + } + if (deviceId != null) { + json['deviceId'] = {'exact': deviceId!}; + } return json; } @override bool operator ==(Object other) { - if (identical(this, other)) return true; + if (identical(this, other)) { + return true; + } return other is VideoConstraints && other.facingMode == facingMode && @@ -146,16 +165,17 @@ class CameraType { } /// Indicates the direction in which the desired camera should be pointing. +@immutable class FacingModeConstraint { - /// Creates a new instance of [FacingModeConstraint] - /// with the given [ideal] and [exact] constraints. - const FacingModeConstraint._({this.ideal, this.exact}); - /// Creates a new instance of [FacingModeConstraint] /// with [ideal] constraint set to [type]. factory FacingModeConstraint(CameraType type) => FacingModeConstraint._(ideal: type); + /// Creates a new instance of [FacingModeConstraint] + /// with the given [ideal] and [exact] constraints. + const FacingModeConstraint._({this.ideal, this.exact}); + /// Creates a new instance of [FacingModeConstraint] /// with [exact] constraint set to [type]. factory FacingModeConstraint.exact(CameraType type) => @@ -174,8 +194,8 @@ class FacingModeConstraint { final CameraType? exact; /// Converts the current instance to a Map. - Object? toJson() { - return { + Object toJson() { + return { if (ideal != null) 'ideal': ideal.toString(), if (exact != null) 'exact': exact.toString(), }; @@ -183,7 +203,9 @@ class FacingModeConstraint { @override bool operator ==(Object other) { - if (identical(this, other)) return true; + if (identical(this, other)) { + return true; + } return other is FacingModeConstraint && other.ideal == ideal && @@ -200,6 +222,7 @@ class FacingModeConstraint { /// The obtained video track will have a size between [minimum] and [maximum] /// with ideally a size of [ideal]. The size is determined by /// the capabilities of the hardware and the other specified constraints. +@immutable class VideoSizeConstraint { /// Creates a new instance of [VideoSizeConstraint] with the given /// [minimum], [ideal] and [maximum] constraints. @@ -221,18 +244,26 @@ class VideoSizeConstraint { /// Converts the current instance to a Map. Object toJson() { - final json = {}; - - if (ideal != null) json['ideal'] = ideal; - if (minimum != null) json['min'] = minimum; - if (maximum != null) json['max'] = maximum; + final Map json = {}; + + if (ideal != null) { + json['ideal'] = ideal; + } + if (minimum != null) { + json['min'] = minimum; + } + if (maximum != null) { + json['max'] = maximum; + } return json; } @override bool operator ==(Object other) { - if (identical(this, other)) return true; + if (identical(this, other)) { + return true; + } return other is VideoSizeConstraint && other.minimum == minimum && diff --git a/packages/camera/camera_web/lib/src/types/media_device_kind.dart b/packages/camera/camera_web/lib/src/types/media_device_kind.dart index 1f746808df9e..3607bb260f1e 100644 --- a/packages/camera/camera_web/lib/src/types/media_device_kind.dart +++ b/packages/camera/camera_web/lib/src/types/media_device_kind.dart @@ -7,11 +7,11 @@ /// See: https://developer.mozilla.org/en-US/docs/Web/API/MediaDeviceInfo/kind abstract class MediaDeviceKind { /// A video input media device kind. - static const videoInput = 'videoinput'; + static const String videoInput = 'videoinput'; /// An audio input media device kind. - static const audioInput = 'audioinput'; + static const String audioInput = 'audioinput'; /// An audio output media device kind. - static const audioOutput = 'audiooutput'; + static const String audioOutput = 'audiooutput'; } diff --git a/packages/camera/camera_web/lib/src/types/zoom_level_capability.dart b/packages/camera/camera_web/lib/src/types/zoom_level_capability.dart index ace57140d956..9a868d2bc0dc 100644 --- a/packages/camera/camera_web/lib/src/types/zoom_level_capability.dart +++ b/packages/camera/camera_web/lib/src/types/zoom_level_capability.dart @@ -5,13 +5,16 @@ import 'dart:html' as html; import 'dart:ui' show hashValues; +import 'package:flutter/foundation.dart'; + /// The possible range of values for the zoom level configurable /// on the camera video track. +@immutable class ZoomLevelCapability { /// Creates a new instance of [ZoomLevelCapability] with the given /// zoom level range of [minimum] to [maximum] configurable /// on the [videoTrack]. - ZoomLevelCapability({ + const ZoomLevelCapability({ required this.minimum, required this.maximum, required this.videoTrack, @@ -19,7 +22,7 @@ class ZoomLevelCapability { /// The zoom level constraint name. /// See: https://w3c.github.io/mediacapture-image/#dom-mediatracksupportedconstraints-zoom - static const constraintName = "zoom"; + static const String constraintName = 'zoom'; /// The minimum zoom level. final double minimum; @@ -32,7 +35,9 @@ class ZoomLevelCapability { @override bool operator ==(Object other) { - if (identical(this, other)) return true; + if (identical(this, other)) { + return true; + } return other is ZoomLevelCapability && other.minimum == minimum && diff --git a/packages/camera/camera_web/pubspec.yaml b/packages/camera/camera_web/pubspec.yaml index 2839710af2f5..6d6f110157bc 100644 --- a/packages/camera/camera_web/pubspec.yaml +++ b/packages/camera/camera_web/pubspec.yaml @@ -2,7 +2,7 @@ name: camera_web description: A Flutter plugin for getting information about and controlling the camera on Web. repository: https://github.com/flutter/plugins/tree/main/packages/camera/camera_web issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 -version: 0.2.1+2 +version: 0.2.1+3 environment: sdk: ">=2.12.0 <3.0.0" @@ -22,7 +22,6 @@ dependencies: sdk: flutter flutter_web_plugins: sdk: flutter - pedantic: ^1.11.1 stream_transform: ^2.0.0 dev_dependencies: diff --git a/script/configs/custom_analysis.yaml b/script/configs/custom_analysis.yaml index 7e4d3832056e..d434b5d56662 100644 --- a/script/configs/custom_analysis.yaml +++ b/script/configs/custom_analysis.yaml @@ -11,7 +11,6 @@ # TODO(ecosystem): Remove everything from this list. See: # https://github.com/flutter/flutter/issues/76229 -- camera/camera_web - google_maps_flutter/google_maps_flutter - google_maps_flutter/google_maps_flutter_platform_interface - google_maps_flutter/google_maps_flutter_web