Skip to content

Commit 17188b7

Browse files
[camera] Clean up maxDuration code (flutter#7039)
`maxVideoDuration` was added to the platform interface a long time ago in preparation for adding that feature, but the other parts were never landed. The previous state was: - It has never been implemented for iOS or Android - It has never been settable from the app-facing package, so is always null unless someone uses the platform interface directly, which we don't consider a supported use case. - It cannot be implemented in the CameraX Android implementation. - It was implemented for Windows and web because when those platforms were added much later, nobody realized that the parameter was unused. There is no compelling need for this feature, as clients of the plugin can simply set their own timer to stop recording. Given that, rather than leave the confusing partial state, this marks the option as deprecated at the platform interface layer and warns implementers that it can be ignored. It also removes the implementations from Windows and web in order to reduce implementation complexity, since that code was not reachable from the app-facing API. This does not consider the Windows and web changes to be breaking, even though they arguably could be, because we do not expect clients to be calling platform interface methods directly. Fixes flutter#150959
1 parent 007ec66 commit 17188b7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+103
-666
lines changed

packages/camera/camera/test/camera_image_stream_test.dart

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -215,11 +215,10 @@ class MockStreamingCameraPlatform extends MockCameraPlatform {
215215
}
216216

217217
@override
218-
Future<XFile> startVideoRecording(int cameraId,
219-
{Duration? maxVideoDuration}) {
218+
Future<void> startVideoRecording(int cameraId, {Duration? maxVideoDuration}) {
220219
streamCallLog.add('startVideoRecording');
221-
return super
222-
.startVideoRecording(cameraId, maxVideoDuration: maxVideoDuration);
220+
// Ignore maxVideoDuration, as it is unimplemented and deprecated.
221+
return super.startVideoRecording(cameraId);
223222
}
224223

225224
@override

packages/camera/camera/test/camera_test.dart

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1511,14 +1511,17 @@ class MockCameraPlatform extends Mock
15111511
super.noSuchMethod(Invocation.method(#prepareForVideoRecording, null));
15121512

15131513
@override
1514-
Future<XFile> startVideoRecording(int cameraId,
1515-
{Duration? maxVideoDuration}) =>
1516-
Future<XFile>.value(mockVideoRecordingXFile);
1514+
Future<void> startVideoRecording(int cameraId, {Duration? maxVideoDuration}) {
1515+
// Ignore maxVideoDuration, as it is unimplemented and deprecated.
1516+
return startVideoCapturing(VideoCaptureOptions(cameraId));
1517+
}
1518+
1519+
@override
1520+
Future<void> startVideoCapturing(VideoCaptureOptions options) async {}
15171521

15181522
@override
1519-
Future<void> startVideoCapturing(VideoCaptureOptions options) {
1520-
return startVideoRecording(options.cameraId,
1521-
maxVideoDuration: options.maxDuration);
1523+
Future<XFile> stopVideoRecording(int cameraId) {
1524+
return Future<XFile>.value(mockVideoRecordingXFile);
15221525
}
15231526

15241527
@override

packages/camera/camera_android/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.10.9+8
2+
3+
* Removes unused code related to `maxVideoDuration`.
4+
15
## 0.10.9+7
26

37
* Updates Android Gradle plugin to 8.5.0.

packages/camera/camera_android/lib/src/android_camera.dart

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -267,8 +267,8 @@ class AndroidCamera extends CameraPlatform {
267267
@override
268268
Future<void> startVideoRecording(int cameraId,
269269
{Duration? maxVideoDuration}) async {
270-
return startVideoCapturing(
271-
VideoCaptureOptions(cameraId, maxDuration: maxVideoDuration));
270+
// Ignore maxVideoDuration, as it is unimplemented and deprecated.
271+
return startVideoCapturing(VideoCaptureOptions(cameraId));
272272
}
273273

274274
@override
@@ -277,7 +277,6 @@ class AndroidCamera extends CameraPlatform {
277277
'startVideoRecording',
278278
<String, dynamic>{
279279
'cameraId': options.cameraId,
280-
'maxVideoDuration': options.maxDuration?.inMilliseconds,
281280
'enableStream': options.streamCallback != null,
282281
},
283282
);
@@ -626,15 +625,6 @@ class AndroidCamera extends CameraPlatform {
626625
cameraEventStreamController.add(CameraClosingEvent(
627626
cameraId,
628627
));
629-
case 'video_recorded':
630-
final Map<String, Object?> arguments = _getArgumentDictionary(call);
631-
cameraEventStreamController.add(VideoRecordedEvent(
632-
cameraId,
633-
XFile(arguments['path']! as String),
634-
arguments['maxVideoDuration'] != null
635-
? Duration(milliseconds: arguments['maxVideoDuration']! as int)
636-
: null,
637-
));
638628
case 'error':
639629
final Map<String, Object?> arguments = _getArgumentDictionary(call);
640630
cameraEventStreamController.add(CameraErrorEvent(

packages/camera/camera_android/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ description: Android implementation of the camera plugin.
33
repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_android
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22
55

6-
version: 0.10.9+7
6+
version: 0.10.9+8
77

88
environment:
99
sdk: ^3.4.0

packages/camera/camera_android/test/android_camera_test.dart

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -636,31 +636,6 @@ void main() {
636636
expect(channel.log, <Matcher>[
637637
isMethodCall('startVideoRecording', arguments: <String, Object?>{
638638
'cameraId': cameraId,
639-
'maxVideoDuration': null,
640-
'enableStream': false,
641-
}),
642-
]);
643-
});
644-
645-
test('Should pass maxVideoDuration when starting recording a video',
646-
() async {
647-
// Arrange
648-
final MethodChannelMock channel = MethodChannelMock(
649-
channelName: _channelName,
650-
methods: <String, dynamic>{'startVideoRecording': null},
651-
);
652-
653-
// Act
654-
await camera.startVideoRecording(
655-
cameraId,
656-
maxVideoDuration: const Duration(seconds: 10),
657-
);
658-
659-
// Assert
660-
expect(channel.log, <Matcher>[
661-
isMethodCall('startVideoRecording', arguments: <String, Object?>{
662-
'cameraId': cameraId,
663-
'maxVideoDuration': 10000,
664639
'enableStream': false,
665640
}),
666641
]);
@@ -685,7 +660,6 @@ void main() {
685660
expect(channel.log, <Matcher>[
686661
isMethodCall('startVideoRecording', arguments: <String, Object?>{
687662
'cameraId': cameraId,
688-
'maxVideoDuration': null,
689663
'enableStream': true,
690664
}),
691665
]);

packages/camera/camera_android_camerax/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 0.6.7+1
2+
3+
* Updates README to remove references to `maxVideoDuration`, as it was never
4+
visible to app-facing clients, nor was it implemented in `camera_android`.
5+
16
## 0.6.7
27

38
* Updates AGP version to 8.5.0.

packages/camera/camera_android_camerax/README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,12 @@ due to this not currently being supported by CameraX.
4444
the plugin will fall back to target 480p (`ResolutionPreset.medium`) if configured with
4545
`ResolutionPreset.low`.
4646

47-
### Setting maximum duration and stream options for video capture
47+
### Setting stream options for video capture
4848

4949
Calling `startVideoCapturing` with `VideoCaptureOptions` configured with
50-
`maxVideoDuration` and `streamOptions` is currently unsupported do to the
51-
limitations of the CameraX library and the platform interface, respectively,
52-
and thus, those parameters will silently be ignored.
50+
`streamOptions` is currently unsupported do to
51+
limitations of the platform interface,
52+
and thus that parameter will silently be ignored.
5353

5454
## What requires Android permissions
5555

packages/camera/camera_android_camerax/lib/src/android_camera_camerax.dart

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,16 +1013,15 @@ class AndroidCameraCameraX extends CameraPlatform {
10131013
@override
10141014
Future<void> startVideoRecording(int cameraId,
10151015
{Duration? maxVideoDuration}) async {
1016-
return startVideoCapturing(
1017-
VideoCaptureOptions(cameraId, maxDuration: maxVideoDuration));
1016+
// Ignore maxVideoDuration, as it is unimplemented and deprecated.
1017+
return startVideoCapturing(VideoCaptureOptions(cameraId));
10181018
}
10191019

10201020
/// Starts a video recording and/or streaming session.
10211021
///
10221022
/// Please see [VideoCaptureOptions] for documentation on the
1023-
/// configuration options. Currently, maxVideoDuration and streamOptions
1024-
/// are unsupported due to the limitations of CameraX and the platform
1025-
/// interface, respectively.
1023+
/// configuration options. Currently streamOptions are unsupported due to
1024+
/// limitations of the platform interface.
10261025
@override
10271026
Future<void> startVideoCapturing(VideoCaptureOptions options) async {
10281027
if (recording != null) {

packages/camera/camera_android_camerax/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: camera_android_camerax
22
description: Android implementation of the camera plugin using the CameraX library.
33
repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_android_camerax
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22
5-
version: 0.6.7
5+
version: 0.6.7+1
66

77
environment:
88
sdk: ^3.4.0

packages/camera/camera_avfoundation/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.9.16+3
2+
3+
* Removes unused `maxVideoDuration` code.
4+
15
## 0.9.16+2
26

37
* Fixes regression taking a picture in torch mode.

packages/camera/camera_avfoundation/lib/src/avfoundation_camera.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,8 @@ class AVFoundationCamera extends CameraPlatform {
207207
@override
208208
Future<void> startVideoRecording(int cameraId,
209209
{Duration? maxVideoDuration}) async {
210-
return startVideoCapturing(
211-
VideoCaptureOptions(cameraId, maxDuration: maxVideoDuration));
210+
// Ignore maxVideoDuration, as it is unimplemented and deprecated.
211+
return startVideoCapturing(VideoCaptureOptions(cameraId));
212212
}
213213

214214
@override

packages/camera/camera_avfoundation/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: camera_avfoundation
22
description: iOS implementation of the camera plugin.
33
repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_avfoundation
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22
5-
version: 0.9.16+2
5+
version: 0.9.16+3
66

77
environment:
88
sdk: ^3.2.3

packages/camera/camera_web/CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
## NEXT
1+
## 0.3.4
22

3+
* Removes `maxVideoDuration`/`maxDuration`, as the feature was never exposed at
4+
the app-facing package level, and is deprecated at the platform interface
5+
level.
36
* Updates minimum supported SDK version to Flutter 3.16/Dart 3.2.
47

58
## 0.3.3

packages/camera/camera_web/example/integration_test/camera_test.dart

Lines changed: 1 addition & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,60 +1069,7 @@ void main() {
10691069
verify(mediaRecorder.start).called(1);
10701070
});
10711071

1072-
testWidgets(
1073-
'starts a video recording '
1074-
'with maxVideoDuration', (WidgetTester tester) async {
1075-
const Duration maxVideoDuration = Duration(hours: 1);
1076-
1077-
final Camera camera = Camera(
1078-
textureId: 1,
1079-
cameraService: cameraService,
1080-
)
1081-
..mediaRecorder = mediaRecorder
1082-
..isVideoTypeSupported = isVideoTypeSupported;
1083-
1084-
await camera.initialize();
1085-
await camera.play();
1086-
1087-
await camera.startVideoRecording(maxVideoDuration: maxVideoDuration);
1088-
1089-
verify(() => mediaRecorder.start(maxVideoDuration.inMilliseconds))
1090-
.called(1);
1091-
});
1092-
10931072
group('throws a CameraWebException', () {
1094-
testWidgets(
1095-
'with notSupported error '
1096-
'when maxVideoDuration is 0 milliseconds or less',
1097-
(WidgetTester tester) async {
1098-
final Camera camera = Camera(
1099-
textureId: 1,
1100-
cameraService: cameraService,
1101-
)
1102-
..mediaRecorder = mediaRecorder
1103-
..isVideoTypeSupported = isVideoTypeSupported;
1104-
1105-
await camera.initialize();
1106-
await camera.play();
1107-
1108-
expect(
1109-
() => camera.startVideoRecording(maxVideoDuration: Duration.zero),
1110-
throwsA(
1111-
isA<CameraWebException>()
1112-
.having(
1113-
(CameraWebException e) => e.cameraId,
1114-
'cameraId',
1115-
textureId,
1116-
)
1117-
.having(
1118-
(CameraWebException e) => e.code,
1119-
'code',
1120-
CameraErrorCode.notSupported,
1121-
),
1122-
),
1123-
);
1124-
});
1125-
11261073
testWidgets(
11271074
'with notSupported error '
11281075
'when no video types are supported', (WidgetTester tester) async {
@@ -1346,46 +1293,6 @@ void main() {
13461293
});
13471294
});
13481295

1349-
group('on video data available', () {
1350-
late void Function(Event) videoDataAvailableListener;
1351-
1352-
setUp(() {
1353-
when(
1354-
() => mediaRecorder.addEventListener('dataavailable', any()),
1355-
).thenAnswer((Invocation invocation) {
1356-
videoDataAvailableListener =
1357-
invocation.positionalArguments[1] as void Function(Event);
1358-
});
1359-
});
1360-
1361-
testWidgets(
1362-
'stops a video recording '
1363-
'if maxVideoDuration is given and '
1364-
'the recording was not stopped manually',
1365-
(WidgetTester tester) async {
1366-
const Duration maxVideoDuration = Duration(hours: 1);
1367-
1368-
final Camera camera = Camera(
1369-
textureId: 1,
1370-
cameraService: cameraService,
1371-
)
1372-
..mediaRecorder = mediaRecorder
1373-
..isVideoTypeSupported = isVideoTypeSupported;
1374-
1375-
await camera.initialize();
1376-
await camera.play();
1377-
await camera.startVideoRecording(maxVideoDuration: maxVideoDuration);
1378-
1379-
when(() => mediaRecorder.state).thenReturn('recording');
1380-
1381-
videoDataAvailableListener(FakeBlobEvent(Blob(<Object>[])));
1382-
1383-
await Future<void>.microtask(() {});
1384-
1385-
verify(mediaRecorder.stop).called(1);
1386-
});
1387-
});
1388-
13891296
group('on video recording stopped', () {
13901297
late void Function(Event) videoRecordingStoppedListener;
13911298

@@ -1543,7 +1450,6 @@ void main() {
15431450
testWidgets(
15441451
'emits a VideoRecordedEvent '
15451452
'when a video recording is created', (WidgetTester tester) async {
1546-
const Duration maxVideoDuration = Duration(hours: 1);
15471453
const String supportedVideoType = 'video/webm';
15481454

15491455
final MockMediaRecorder mediaRecorder = MockMediaRecorder();
@@ -1580,7 +1486,7 @@ void main() {
15801486
final StreamQueue<VideoRecordedEvent> streamQueue =
15811487
StreamQueue<VideoRecordedEvent>(camera.onVideoRecordedEvent);
15821488

1583-
await camera.startVideoRecording(maxVideoDuration: maxVideoDuration);
1489+
await camera.startVideoRecording();
15841490

15851491
Blob? finalVideo;
15861492
camera.blobBuilder = (List<Blob> blobs, String videoType) {
@@ -1614,11 +1520,6 @@ void main() {
16141520
'name',
16151521
finalVideo.hashCode.toString(),
16161522
),
1617-
)
1618-
.having(
1619-
(VideoRecordedEvent e) => e.maxVideoDuration,
1620-
'maxVideoDuration',
1621-
maxVideoDuration,
16221523
),
16231524
),
16241525
);

packages/camera/camera_web/example/integration_test/camera_web_test.dart

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2839,9 +2839,7 @@ void main() {
28392839
.thenAnswer((Invocation _) => const Stream<ErrorEvent>.empty());
28402840

28412841
when(
2842-
() => camera.startVideoRecording(
2843-
maxVideoDuration: any(named: 'maxVideoDuration'),
2844-
),
2842+
() => camera.startVideoRecording(),
28452843
).thenThrow(exception);
28462844

28472845
final Stream<CameraErrorEvent> eventStream =

0 commit comments

Comments
 (0)