From 228c2b106f30b452c48b2ab7ba7f99f3bee6460e Mon Sep 17 00:00:00 2001 From: Camille Simon <43054281+camsim99@users.noreply.github.com> Date: Mon, 17 Jul 2023 13:44:14 -0700 Subject: [PATCH] [camerax] Add flash configuration for image capture (#3800) Implements off, auto, and always flash configurations for image capture. Part of https://github.com/flutter/flutter/issues/120715. --- .../camera_android_camerax/CHANGELOG.md | 4 ++ .../camera/camera_android_camerax/README.md | 2 +- .../lib/src/android_camera_camerax.dart | 28 ++++++++++++-- .../camera_android_camerax/pubspec.yaml | 2 +- .../test/android_camera_camerax_test.dart | 37 ++++++++++++++++++- 5 files changed, 66 insertions(+), 7 deletions(-) diff --git a/packages/camera/camera_android_camerax/CHANGELOG.md b/packages/camera/camera_android_camerax/CHANGELOG.md index 0db64b8e8a76..01fb140b3192 100644 --- a/packages/camera/camera_android_camerax/CHANGELOG.md +++ b/packages/camera/camera_android_camerax/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.5.0+10 + +* Implements off, auto, and always flash mode configurations for image capture. + ## 0.5.0+9 * Marks all Dart-wrapped Android native classes as `@immutable`. diff --git a/packages/camera/camera_android_camerax/README.md b/packages/camera/camera_android_camerax/README.md index 9d83ddc185fc..dd6e56338805 100644 --- a/packages/camera/camera_android_camerax/README.md +++ b/packages/camera/camera_android_camerax/README.md @@ -35,7 +35,7 @@ Any specified `ResolutionPreset` wll go unused in favor of CameraX defaults and ### Flash mode configuration \[[Issue #120715][120715]\] -`setFlashMode` is unimplemented. +Calling `setFlashMode` with mode `FlashMode.torch` currently does nothing. ### Exposure mode, point, & offset configuration \[[Issue #120468][120468]\] diff --git a/packages/camera/camera_android_camerax/lib/src/android_camera_camerax.dart b/packages/camera/camera_android_camerax/lib/src/android_camera_camerax.dart index aa5d1e0ab207..99f179bbee2d 100644 --- a/packages/camera/camera_android_camerax/lib/src/android_camera_camerax.dart +++ b/packages/camera/camera_android_camerax/lib/src/android_camera_camerax.dart @@ -104,6 +104,9 @@ class AndroidCameraCameraX extends CameraPlatform { @visibleForTesting ImageCapture? imageCapture; + /// The flash mode currently configured for [imageCapture]. + int? _currentFlashMode; + /// The [ImageAnalysis] instance that can be configured to analyze individual /// frames. ImageAnalysis? imageAnalysis; @@ -459,13 +462,32 @@ class AndroidCameraCameraX extends CameraPlatform { /// [cameraId] is not used. @override Future takePicture(int cameraId) async { - // TODO(camsim99): Add support for flash mode configuration. - // https://github.com/flutter/flutter/issues/120715 + if (_currentFlashMode != null) { + await imageCapture!.setFlashMode(_currentFlashMode!); + } final String picturePath = await imageCapture!.takePicture(); - return XFile(picturePath); } + /// Sets the flash mode for the selected camera. + @override + Future setFlashMode(int cameraId, FlashMode mode) async { + switch (mode) { + case FlashMode.off: + _currentFlashMode = ImageCapture.flashModeOff; + break; + case FlashMode.auto: + _currentFlashMode = ImageCapture.flashModeAuto; + break; + case FlashMode.always: + _currentFlashMode = ImageCapture.flashModeOn; + break; + case FlashMode.torch: + // TODO(camsim99): Implement torch mode when CameraControl is wrapped. + break; + } + } + /// Configures and starts a video recording. Returns silently without doing /// anything if there is currently an active recording. @override diff --git a/packages/camera/camera_android_camerax/pubspec.yaml b/packages/camera/camera_android_camerax/pubspec.yaml index 3eecf7f9c608..328ae287f54f 100644 --- a/packages/camera/camera_android_camerax/pubspec.yaml +++ b/packages/camera/camera_android_camerax/pubspec.yaml @@ -2,7 +2,7 @@ name: camera_android_camerax description: Android implementation of the camera plugin using the CameraX library. repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_android_camerax issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 -version: 0.5.0+9 +version: 0.5.0+10 environment: sdk: ">=2.19.0 <4.0.0" diff --git a/packages/camera/camera_android_camerax/test/android_camera_camerax_test.dart b/packages/camera/camera_android_camerax/test/android_camera_camerax_test.dart index 258a8344aed9..b1c57e27dab2 100644 --- a/packages/camera/camera_android_camerax/test/android_camera_camerax_test.dart +++ b/packages/camera/camera_android_camerax/test/android_camera_camerax_test.dart @@ -779,8 +779,6 @@ void main() { final AndroidCameraCameraX camera = AndroidCameraCameraX(); const String testPicturePath = 'test/absolute/path/to/picture'; - camera.processCameraProvider = MockProcessCameraProvider(); - camera.cameraSelector = MockCameraSelector(); camera.imageCapture = MockImageCapture(); when(camera.imageCapture!.takePicture()) @@ -791,6 +789,41 @@ void main() { expect(imageFile.path, equals(testPicturePath)); }); + test('setFlashMode configures ImageCapture with expected flash mode', + () async { + final AndroidCameraCameraX camera = AndroidCameraCameraX(); + const int cameraId = 22; + + camera.imageCapture = MockImageCapture(); + + for (final FlashMode flashMode in FlashMode.values) { + await camera.setFlashMode(cameraId, flashMode); + + int? expectedFlashMode; + switch (flashMode) { + case FlashMode.off: + expectedFlashMode = ImageCapture.flashModeOff; + break; + case FlashMode.auto: + expectedFlashMode = ImageCapture.flashModeAuto; + break; + case FlashMode.always: + expectedFlashMode = ImageCapture.flashModeOn; + break; + case FlashMode.torch: + // TODO(camsim99): Test torch mode when implemented. + break; + } + + if (expectedFlashMode == null) { + continue; + } + + await camera.takePicture(cameraId); + verify(camera.imageCapture!.setFlashMode(expectedFlashMode)); + } + }); + test('getMinExposureOffset returns expected exposure offset', () async { final AndroidCameraCameraX camera = AndroidCameraCameraX(); final MockCameraInfo mockCameraInfo = MockCameraInfo();