From fc9055e26a34b23c7114092c138f0ef910e9f905 Mon Sep 17 00:00:00 2001 From: Jamiu Akinyemi Date: Mon, 29 Sep 2025 15:11:56 +0100 Subject: [PATCH 1/6] checkout unmodified files to upstream main --- packages/camera/camera/CHANGELOG.md | 3 ++- .../example/integration_test/camera_test.dart | 27 ++++++++++++++++--- packages/camera/camera/example/pubspec.yaml | 5 ++++ .../camera/lib/src/camera_controller.dart | 17 +++++++++++- packages/camera/camera/pubspec.yaml | 6 ++++- .../camera/test/camera_preview_test.dart | 1 + 6 files changed, 53 insertions(+), 6 deletions(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index fae21094cd74..74d64055d31c 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,5 +1,6 @@ -## NEXT +## 0.11.2+1 +* Fixes flutter/flutter#148013: setDescriptionWhileRecording with android camerax. * Updates minimum supported SDK version to Flutter 3.29/Dart 3.7. * Updates README to reflect that only Android API 24+ is supported. diff --git a/packages/camera/camera/example/integration_test/camera_test.dart b/packages/camera/camera/example/integration_test/camera_test.dart index 172319531de5..19909e55a89b 100644 --- a/packages/camera/camera/example/integration_test/camera_test.dart +++ b/packages/camera/camera/example/integration_test/camera_test.dart @@ -260,7 +260,9 @@ void main() { return completer.future; } - testWidgets('Set description while recording', (WidgetTester tester) async { + testWidgets('Set description while recording captures full video', ( + WidgetTester tester, + ) async { final List cameras = await availableCameras(); if (cameras.length < 2) { return; @@ -269,7 +271,6 @@ void main() { final CameraController controller = CameraController( cameras[0], ResolutionPreset.low, - enableAudio: false, ); await controller.initialize(); @@ -278,7 +279,27 @@ void main() { await controller.startVideoRecording(); await controller.setDescription(cameras[1]); - expect(controller.description, cameras[1]); + await tester.pumpAndSettle(const Duration(seconds: 4)); + + await controller.setDescription(cameras[0]); + + await tester.pumpAndSettle(const Duration(seconds: 1)); + + final XFile file = await controller.stopVideoRecording(); + + final File videoFile = File(file.path); + final VideoPlayerController videoController = VideoPlayerController.file( + videoFile, + ); + await videoController.initialize(); + final int duration = videoController.value.duration.inMilliseconds; + await videoController.dispose(); + + expect( + duration, + greaterThanOrEqualTo(const Duration(seconds: 4).inMilliseconds), + ); + await controller.dispose(); }); testWidgets('Set description', (WidgetTester tester) async { diff --git a/packages/camera/camera/example/pubspec.yaml b/packages/camera/camera/example/pubspec.yaml index e268268e3204..f6f1f2c098aa 100644 --- a/packages/camera/camera/example/pubspec.yaml +++ b/packages/camera/camera/example/pubspec.yaml @@ -31,3 +31,8 @@ dev_dependencies: flutter: uses-material-design: true +# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. +# See https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#changing-federated-plugins +dependency_overrides: + camera_android_camerax: {path: ../../../../packages/camera/camera_android_camerax} + camera_platform_interface: {path: ../../../../packages/camera/camera_platform_interface} diff --git a/packages/camera/camera/lib/src/camera_controller.dart b/packages/camera/camera/lib/src/camera_controller.dart index 4ecc6aae971a..3c3a803be0e9 100644 --- a/packages/camera/camera/lib/src/camera_controller.dart +++ b/packages/camera/camera/lib/src/camera_controller.dart @@ -439,6 +439,10 @@ class CameraController extends ValueNotifier { /// Sets the description of the camera. /// + /// On Android, you must start the recording with [startVideoRecording] + /// with `enablePersistentRecording` set to `true` + /// to avoid cancelling any active recording. + /// /// Throws a [CameraException] if setting the description fails. Future setDescription(CameraDescription description) async { if (value.isRecordingVideo) { @@ -554,8 +558,15 @@ class CameraController extends ValueNotifier { /// /// The video is returned as a [XFile] after calling [stopVideoRecording]. /// Throws a [CameraException] if the capture fails. + /// + /// `enablePersistentRecording` parameter configures the recording to be a persistent recording. + /// A persistent recording can only be stopped by explicitly calling [stopVideoRecording] + /// and will ignore events that would normally cause recording to stop, + /// such as lifecycle events or explicit calls to [setDescription] while recording is in progress. + /// Currently a no-op on platforms other than Android. Future startVideoRecording({ onLatestImageAvailable? onAvailable, + bool enablePersistentRecording = true, }) async { _throwIfNotInitialized('startVideoRecording'); if (value.isRecordingVideo) { @@ -574,7 +585,11 @@ class CameraController extends ValueNotifier { try { await CameraPlatform.instance.startVideoCapturing( - VideoCaptureOptions(_cameraId, streamCallback: streamCallback), + VideoCaptureOptions( + _cameraId, + streamCallback: streamCallback, + enablePersistentRecording: enablePersistentRecording, + ), ); value = value.copyWith( isRecordingVideo: true, diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 073c80198728..777ee3cdc012 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -4,7 +4,7 @@ description: A Flutter plugin for controlling the camera. Supports previewing Dart. repository: https://github.com/flutter/packages/tree/main/packages/camera/camera issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 -version: 0.11.2 +version: 0.11.2+1 environment: sdk: ^3.7.0 @@ -38,3 +38,7 @@ dev_dependencies: topics: - camera +# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. +# See https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#changing-federated-plugins +dependency_overrides: + camera_android_camerax: {path: ../../../packages/camera/camera_android_camerax} diff --git a/packages/camera/camera/test/camera_preview_test.dart b/packages/camera/camera/test/camera_preview_test.dart index 139c5534124b..3426a77043da 100644 --- a/packages/camera/camera/test/camera_preview_test.dart +++ b/packages/camera/camera/test/camera_preview_test.dart @@ -111,6 +111,7 @@ class FakeController extends ValueNotifier @override Future startVideoRecording({ onLatestImageAvailable? onAvailable, + bool enablePersistentRecording = true, }) async {} @override From 04109c877783199fee5c005138e0c8ffb0e9ae1c Mon Sep 17 00:00:00 2001 From: Jamiu Akinyemi Date: Mon, 29 Sep 2025 15:17:45 +0100 Subject: [PATCH 2/6] remove dependency overrides, update changelog --- packages/camera/camera/CHANGELOG.md | 2 +- packages/camera/camera/example/pubspec.yaml | 5 ----- packages/camera/camera/pubspec.yaml | 4 ---- 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index 74d64055d31c..9b6c81857e1d 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,6 +1,6 @@ ## 0.11.2+1 -* Fixes flutter/flutter#148013: setDescriptionWhileRecording with android camerax. +* Implement setDescriptionWhileRecording with android camerax (Fixes flutter/flutter#148013). * Updates minimum supported SDK version to Flutter 3.29/Dart 3.7. * Updates README to reflect that only Android API 24+ is supported. diff --git a/packages/camera/camera/example/pubspec.yaml b/packages/camera/camera/example/pubspec.yaml index f6f1f2c098aa..e268268e3204 100644 --- a/packages/camera/camera/example/pubspec.yaml +++ b/packages/camera/camera/example/pubspec.yaml @@ -31,8 +31,3 @@ dev_dependencies: flutter: uses-material-design: true -# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. -# See https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#changing-federated-plugins -dependency_overrides: - camera_android_camerax: {path: ../../../../packages/camera/camera_android_camerax} - camera_platform_interface: {path: ../../../../packages/camera/camera_platform_interface} diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 777ee3cdc012..5207181aac9b 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -38,7 +38,3 @@ dev_dependencies: topics: - camera -# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE. -# See https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#changing-federated-plugins -dependency_overrides: - camera_android_camerax: {path: ../../../packages/camera/camera_android_camerax} From 3c536a4a0e2c020866d3c6c84eec247dec121659 Mon Sep 17 00:00:00 2001 From: Jamiu Akinyemi Date: Tue, 30 Sep 2025 06:32:48 +0100 Subject: [PATCH 3/6] update dependency version --- packages/camera/camera/pubspec.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 5207181aac9b..1ddf1e1d25cd 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -21,9 +21,9 @@ flutter: default_package: camera_web dependencies: - camera_android_camerax: ^0.6.13 + camera_android_camerax: ^0.6.22 camera_avfoundation: ^0.9.18 - camera_platform_interface: ^2.10.0 + camera_platform_interface: ^2.11.0 camera_web: ^0.3.3 flutter: sdk: flutter From 07aa9db4289e6f5b2aeb06a3a6e24cd5f5468bda Mon Sep 17 00:00:00 2001 From: Jamiu Akinyemi Date: Thu, 16 Oct 2025 08:27:12 +0100 Subject: [PATCH 4/6] update version and changelog --- packages/camera/camera/CHANGELOG.md | 4 ++-- packages/camera/camera/pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index 9b6c81857e1d..7960ca275625 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,6 +1,6 @@ -## 0.11.2+1 +## 0.12.0 -* Implement setDescriptionWhileRecording with android camerax (Fixes flutter/flutter#148013). +* Adds support to disable persistent recording on Android. See `CameraController.startVideoRecording(enablePersistentRecording)`. * Updates minimum supported SDK version to Flutter 3.29/Dart 3.7. * Updates README to reflect that only Android API 24+ is supported. diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 1ddf1e1d25cd..307aad14a071 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -4,7 +4,7 @@ description: A Flutter plugin for controlling the camera. Supports previewing Dart. repository: https://github.com/flutter/packages/tree/main/packages/camera/camera issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 -version: 0.11.2+1 +version: 0.12.0 environment: sdk: ^3.7.0 From a088450d53f2e247b61594bc8135b5893254b782 Mon Sep 17 00:00:00 2001 From: Jamiu Akinyemi Date: Tue, 21 Oct 2025 07:34:20 +0100 Subject: [PATCH 5/6] update minimum SDKs --- packages/camera/camera/CHANGELOG.md | 6 +++--- packages/camera/camera/pubspec.yaml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index 7960ca275625..8e53907b478a 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,7 +1,7 @@ -## 0.12.0 +## 0.11.3 -* Adds support to disable persistent recording on Android. See `CameraController.startVideoRecording(enablePersistentRecording)`. -* Updates minimum supported SDK version to Flutter 3.29/Dart 3.7. +* Adds support to configure persistent recording on Android. See `CameraController.startVideoRecording(enablePersistentRecording)`. +* Updates minimum supported SDK version to Flutter 3.35.0/Dart 3.9. * Updates README to reflect that only Android API 24+ is supported. ## 0.11.2 diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 307aad14a071..95b55be083db 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -4,11 +4,11 @@ description: A Flutter plugin for controlling the camera. Supports previewing Dart. repository: https://github.com/flutter/packages/tree/main/packages/camera/camera issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 -version: 0.12.0 +version: 0.11.3 environment: - sdk: ^3.7.0 - flutter: ">=3.29.0" + sdk: ^3.9.0 + flutter: ">=3.35.0" flutter: plugin: From 96fd73c763a6af5d1114a8648f32c19ee4d5824b Mon Sep 17 00:00:00 2001 From: Jamiu Akinyemi Date: Tue, 21 Oct 2025 12:03:59 +0100 Subject: [PATCH 6/6] run code formatting --- .../camera/lib/src/camera_controller.dart | 21 +++++----- .../camera/camera/lib/src/camera_preview.dart | 39 +++++++++---------- packages/camera/camera/test/camera_test.dart | 14 +++---- 3 files changed, 34 insertions(+), 40 deletions(-) diff --git a/packages/camera/camera/lib/src/camera_controller.dart b/packages/camera/camera/lib/src/camera_controller.dart index 3c3a803be0e9..23494b4b27ff 100644 --- a/packages/camera/camera/lib/src/camera_controller.dart +++ b/packages/camera/camera/lib/src/camera_controller.dart @@ -187,20 +187,17 @@ class CameraValue { exposurePointSupported ?? this.exposurePointSupported, focusPointSupported: focusPointSupported ?? this.focusPointSupported, deviceOrientation: deviceOrientation ?? this.deviceOrientation, - lockedCaptureOrientation: - lockedCaptureOrientation == null - ? this.lockedCaptureOrientation - : lockedCaptureOrientation.orNull, - recordingOrientation: - recordingOrientation == null - ? this.recordingOrientation - : recordingOrientation.orNull, + lockedCaptureOrientation: lockedCaptureOrientation == null + ? this.lockedCaptureOrientation + : lockedCaptureOrientation.orNull, + recordingOrientation: recordingOrientation == null + ? this.recordingOrientation + : recordingOrientation.orNull, isPreviewPaused: isPreviewPaused ?? this.isPreviewPaused, description: description ?? this.description, - previewPauseOrientation: - previewPauseOrientation == null - ? this.previewPauseOrientation - : previewPauseOrientation.orNull, + previewPauseOrientation: previewPauseOrientation == null + ? this.previewPauseOrientation + : previewPauseOrientation.orNull, ); } diff --git a/packages/camera/camera/lib/src/camera_preview.dart b/packages/camera/camera/lib/src/camera_preview.dart index c0a15fe56f07..ea0b601ac73a 100644 --- a/packages/camera/camera/lib/src/camera_preview.dart +++ b/packages/camera/camera/lib/src/camera_preview.dart @@ -23,24 +23,23 @@ class CameraPreview extends StatelessWidget { Widget build(BuildContext context) { return controller.value.isInitialized ? ValueListenableBuilder( - valueListenable: controller, - builder: (BuildContext context, Object? value, Widget? child) { - return AspectRatio( - aspectRatio: - _isLandscape() - ? controller.value.aspectRatio - : (1 / controller.value.aspectRatio), - child: Stack( - fit: StackFit.expand, - children: [ - _wrapInRotatedBox(child: controller.buildPreview()), - child ?? Container(), - ], - ), - ); - }, - child: child, - ) + valueListenable: controller, + builder: (BuildContext context, Object? value, Widget? child) { + return AspectRatio( + aspectRatio: _isLandscape() + ? controller.value.aspectRatio + : (1 / controller.value.aspectRatio), + child: Stack( + fit: StackFit.expand, + children: [ + _wrapInRotatedBox(child: controller.buildPreview()), + child ?? Container(), + ], + ), + ); + }, + child: child, + ) : Container(); } @@ -73,7 +72,7 @@ class CameraPreview extends StatelessWidget { return controller.value.isRecordingVideo ? controller.value.recordingOrientation! : (controller.value.previewPauseOrientation ?? - controller.value.lockedCaptureOrientation ?? - controller.value.deviceOrientation); + controller.value.lockedCaptureOrientation ?? + controller.value.deviceOrientation); } } diff --git a/packages/camera/camera/test/camera_test.dart b/packages/camera/camera/test/camera_test.dart index cc7983d10a39..c3af92bb7579 100644 --- a/packages/camera/camera/test/camera_test.dart +++ b/packages/camera/camera/test/camera_test.dart @@ -1838,10 +1838,9 @@ class MockCameraPlatform extends Mock Future createCameraWithSettings( CameraDescription cameraDescription, MediaSettings? mediaSettings, - ) => - mockPlatformException - ? throw PlatformException(code: 'foo', message: 'bar') - : Future.value(mockInitializeCamera); + ) => mockPlatformException + ? throw PlatformException(code: 'foo', message: 'bar') + : Future.value(mockInitializeCamera); @override Future createCamera( @@ -1869,10 +1868,9 @@ class MockCameraPlatform extends Mock ); @override - Future takePicture(int cameraId) => - mockPlatformException - ? throw PlatformException(code: 'foo', message: 'bar') - : Future.value(mockTakePicture); + Future takePicture(int cameraId) => mockPlatformException + ? throw PlatformException(code: 'foo', message: 'bar') + : Future.value(mockTakePicture); @override Future prepareForVideoRecording() async =>