From 11966fa35fe35d7b444b7906045f49f7a44ccece Mon Sep 17 00:00:00 2001 From: NeKo Date: Thu, 8 Aug 2019 02:27:34 +0200 Subject: [PATCH 01/30] [camera] Add support for Torch and Auto Exposure * new callable methods torchOn and torchOff * new callable methods aeOn and aeOff * Torch and AE mode could be activated at initialize --- .../io/flutter/plugins/camera/Camera.java | 66 +++++++++++- .../flutter/plugins/camera/CameraPlugin.java | 34 +++++- packages/camera/ios/Classes/CameraPlugin.m | 66 ++++++++++++ packages/camera/lib/camera.dart | 102 ++++++++++++++++++ 4 files changed, 265 insertions(+), 3 deletions(-) diff --git a/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index bf99f8d561d5..c7b3d72b01da 100644 --- a/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -19,6 +19,7 @@ import android.media.Image; import android.media.ImageReader; import android.media.MediaRecorder; +import android.os.Build; import android.util.Size; import android.view.OrientationEventListener; import android.view.Surface; @@ -48,6 +49,8 @@ public class Camera { private final Size previewSize; private final Size videoSize; private final boolean enableAudio; + private final boolean enableTorch; + private final boolean enableAE; private CameraDevice cameraDevice; private CameraCaptureSession cameraCaptureSession; @@ -64,7 +67,9 @@ public Camera( final FlutterView flutterView, final String cameraName, final String resolutionPreset, - final boolean enableAudio) + final boolean enableAudio, + final boolean enableTorch, + final boolean enableAE) throws CameraAccessException { if (activity == null) { throw new IllegalStateException("No activity available!"); @@ -72,6 +77,8 @@ public Camera( this.cameraName = cameraName; this.enableAudio = enableAudio; + this.enableTorch = enableTorch; + this.enableAE = enableAE; this.flutterTexture = flutterView.createSurfaceTexture(); this.cameraManager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE); orientationEventListener = @@ -323,6 +330,16 @@ private void createCaptureSession( } } + // Torch + captureRequestBuilder.set( + CaptureRequest.FLASH_MODE, + enableTorch ? CaptureRequest.FLASH_MODE_TORCH : CaptureRequest.FLASH_MODE_OFF); + + // Auto Exposure + captureRequestBuilder.set( + CaptureRequest.CONTROL_AE_MODE, + enableAE ? CaptureRequest.CONTROL_AE_MODE_ON : CaptureRequest.CONTROL_AE_MODE_OFF); + // Prepare the callback CameraCaptureSession.StateCallback callback = new CameraCaptureSession.StateCallback() { @@ -335,7 +352,18 @@ public void onConfigured(@NonNull CameraCaptureSession session) { } cameraCaptureSession = session; captureRequestBuilder.set( - CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO); + CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO); + + // // Torch + // captureRequestBuilder.set( + // CaptureRequest.FLASH_MODE, + // enableTorch ? CaptureRequest.FLASH_MODE_TORCH : CaptureRequest.FLASH_MODE_OFF); + + // // Auto Exposure + // captureRequestBuilder.set( + // CaptureRequest.CONTROL_AE_MODE, + // enableAE ? CaptureRequest.CONTROL_AE_MODE_ON : CaptureRequest.CONTROL_AE_MODE_OFF); + cameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null); if (onSuccessCallback != null) { onSuccessCallback.run(); @@ -447,6 +475,40 @@ private void setImageStreamImageAvailableListener(final EventChannel.EventSink i null); } + // Torch + public void setTorchMode(@NonNull final Result result, boolean enable){ + setTorchMode(result, enable, 1.0); + } + + public void setTorchMode(@NonNull final Result result, boolean enable, double level){ + try { + captureRequestBuilder.set( + CaptureRequest.FLASH_MODE, + enable ? CaptureRequest.FLASH_MODE_TORCH : CaptureRequest.FLASH_MODE_OFF); + + cameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null); + + result.success(null); + } catch (Exception e) { + result.error("cameraTorchFailed", e.getMessage(), null); + } + } + + public void setAEMode(@NonNull final Result result, boolean enable){ + try { + // Auto Exposure + captureRequestBuilder.set( + CaptureRequest.CONTROL_AE_MODE, + enable ? CaptureRequest.CONTROL_AE_MODE_ON : CaptureRequest.CONTROL_AE_MODE_OFF); + + cameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null); + + result.success(null); + } catch (Exception e) { + result.error("cameraAEFailed", e.getMessage(), null); + } + } + private void sendEvent(EventType eventType) { sendEvent(eventType, null); } diff --git a/packages/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java b/packages/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java index 2d16e0be80ef..1273324aab23 100644 --- a/packages/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java +++ b/packages/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java @@ -3,6 +3,7 @@ import android.hardware.camera2.CameraAccessException; import android.os.Build; import androidx.annotation.NonNull; +import android.content.pm.PackageManager; import io.flutter.plugin.common.EventChannel; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; @@ -44,7 +45,9 @@ private void instantiateCamera(MethodCall call, Result result) throws CameraAcce String cameraName = call.argument("cameraName"); String resolutionPreset = call.argument("resolutionPreset"); boolean enableAudio = call.argument("enableAudio"); - camera = new Camera(registrar.activity(), view, cameraName, resolutionPreset, enableAudio); + boolean enableTorch = call.argument("enableTorch"); + boolean enableAE = call.argument("enableAE"); + camera = new Camera(registrar.activity(), view, cameraName, resolutionPreset, enableAudio, enableTorch, enableAE); EventChannel cameraEventChannel = new EventChannel( @@ -128,6 +131,31 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull final Result result) } break; } + case "torchOn": + { + camera.setTorchMode(result, true, call.argument("level")); + break; + } + case "torchOff": + { + camera.setTorchMode(result, false); + break; + } + case "hasTorch": + { + result.success(hasTorch()); + break; + } + case "aeOn": + { + camera.setAEMode(result, true); + break; + } + case "aeOff": + { + camera.setAEMode(result, false); + break; + } case "dispose": { if (camera != null) { @@ -142,6 +170,10 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull final Result result) } } + private boolean hasTorch() { + return registrar.context().getApplicationContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH); + } + // We move catching CameraAccessException out of onMethodCall because it causes a crash // on plugin registration for sdks incompatible with Camera2 (< 21). We want this plugin to // to be able to compile with <21 sdks for apps that want the camera and support earlier version. diff --git a/packages/camera/ios/Classes/CameraPlugin.m b/packages/camera/ios/Classes/CameraPlugin.m index 4c001926ae25..1117d640c33b 100644 --- a/packages/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/ios/Classes/CameraPlugin.m @@ -121,6 +121,8 @@ @interface FLTCam : NSObject { this.description, this.resolutionPreset, { this.enableAudio = true, + this.enableTorch = false, + this.enableAE = true, }) : super(const CameraValue.uninitialized()); final CameraDescription description; @@ -215,6 +217,13 @@ class CameraController extends ValueNotifier { /// Whether to include audio when recording a video. final bool enableAudio; + // Torch + final bool enableTorch; + + // Auto Exposure + final bool enableAE; + + int _textureId; bool _isDisposed = false; StreamSubscription _eventSubscription; @@ -237,6 +246,8 @@ class CameraController extends ValueNotifier { 'cameraName': description.name, 'resolutionPreset': serializeResolutionPreset(resolutionPreset), 'enableAudio': enableAudio, + 'enableTorch': enableTorch, + 'enableAE': enableAE, }, ); _textureId = reply['textureId']; @@ -477,6 +488,97 @@ class CameraController extends ValueNotifier { } } + /// Switch ON the torch. + Future torchOn({double level: 1.0}) async { + if (!value.isInitialized || _isDisposed) { + throw CameraException( + 'Uninitialized CameraController.', + 'torchOn was called on uninitialized CameraController', + ); + } + + try { + await _channel.invokeMethod( + 'torchOn', + {'level': level} + ); + } on PlatformException catch (e) { + throw CameraException(e.code, e.message); + } + } + + /// Switch OFF the torch. + Future torchOff() async { + if (!value.isInitialized || _isDisposed) { + throw CameraException( + 'Uninitialized CameraController.', + 'torchOff was called on uninitialized CameraController', + ); + } + + try { + await _channel.invokeMethod( + 'torchOff' + ); + } on PlatformException catch (e) { + throw CameraException(e.code, e.message); + } + } + + /// check if the device has a torch. + Future get hasTorch async { + if (!value.isInitialized || _isDisposed) { + throw CameraException( + 'Uninitialized CameraController.', + 'hasTorch was called on uninitialized CameraController', + ); + } + + try { + return await _channel.invokeMethod( + 'hasTorch' + ); + } on PlatformException catch (e) { + throw CameraException(e.code, e.message); + } + } + + /// Switch ON continuous Auto Exposure. + Future aeOn() async { + if (!value.isInitialized || _isDisposed) { + throw CameraException( + 'Uninitialized CameraController.', + 'aeOn was called on uninitialized CameraController', + ); + } + + try { + await _channel.invokeMethod( + 'aeOn' + ); + } on PlatformException catch (e) { + throw CameraException(e.code, e.message); + } + } + + /// Switch OFF continuous Auto Exposure. + Future aeOff() async { + if (!value.isInitialized || _isDisposed) { + throw CameraException( + 'Uninitialized CameraController.', + 'aeOff was called on uninitialized CameraController', + ); + } + + try { + await _channel.invokeMethod( + 'aeOff' + ); + } on PlatformException catch (e) { + throw CameraException(e.code, e.message); + } + } + /// Releases the resources of this camera. @override Future dispose() async { From 841d3f361b2a0250ee2480571079682299362d3f Mon Sep 17 00:00:00 2001 From: NeKo Date: Sat, 10 Aug 2019 16:53:52 +0200 Subject: [PATCH 02/30] [camera] set auto exposure trigger when turn on or off the torch --- .../src/main/java/io/flutter/plugins/camera/Camera.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index c7b3d72b01da..8f28966a2177 100644 --- a/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -485,6 +485,9 @@ public void setTorchMode(@NonNull final Result result, boolean enable, double le captureRequestBuilder.set( CaptureRequest.FLASH_MODE, enable ? CaptureRequest.FLASH_MODE_TORCH : CaptureRequest.FLASH_MODE_OFF); + + captureRequestBuilder.set( + CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START); cameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null); From 77fffa03c66af77529c295d1e0b7f6b981cc1be5 Mon Sep 17 00:00:00 2001 From: NeKo Date: Sat, 10 Aug 2019 17:32:11 +0200 Subject: [PATCH 03/30] [camera] increment version in pubspec.yaml --- packages/camera/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/camera/pubspec.yaml b/packages/camera/pubspec.yaml index a7e65c706ef1..f2622225ca95 100644 --- a/packages/camera/pubspec.yaml +++ b/packages/camera/pubspec.yaml @@ -2,7 +2,7 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.5.2+2 +version: 0.5.4 authors: - Flutter Team From 2680f8dcb52d925ff7ccb3a1070e8154fa7e9618 Mon Sep 17 00:00:00 2001 From: NeKo Date: Sat, 10 Aug 2019 17:39:05 +0200 Subject: [PATCH 04/30] [camera] update changelog --- packages/camera/CHANGELOG.md | 3 +++ packages/camera/pubspec.yaml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/camera/CHANGELOG.md b/packages/camera/CHANGELOG.md index 2d09af5b8953..b5b6657c5044 100644 --- a/packages/camera/CHANGELOG.md +++ b/packages/camera/CHANGELOG.md @@ -1,3 +1,6 @@ +## 0.5.3 +* Add support for Torch and Auto Exposure + ## 0.5.2+2 * Fix memory leak related to not unregistering stream handler in FlutterEventChannel when disposing camera. diff --git a/packages/camera/pubspec.yaml b/packages/camera/pubspec.yaml index f2622225ca95..cd608c9987be 100644 --- a/packages/camera/pubspec.yaml +++ b/packages/camera/pubspec.yaml @@ -2,7 +2,7 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.5.4 +version: 0.5.3 authors: - Flutter Team From ab961e9301a2583b39f8364aa1c6c5901fcc69d8 Mon Sep 17 00:00:00 2001 From: NeKo Date: Sat, 10 Aug 2019 18:13:53 +0200 Subject: [PATCH 05/30] [camera] fix format for default value --- packages/camera/lib/camera.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/camera/lib/camera.dart b/packages/camera/lib/camera.dart index adcfdfff360e..9be19e5923cb 100644 --- a/packages/camera/lib/camera.dart +++ b/packages/camera/lib/camera.dart @@ -489,7 +489,7 @@ class CameraController extends ValueNotifier { } /// Switch ON the torch. - Future torchOn({double level: 1.0}) async { + Future torchOn({double level = 1.0}) async { if (!value.isInitialized || _isDisposed) { throw CameraException( 'Uninitialized CameraController.', From 664f56606f1762d60e6b5ef37e77d8a5e5549ef6 Mon Sep 17 00:00:00 2001 From: NeKo Date: Sat, 10 Aug 2019 18:57:37 +0200 Subject: [PATCH 06/30] [camera] remove commented code and fix format --- .../io/flutter/plugins/camera/Camera.java | 40 ++++------- .../flutter/plugins/camera/CameraPlugin.java | 17 ++++- packages/camera/ios/Classes/CameraPlugin.m | 69 ++++++++++--------- packages/camera/lib/camera.dart | 35 ++++------ 4 files changed, 78 insertions(+), 83 deletions(-) diff --git a/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index 3ae85e0b0754..20329e5f3b34 100644 --- a/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -21,7 +21,6 @@ import android.media.Image; import android.media.ImageReader; import android.media.MediaRecorder; -import android.os.Build; import android.util.Size; import android.view.OrientationEventListener; import android.view.Surface; @@ -328,13 +327,13 @@ private void createCaptureSession( // Torch captureRequestBuilder.set( - CaptureRequest.FLASH_MODE, - enableTorch ? CaptureRequest.FLASH_MODE_TORCH : CaptureRequest.FLASH_MODE_OFF); + CaptureRequest.FLASH_MODE, + enableTorch ? CaptureRequest.FLASH_MODE_TORCH : CaptureRequest.FLASH_MODE_OFF); // Auto Exposure captureRequestBuilder.set( - CaptureRequest.CONTROL_AE_MODE, - enableAE ? CaptureRequest.CONTROL_AE_MODE_ON : CaptureRequest.CONTROL_AE_MODE_OFF); + CaptureRequest.CONTROL_AE_MODE, + enableAE ? CaptureRequest.CONTROL_AE_MODE_ON : CaptureRequest.CONTROL_AE_MODE_OFF); // Prepare the callback CameraCaptureSession.StateCallback callback = @@ -348,17 +347,7 @@ public void onConfigured(@NonNull CameraCaptureSession session) { } cameraCaptureSession = session; captureRequestBuilder.set( - CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO); - - // // Torch - // captureRequestBuilder.set( - // CaptureRequest.FLASH_MODE, - // enableTorch ? CaptureRequest.FLASH_MODE_TORCH : CaptureRequest.FLASH_MODE_OFF); - - // // Auto Exposure - // captureRequestBuilder.set( - // CaptureRequest.CONTROL_AE_MODE, - // enableAE ? CaptureRequest.CONTROL_AE_MODE_ON : CaptureRequest.CONTROL_AE_MODE_OFF); + CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO); cameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null); if (onSuccessCallback != null) { @@ -472,36 +461,35 @@ private void setImageStreamImageAvailableListener(final EventChannel.EventSink i } // Torch - public void setTorchMode(@NonNull final Result result, boolean enable){ + public void setTorchMode(@NonNull final Result result, boolean enable) { setTorchMode(result, enable, 1.0); } - public void setTorchMode(@NonNull final Result result, boolean enable, double level){ + public void setTorchMode(@NonNull final Result result, boolean enable, double level) { try { captureRequestBuilder.set( - CaptureRequest.FLASH_MODE, - enable ? CaptureRequest.FLASH_MODE_TORCH : CaptureRequest.FLASH_MODE_OFF); + CaptureRequest.FLASH_MODE, + enable ? CaptureRequest.FLASH_MODE_TORCH : CaptureRequest.FLASH_MODE_OFF); captureRequestBuilder.set( - CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START); + CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, + CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START); cameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null); - result.success(null); } catch (Exception e) { result.error("cameraTorchFailed", e.getMessage(), null); } } - public void setAEMode(@NonNull final Result result, boolean enable){ + public void setAEMode(@NonNull final Result result, boolean enable) { try { // Auto Exposure captureRequestBuilder.set( - CaptureRequest.CONTROL_AE_MODE, - enable ? CaptureRequest.CONTROL_AE_MODE_ON : CaptureRequest.CONTROL_AE_MODE_OFF); + CaptureRequest.CONTROL_AE_MODE, + enable ? CaptureRequest.CONTROL_AE_MODE_ON : CaptureRequest.CONTROL_AE_MODE_OFF); cameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null); - result.success(null); } catch (Exception e) { result.error("cameraAEFailed", e.getMessage(), null); diff --git a/packages/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java b/packages/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java index 1273324aab23..8fd57097ffab 100644 --- a/packages/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java +++ b/packages/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java @@ -1,9 +1,9 @@ package io.flutter.plugins.camera; +import android.content.pm.PackageManager; import android.hardware.camera2.CameraAccessException; import android.os.Build; import androidx.annotation.NonNull; -import android.content.pm.PackageManager; import io.flutter.plugin.common.EventChannel; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; @@ -47,7 +47,15 @@ private void instantiateCamera(MethodCall call, Result result) throws CameraAcce boolean enableAudio = call.argument("enableAudio"); boolean enableTorch = call.argument("enableTorch"); boolean enableAE = call.argument("enableAE"); - camera = new Camera(registrar.activity(), view, cameraName, resolutionPreset, enableAudio, enableTorch, enableAE); + camera = + new Camera( + registrar.activity(), + view, + cameraName, + resolutionPreset, + enableAudio, + enableTorch, + enableAE); EventChannel cameraEventChannel = new EventChannel( @@ -171,7 +179,10 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull final Result result) } private boolean hasTorch() { - return registrar.context().getApplicationContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH); + return registrar.context() + .getApplicationContext() + .getPackageManager() + .hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH); } // We move catching CameraAccessException out of onMethodCall because it causes a crash diff --git a/packages/camera/ios/Classes/CameraPlugin.m b/packages/camera/ios/Classes/CameraPlugin.m index 37121ca995e6..3f49cd952062 100644 --- a/packages/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/ios/Classes/CameraPlugin.m @@ -186,7 +186,7 @@ - (instancetype)initWithCameraName:(NSString *)cameraName resolutionPreset:(NSString *)resolutionPreset enableAudio:(BOOL)enableAudio enableTorch:(BOOL)enableTorch - enableAE:(BOOL)enableAE + enableAE:(BOOL)enableAE dispatchQueue:(dispatch_queue_t)dispatchQueue error:(NSError **)error; @@ -209,7 +209,7 @@ - (instancetype)initWithCameraName:(NSString *)cameraName resolutionPreset:(NSString *)resolutionPreset enableAudio:(BOOL)enableAudio enableTorch:(BOOL)enableTorch - enableAE:(BOOL)enableAE + enableAE:(BOOL)enableAE dispatchQueue:(dispatch_queue_t)dispatchQueue error:(NSError **)error { self = [super init]; @@ -258,11 +258,11 @@ - (instancetype)initWithCameraName:(NSString *)cameraName [self setCaptureSessionPreset:_resolutionPreset]; [self setCaptureSessionPreset:resolutionPreset]; - if(enableTorch) { + if (enableTorch) { [self setTorchMode:enableTorch]; } - if(enableAE) { + if (enableAE) { [self setAEMode:enableAE]; } @@ -595,40 +595,41 @@ - (void)stopImageStream { } } -- (bool) hasTorch { +- (bool)hasTorch { AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; return ([device hasTorch] && [device hasFlash]); } -- (void) setTorchMode:(NSNumber)enable +- (void)setTorchMode:(NSNumber)enable (float)level { AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; - if ([device hasTorch] && [device hasFlash]){ - [device lockForConfiguration:nil]; - if(enable){ - NSError *error = nil; - float acceptedLevel = (level < AVCaptureMaxAvailableTorchLevel ? level : AVCaptureMaxAvailableTorchLevel); - NSLog(@"FLash level: %f", acceptedLevel); - [device setTorchModeOnWithLevel:acceptedLevel error:&error]; - }else{ - [device setTorchMode:AVCaptureTorchModeOff]; - } - [device unlockForConfiguration]; + if ([device hasTorch] && [device hasFlash]) { + [device lockForConfiguration:nil]; + if(enable){ + NSError *error = nil; + float acceptedLevel = + (level < AVCaptureMaxAvailableTorchLevel ? level : AVCaptureMaxAvailableTorchLevel); + NSLog(@"FLash level: %f", acceptedLevel); + [device setTorchModeOnWithLevel:acceptedLevel error:&error]; + }else{ + [device setTorchMode:AVCaptureTorchModeOff]; + } + [device unlockForConfiguration]; } } -- (void) setAEMode:(NSNumber)enable { +- (void)setAEMode:(NSNumber)enable { AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; - if ([device isExposureModeSupported:AVCaptureDevice.ExposureMode]){ - [device lockForConfiguration:nil]; - if(enable){ - AVCaptureDevice.ExposureMode exposure = AVCaptureDevice.ExposureMode.continuousAutoExposure; - if(exposure && [device isExposureModeSupported: exposure]) - [device exposureMode:exposure]; - }else{ - [device exposureMode:AVCaptureDevice.ExposureMode.autoExpose]; - } - [device unlockForConfiguration]; + if ([device isExposureModeSupported:AVCaptureDevice.ExposureMode]) { + [device lockForConfiguration:nil]; + if(enable){ + AVCaptureDevice.ExposureMode exposure = AVCaptureDevice.ExposureMode.continuousAutoExposure; + if(exposure && [device isExposureModeSupported: exposure]) + [device exposureMode:exposure]; + }else{ + [device exposureMode:AVCaptureDevice.ExposureMode.autoExpose]; + } + [device unlockForConfiguration]; } } @@ -789,7 +790,7 @@ - (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)re NSString *resolutionPreset = call.arguments[@"resolutionPreset"]; NSNumber *enableAudio = call.arguments[@"enableAudio"]; NSNumber *enableTorch = call.arguments[@"enableTorch"]; - NSNumber *enableAE = call.arguments[@"enableAE"];plop + NSNumber *enableAE = call.arguments[@"enableAE"]; NSError *error; FLTCam *cam = [[FLTCam alloc] initWithCameraName:cameraName resolutionPreset:resolutionPreset @@ -834,12 +835,12 @@ - (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)re } else if ([@"hasTorch" isEqualToString:call.method]) { result([NSNumber numberWithBool:[_camera hasTorch]]); } else if ([@"torchOn" isEqualToString:call.method]) { - NSNumber *level = call.arguments[@"level"]; - [_camera setTorchMode:true level.doubleValue]; - result(nil); + NSNumber *level = call.arguments[@"level"]; + [_camera setTorchMode:true level.doubleValue]; + result(nil); } else if ([@"torchOff" isEqualToString:call.method]) { - [_camera setTorchMode:false]; - result(nil); + [_camera setTorchMode:false]; + result(nil); } else { NSDictionary *argsMap = call.arguments; NSUInteger textureId = ((NSNumber *)argsMap[@"textureId"]).unsignedIntegerValue; diff --git a/packages/camera/lib/camera.dart b/packages/camera/lib/camera.dart index 070393478e35..72043d19c2d0 100644 --- a/packages/camera/lib/camera.dart +++ b/packages/camera/lib/camera.dart @@ -504,12 +504,14 @@ class CameraController extends ValueNotifier { 'stopVideoRecording was called when no video is recording.', ); } + try { value = value.copyWith(isRecordingVideo: false); - await _channel.invokeMethod( - 'stopVideoRecording', - {'textureId': _textureId}, - ); + await _channel + .invokeMethod( + 'stopVideoRecording', + {'textureId': _textureId}, + ); } on PlatformException catch (e) { throw CameraException(e.code, e.message); } @@ -525,10 +527,8 @@ class CameraController extends ValueNotifier { } try { - await _channel.invokeMethod( - 'torchOn', - {'level': level} - ); + await _channel + .invokeMethod('torchOn', {'level': level}); } on PlatformException catch (e) { throw CameraException(e.code, e.message); } @@ -544,9 +544,7 @@ class CameraController extends ValueNotifier { } try { - await _channel.invokeMethod( - 'torchOff' - ); + await _channel.invokeMethod('torchOff'); } on PlatformException catch (e) { throw CameraException(e.code, e.message); } @@ -562,9 +560,7 @@ class CameraController extends ValueNotifier { } try { - return await _channel.invokeMethod( - 'hasTorch' - ); + return await _channel.invokeMethod('hasTorch'); } on PlatformException catch (e) { throw CameraException(e.code, e.message); } @@ -580,9 +576,7 @@ class CameraController extends ValueNotifier { } try { - await _channel.invokeMethod( - 'aeOn' - ); + await _channel.invokeMethod('aeOn'); } on PlatformException catch (e) { throw CameraException(e.code, e.message); } @@ -598,9 +592,10 @@ class CameraController extends ValueNotifier { } try { - await _channel.invokeMethod( - 'aeOff' - ); + await _channel + .invokeMethod( + 'aeOff' + ); } on PlatformException catch (e) { throw CameraException(e.code, e.message); } From cf1986dae777efe59feaa8e352fbaf6f54da6b43 Mon Sep 17 00:00:00 2001 From: NeKo Date: Sat, 10 Aug 2019 19:20:54 +0200 Subject: [PATCH 07/30] [camera] fix format --- .../java/io/flutter/plugins/camera/Camera.java | 10 +++++----- .../io/flutter/plugins/camera/CameraPlugin.java | 15 ++++++++------- packages/camera/ios/Classes/CameraPlugin.m | 12 ++++++------ packages/camera/lib/camera.dart | 11 +++++------ 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index 20329e5f3b34..99f509caff38 100644 --- a/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -327,12 +327,12 @@ private void createCaptureSession( // Torch captureRequestBuilder.set( - CaptureRequest.FLASH_MODE, + CaptureRequest.FLASH_MODE, enableTorch ? CaptureRequest.FLASH_MODE_TORCH : CaptureRequest.FLASH_MODE_OFF); // Auto Exposure captureRequestBuilder.set( - CaptureRequest.CONTROL_AE_MODE, + CaptureRequest.CONTROL_AE_MODE, enableAE ? CaptureRequest.CONTROL_AE_MODE_ON : CaptureRequest.CONTROL_AE_MODE_OFF); // Prepare the callback @@ -468,11 +468,11 @@ public void setTorchMode(@NonNull final Result result, boolean enable) { public void setTorchMode(@NonNull final Result result, boolean enable, double level) { try { captureRequestBuilder.set( - CaptureRequest.FLASH_MODE, + CaptureRequest.FLASH_MODE, enable ? CaptureRequest.FLASH_MODE_TORCH : CaptureRequest.FLASH_MODE_OFF); captureRequestBuilder.set( - CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, + CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START); cameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null); @@ -486,7 +486,7 @@ public void setAEMode(@NonNull final Result result, boolean enable) { try { // Auto Exposure captureRequestBuilder.set( - CaptureRequest.CONTROL_AE_MODE, + CaptureRequest.CONTROL_AE_MODE, enable ? CaptureRequest.CONTROL_AE_MODE_ON : CaptureRequest.CONTROL_AE_MODE_OFF); cameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null); diff --git a/packages/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java b/packages/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java index 8fd57097ffab..c14f326f9947 100644 --- a/packages/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java +++ b/packages/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java @@ -47,14 +47,14 @@ private void instantiateCamera(MethodCall call, Result result) throws CameraAcce boolean enableAudio = call.argument("enableAudio"); boolean enableTorch = call.argument("enableTorch"); boolean enableAE = call.argument("enableAE"); - camera = + camera = new Camera( registrar.activity(), - view, - cameraName, - resolutionPreset, - enableAudio, - enableTorch, + view, + cameraName, + resolutionPreset, + enableAudio, + enableTorch, enableAE); EventChannel cameraEventChannel = @@ -179,7 +179,8 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull final Result result) } private boolean hasTorch() { - return registrar.context() + return registrar + .context() .getApplicationContext() .getPackageManager() .hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH); diff --git a/packages/camera/ios/Classes/CameraPlugin.m b/packages/camera/ios/Classes/CameraPlugin.m index 3f49cd952062..359db66e197b 100644 --- a/packages/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/ios/Classes/CameraPlugin.m @@ -265,7 +265,7 @@ - (instancetype)initWithCameraName:(NSString *)cameraName if (enableAE) { [self setAEMode:enableAE]; } - + return self; } @@ -605,13 +605,13 @@ - (void)setTorchMode:(NSNumber)enable AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; if ([device hasTorch] && [device hasFlash]) { [device lockForConfiguration:nil]; - if(enable){ + if (enable) { NSError *error = nil; - float acceptedLevel = + float acceptedLevel = (level < AVCaptureMaxAvailableTorchLevel ? level : AVCaptureMaxAvailableTorchLevel); NSLog(@"FLash level: %f", acceptedLevel); [device setTorchModeOnWithLevel:acceptedLevel error:&error]; - }else{ + } else { [device setTorchMode:AVCaptureTorchModeOff]; } [device unlockForConfiguration]; @@ -622,11 +622,11 @@ - (void)setAEMode:(NSNumber)enable { AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; if ([device isExposureModeSupported:AVCaptureDevice.ExposureMode]) { [device lockForConfiguration:nil]; - if(enable){ + if (enable) { AVCaptureDevice.ExposureMode exposure = AVCaptureDevice.ExposureMode.continuousAutoExposure; if(exposure && [device isExposureModeSupported: exposure]) [device exposureMode:exposure]; - }else{ + } else { [device exposureMode:AVCaptureDevice.ExposureMode.autoExpose]; } [device unlockForConfiguration]; diff --git a/packages/camera/lib/camera.dart b/packages/camera/lib/camera.dart index 72043d19c2d0..7dd949382773 100644 --- a/packages/camera/lib/camera.dart +++ b/packages/camera/lib/camera.dart @@ -507,11 +507,10 @@ class CameraController extends ValueNotifier { try { value = value.copyWith(isRecordingVideo: false); - await _channel - .invokeMethod( - 'stopVideoRecording', - {'textureId': _textureId}, - ); + await _channel.invokeMethod( + 'stopVideoRecording', + {'textureId': _textureId}, + ); } on PlatformException catch (e) { throw CameraException(e.code, e.message); } @@ -525,7 +524,7 @@ class CameraController extends ValueNotifier { 'torchOn was called on uninitialized CameraController', ); } - + try { await _channel .invokeMethod('torchOn', {'level': level}); From 9301cab5e5d13caf6987b66a6a91884b0838640f Mon Sep 17 00:00:00 2001 From: NeKo Date: Sat, 10 Aug 2019 19:40:20 +0200 Subject: [PATCH 08/30] [camera] fix space characters --- .../src/main/java/io/flutter/plugins/camera/Camera.java | 4 ++-- .../main/java/io/flutter/plugins/camera/CameraPlugin.java | 2 +- packages/camera/ios/Classes/CameraPlugin.m | 8 +++----- packages/camera/lib/camera.dart | 6 ++---- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index 99f509caff38..4aece7713a17 100644 --- a/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -474,7 +474,7 @@ public void setTorchMode(@NonNull final Result result, boolean enable, double le captureRequestBuilder.set( CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START); - + cameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null); result.success(null); } catch (Exception e) { @@ -488,7 +488,7 @@ public void setAEMode(@NonNull final Result result, boolean enable) { captureRequestBuilder.set( CaptureRequest.CONTROL_AE_MODE, enable ? CaptureRequest.CONTROL_AE_MODE_ON : CaptureRequest.CONTROL_AE_MODE_OFF); - + cameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null); result.success(null); } catch (Exception e) { diff --git a/packages/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java b/packages/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java index c14f326f9947..624adc91dea9 100644 --- a/packages/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java +++ b/packages/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java @@ -49,7 +49,7 @@ private void instantiateCamera(MethodCall call, Result result) throws CameraAcce boolean enableAE = call.argument("enableAE"); camera = new Camera( - registrar.activity(), + registrar.activity(), view, cameraName, resolutionPreset, diff --git a/packages/camera/ios/Classes/CameraPlugin.m b/packages/camera/ios/Classes/CameraPlugin.m index 359db66e197b..22fc0d87839e 100644 --- a/packages/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/ios/Classes/CameraPlugin.m @@ -600,8 +600,7 @@ - (bool)hasTorch { return ([device hasTorch] && [device hasFlash]); } -- (void)setTorchMode:(NSNumber)enable - (float)level { +- (void)setTorchMode:(NSNumber)enable(float)level { AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; if ([device hasTorch] && [device hasFlash]) { [device lockForConfiguration:nil]; @@ -624,8 +623,7 @@ - (void)setAEMode:(NSNumber)enable { [device lockForConfiguration:nil]; if (enable) { AVCaptureDevice.ExposureMode exposure = AVCaptureDevice.ExposureMode.continuousAutoExposure; - if(exposure && [device isExposureModeSupported: exposure]) - [device exposureMode:exposure]; + if(exposure && [device isExposureModeSupported: exposure]) [device exposureMode:exposure]; } else { [device exposureMode:AVCaptureDevice.ExposureMode.autoExpose]; } @@ -796,7 +794,7 @@ - (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)re resolutionPreset:resolutionPreset enableAudio:[enableAudio boolValue] enableTorch:[enableTorch boolValue] - enableAE:[enableAE boolValue] + enableAE:[enableAE boolValue] dispatchQueue:_dispatchQueue error:&error]; if (error) { diff --git a/packages/camera/lib/camera.dart b/packages/camera/lib/camera.dart index 7dd949382773..4d47fdd5fb5d 100644 --- a/packages/camera/lib/camera.dart +++ b/packages/camera/lib/camera.dart @@ -573,7 +573,7 @@ class CameraController extends ValueNotifier { 'aeOn was called on uninitialized CameraController', ); } - + try { await _channel.invokeMethod('aeOn'); } on PlatformException catch (e) { @@ -592,9 +592,7 @@ class CameraController extends ValueNotifier { try { await _channel - .invokeMethod( - 'aeOff' - ); + .invokeMethod('aeOff'); } on PlatformException catch (e) { throw CameraException(e.code, e.message); } From f5566acbc0f73812470f26077164a2aa15f21e74 Mon Sep 17 00:00:00 2001 From: NeKo Date: Sat, 10 Aug 2019 19:47:46 +0200 Subject: [PATCH 09/30] [camera] fix format --- packages/camera/ios/Classes/CameraPlugin.m | 2 +- packages/camera/lib/camera.dart | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/camera/ios/Classes/CameraPlugin.m b/packages/camera/ios/Classes/CameraPlugin.m index 22fc0d87839e..7916d539b199 100644 --- a/packages/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/ios/Classes/CameraPlugin.m @@ -623,7 +623,7 @@ - (void)setAEMode:(NSNumber)enable { [device lockForConfiguration:nil]; if (enable) { AVCaptureDevice.ExposureMode exposure = AVCaptureDevice.ExposureMode.continuousAutoExposure; - if(exposure && [device isExposureModeSupported: exposure]) [device exposureMode:exposure]; + if (exposure && [device isExposureModeSupported:exposure]) [device exposureMode:exposure]; } else { [device exposureMode:AVCaptureDevice.ExposureMode.autoExpose]; } diff --git a/packages/camera/lib/camera.dart b/packages/camera/lib/camera.dart index 4d47fdd5fb5d..5c1dede20c39 100644 --- a/packages/camera/lib/camera.dart +++ b/packages/camera/lib/camera.dart @@ -591,8 +591,7 @@ class CameraController extends ValueNotifier { } try { - await _channel - .invokeMethod('aeOff'); + await _channel.invokeMethod('aeOff'); } on PlatformException catch (e) { throw CameraException(e.code, e.message); } From 111107446542546fad5109704a79f6d53cb1f39c Mon Sep 17 00:00:00 2001 From: NeKo Date: Sat, 10 Aug 2019 19:55:55 +0200 Subject: [PATCH 10/30] [camera] delete a blank line for the pleasure of the CI --- packages/camera/lib/camera.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/camera/lib/camera.dart b/packages/camera/lib/camera.dart index 5c1dede20c39..097d21de3af5 100644 --- a/packages/camera/lib/camera.dart +++ b/packages/camera/lib/camera.dart @@ -250,7 +250,6 @@ class CameraController extends ValueNotifier { // Auto Exposure final bool enableAE; - int _textureId; bool _isDisposed = false; StreamSubscription _eventSubscription; From 21f1ddf6d1bb9e678883693ab5c82f0b066b23b5 Mon Sep 17 00:00:00 2001 From: NeKo Date: Sat, 10 Aug 2019 20:50:36 +0200 Subject: [PATCH 11/30] [camera] refactor ios code --- packages/camera/ios/Classes/CameraPlugin.m | 27 +++++++++++----------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/packages/camera/ios/Classes/CameraPlugin.m b/packages/camera/ios/Classes/CameraPlugin.m index 7916d539b199..bd09a66609d5 100644 --- a/packages/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/ios/Classes/CameraPlugin.m @@ -259,11 +259,11 @@ - (instancetype)initWithCameraName:(NSString *)cameraName [self setCaptureSessionPreset:resolutionPreset]; if (enableTorch) { - [self setTorchMode:enableTorch]; + [self setTorchMode:[enableTorch boolValue]]; } if (enableAE) { - [self setAEMode:enableAE]; + [self setAEMode:[enableAE boolValue]]; } return self; @@ -600,7 +600,8 @@ - (bool)hasTorch { return ([device hasTorch] && [device hasFlash]); } -- (void)setTorchMode:(NSNumber)enable(float)level { +- (void)setTorchMode:(NSNumber *)enable + level:(float)level { AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; if ([device hasTorch] && [device hasFlash]) { [device lockForConfiguration:nil]; @@ -617,18 +618,16 @@ - (void)setTorchMode:(NSNumber)enable(float)level { } } -- (void)setAEMode:(NSNumber)enable { +- (void)setAEMode:(NSNumber *)enable { AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; - if ([device isExposureModeSupported:AVCaptureDevice.ExposureMode]) { - [device lockForConfiguration:nil]; - if (enable) { - AVCaptureDevice.ExposureMode exposure = AVCaptureDevice.ExposureMode.continuousAutoExposure; - if (exposure && [device isExposureModeSupported:exposure]) [device exposureMode:exposure]; - } else { - [device exposureMode:AVCaptureDevice.ExposureMode.autoExpose]; - } - [device unlockForConfiguration]; + [device lockForConfiguration:nil]; + if (enable) { + int exposure = AVCaptureDevice.ExposureMode.continuousAutoExposure; + if (exposure && [device isExposureModeSupported:exposure]) [device exposureMode:exposure]; + } else { + [device exposureMode:AVCaptureDevice.ExposureMode.autoExpose]; } + [device unlockForConfiguration]; } - (BOOL)setupWriterForPath:(NSString *)path { @@ -834,7 +833,7 @@ - (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)re result([NSNumber numberWithBool:[_camera hasTorch]]); } else if ([@"torchOn" isEqualToString:call.method]) { NSNumber *level = call.arguments[@"level"]; - [_camera setTorchMode:true level.doubleValue]; + [_camera setTorchMode:true level:doubleValue]; result(nil); } else if ([@"torchOff" isEqualToString:call.method]) { [_camera setTorchMode:false]; From de899461c2376587e65a33874e4665767e21bb71 Mon Sep 17 00:00:00 2001 From: NeKo Date: Sat, 10 Aug 2019 20:59:19 +0200 Subject: [PATCH 12/30] [camera] fix ios code format --- packages/camera/ios/Classes/CameraPlugin.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/camera/ios/Classes/CameraPlugin.m b/packages/camera/ios/Classes/CameraPlugin.m index bd09a66609d5..224cdea1a7a0 100644 --- a/packages/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/ios/Classes/CameraPlugin.m @@ -600,8 +600,7 @@ - (bool)hasTorch { return ([device hasTorch] && [device hasFlash]); } -- (void)setTorchMode:(NSNumber *)enable - level:(float)level { +- (void)setTorchMode:(NSNumber *)enable level:(float)level { AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; if ([device hasTorch] && [device hasFlash]) { [device lockForConfiguration:nil]; From d2b876f5796f4d376cc6290452d98bce5b142fa7 Mon Sep 17 00:00:00 2001 From: NeKo Date: Sun, 11 Aug 2019 00:05:51 +0200 Subject: [PATCH 13/30] [camera] fix ios code --- packages/camera/ios/Classes/CameraPlugin.m | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/packages/camera/ios/Classes/CameraPlugin.m b/packages/camera/ios/Classes/CameraPlugin.m index 224cdea1a7a0..3f9c217c779e 100644 --- a/packages/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/ios/Classes/CameraPlugin.m @@ -197,6 +197,9 @@ - (void)stopVideoRecordingWithResult:(FlutterResult)result; - (void)startImageStreamWithMessenger:(NSObject *)messenger; - (void)stopImageStream; - (void)captureToFile:(NSString *)filename result:(FlutterResult)result; +- (void)setTorchMode:(BOOL)enable level:(float)level; +- (void)setTorchMode:(BOOL)enable; +- (void)setAEMode:(BOOL)enable; @end @implementation FLTCam { @@ -220,8 +223,6 @@ - (instancetype)initWithCameraName:(NSString *)cameraName *error = e; } _enableAudio = enableAudio; - _enableTorch = enableTorch; - _enableAE = enableAE; _dispatchQueue = dispatchQueue; _captureSession = [[AVCaptureSession alloc] init]; @@ -600,7 +601,11 @@ - (bool)hasTorch { return ([device hasTorch] && [device hasFlash]); } -- (void)setTorchMode:(NSNumber *)enable level:(float)level { +- (void)setTorchMode:(BOOL)enable level:(float)level { + [self setTorchMode:enable level:1.0]; +} + +- (void)setTorchMode:(BOOL)enable level:(float)level { AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; if ([device hasTorch] && [device hasFlash]) { [device lockForConfiguration:nil]; @@ -617,7 +622,7 @@ - (void)setTorchMode:(NSNumber *)enable level:(float)level { } } -- (void)setAEMode:(NSNumber *)enable { +- (void)setAEMode:(BOOL)enable { AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; [device lockForConfiguration:nil]; if (enable) { @@ -837,6 +842,12 @@ - (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)re } else if ([@"torchOff" isEqualToString:call.method]) { [_camera setTorchMode:false]; result(nil); + } else if ([@"aeOn" isEqualToString:call.method]) { + [_camera setAEMode:true]; + result(nil); + } else if ([@"aeOff" isEqualToString:call.method]) { + [_camera setAEMode:false]; + result(nil); } else { NSDictionary *argsMap = call.arguments; NSUInteger textureId = ((NSNumber *)argsMap[@"textureId"]).unsignedIntegerValue; From 4c18d55b40021b8511008f22477b960013a7e5f0 Mon Sep 17 00:00:00 2001 From: NeKo Date: Sat, 10 Aug 2019 19:55:55 +0200 Subject: [PATCH 14/30] [camera] delete a blank line for the pleasure of the CI --- packages/camera/ios/Classes/CameraPlugin.m | 41 +++++++++++++--------- packages/camera/lib/camera.dart | 1 - 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/packages/camera/ios/Classes/CameraPlugin.m b/packages/camera/ios/Classes/CameraPlugin.m index 7916d539b199..3f9c217c779e 100644 --- a/packages/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/ios/Classes/CameraPlugin.m @@ -197,6 +197,9 @@ - (void)stopVideoRecordingWithResult:(FlutterResult)result; - (void)startImageStreamWithMessenger:(NSObject *)messenger; - (void)stopImageStream; - (void)captureToFile:(NSString *)filename result:(FlutterResult)result; +- (void)setTorchMode:(BOOL)enable level:(float)level; +- (void)setTorchMode:(BOOL)enable; +- (void)setAEMode:(BOOL)enable; @end @implementation FLTCam { @@ -220,8 +223,6 @@ - (instancetype)initWithCameraName:(NSString *)cameraName *error = e; } _enableAudio = enableAudio; - _enableTorch = enableTorch; - _enableAE = enableAE; _dispatchQueue = dispatchQueue; _captureSession = [[AVCaptureSession alloc] init]; @@ -259,11 +260,11 @@ - (instancetype)initWithCameraName:(NSString *)cameraName [self setCaptureSessionPreset:resolutionPreset]; if (enableTorch) { - [self setTorchMode:enableTorch]; + [self setTorchMode:[enableTorch boolValue]]; } if (enableAE) { - [self setAEMode:enableAE]; + [self setAEMode:[enableAE boolValue]]; } return self; @@ -600,7 +601,11 @@ - (bool)hasTorch { return ([device hasTorch] && [device hasFlash]); } -- (void)setTorchMode:(NSNumber)enable(float)level { +- (void)setTorchMode:(BOOL)enable level:(float)level { + [self setTorchMode:enable level:1.0]; +} + +- (void)setTorchMode:(BOOL)enable level:(float)level { AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; if ([device hasTorch] && [device hasFlash]) { [device lockForConfiguration:nil]; @@ -617,18 +622,16 @@ - (void)setTorchMode:(NSNumber)enable(float)level { } } -- (void)setAEMode:(NSNumber)enable { +- (void)setAEMode:(BOOL)enable { AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; - if ([device isExposureModeSupported:AVCaptureDevice.ExposureMode]) { - [device lockForConfiguration:nil]; - if (enable) { - AVCaptureDevice.ExposureMode exposure = AVCaptureDevice.ExposureMode.continuousAutoExposure; - if (exposure && [device isExposureModeSupported:exposure]) [device exposureMode:exposure]; - } else { - [device exposureMode:AVCaptureDevice.ExposureMode.autoExpose]; - } - [device unlockForConfiguration]; + [device lockForConfiguration:nil]; + if (enable) { + int exposure = AVCaptureDevice.ExposureMode.continuousAutoExposure; + if (exposure && [device isExposureModeSupported:exposure]) [device exposureMode:exposure]; + } else { + [device exposureMode:AVCaptureDevice.ExposureMode.autoExpose]; } + [device unlockForConfiguration]; } - (BOOL)setupWriterForPath:(NSString *)path { @@ -834,11 +837,17 @@ - (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)re result([NSNumber numberWithBool:[_camera hasTorch]]); } else if ([@"torchOn" isEqualToString:call.method]) { NSNumber *level = call.arguments[@"level"]; - [_camera setTorchMode:true level.doubleValue]; + [_camera setTorchMode:true level:doubleValue]; result(nil); } else if ([@"torchOff" isEqualToString:call.method]) { [_camera setTorchMode:false]; result(nil); + } else if ([@"aeOn" isEqualToString:call.method]) { + [_camera setAEMode:true]; + result(nil); + } else if ([@"aeOff" isEqualToString:call.method]) { + [_camera setAEMode:false]; + result(nil); } else { NSDictionary *argsMap = call.arguments; NSUInteger textureId = ((NSNumber *)argsMap[@"textureId"]).unsignedIntegerValue; diff --git a/packages/camera/lib/camera.dart b/packages/camera/lib/camera.dart index 5c1dede20c39..097d21de3af5 100644 --- a/packages/camera/lib/camera.dart +++ b/packages/camera/lib/camera.dart @@ -250,7 +250,6 @@ class CameraController extends ValueNotifier { // Auto Exposure final bool enableAE; - int _textureId; bool _isDisposed = false; StreamSubscription _eventSubscription; From 6d4ef4171d28acbd554e8b17ed04c8ee6e41a231 Mon Sep 17 00:00:00 2001 From: NeKo Date: Sun, 11 Aug 2019 02:08:41 +0200 Subject: [PATCH 15/30] [camera] fix iOS mistakes like default value for the setTorchMode and Exposure settings --- packages/camera/ios/Classes/CameraPlugin.m | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/camera/ios/Classes/CameraPlugin.m b/packages/camera/ios/Classes/CameraPlugin.m index 3f9c217c779e..9feed01ceeba 100644 --- a/packages/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/ios/Classes/CameraPlugin.m @@ -601,7 +601,7 @@ - (bool)hasTorch { return ([device hasTorch] && [device hasFlash]); } -- (void)setTorchMode:(BOOL)enable level:(float)level { +- (void)setTorchMode:(BOOL)enable { [self setTorchMode:enable level:1.0]; } @@ -627,9 +627,9 @@ - (void)setAEMode:(BOOL)enable { [device lockForConfiguration:nil]; if (enable) { int exposure = AVCaptureDevice.ExposureMode.continuousAutoExposure; - if (exposure && [device isExposureModeSupported:exposure]) [device exposureMode:exposure]; + if (exposure && [device isExposureModeSupported:exposure]) device.exposureMode = exposure; } else { - [device exposureMode:AVCaptureDevice.ExposureMode.autoExpose]; + device.exposureMode = AVCaptureDevice.ExposureMode.autoExpose; } [device unlockForConfiguration]; } @@ -837,7 +837,7 @@ - (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)re result([NSNumber numberWithBool:[_camera hasTorch]]); } else if ([@"torchOn" isEqualToString:call.method]) { NSNumber *level = call.arguments[@"level"]; - [_camera setTorchMode:true level:doubleValue]; + [_camera setTorchMode:true level:level]; result(nil); } else if ([@"torchOff" isEqualToString:call.method]) { [_camera setTorchMode:false]; From dd8f6f369c20c5b7598a9e0b169f117e30c728c2 Mon Sep 17 00:00:00 2001 From: NeKo Date: Sun, 11 Aug 2019 02:59:18 +0200 Subject: [PATCH 16/30] [camera] fix iOS code --- packages/camera/ios/Classes/CameraPlugin.m | 28 +++++++++++++++------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/packages/camera/ios/Classes/CameraPlugin.m b/packages/camera/ios/Classes/CameraPlugin.m index bd09a66609d5..d08658257391 100644 --- a/packages/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/ios/Classes/CameraPlugin.m @@ -197,6 +197,9 @@ - (void)stopVideoRecordingWithResult:(FlutterResult)result; - (void)startImageStreamWithMessenger:(NSObject *)messenger; - (void)stopImageStream; - (void)captureToFile:(NSString *)filename result:(FlutterResult)result; +- (void)setTorchMode:(BOOL)enable level:(float)level; +- (void)setTorchMode:(BOOL)enable; +- (void)setAEMode:(BOOL)enable; @end @implementation FLTCam { @@ -220,8 +223,6 @@ - (instancetype)initWithCameraName:(NSString *)cameraName *error = e; } _enableAudio = enableAudio; - _enableTorch = enableTorch; - _enableAE = enableAE; _dispatchQueue = dispatchQueue; _captureSession = [[AVCaptureSession alloc] init]; @@ -255,8 +256,8 @@ - (instancetype)initWithCameraName:(NSString *)cameraName [_captureSession addOutput:_capturePhotoOutput]; _motionManager = [[CMMotionManager alloc] init]; [_motionManager startAccelerometerUpdates]; + [self setCaptureSessionPreset:_resolutionPreset]; - [self setCaptureSessionPreset:resolutionPreset]; if (enableTorch) { [self setTorchMode:[enableTorch boolValue]]; @@ -600,8 +601,11 @@ - (bool)hasTorch { return ([device hasTorch] && [device hasFlash]); } -- (void)setTorchMode:(NSNumber *)enable - level:(float)level { +- (void)setTorchMode:(BOOL)enable { + [self setTorchMode:enable level:1.0]; +} + +- (void)setTorchMode:(BOOL)enable level:(float)level { AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; if ([device hasTorch] && [device hasFlash]) { [device lockForConfiguration:nil]; @@ -618,14 +622,14 @@ - (void)setTorchMode:(NSNumber *)enable } } -- (void)setAEMode:(NSNumber *)enable { +- (void)setAEMode:(BOOL)enable { AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; [device lockForConfiguration:nil]; if (enable) { int exposure = AVCaptureDevice.ExposureMode.continuousAutoExposure; - if (exposure && [device isExposureModeSupported:exposure]) [device exposureMode:exposure]; + if (exposure && [device isExposureModeSupported:exposure]) device.exposureMode = exposure; } else { - [device exposureMode:AVCaptureDevice.ExposureMode.autoExpose]; + device.exposureMode = AVCaptureDevice.ExposureMode.autoExpose; } [device unlockForConfiguration]; } @@ -833,11 +837,17 @@ - (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)re result([NSNumber numberWithBool:[_camera hasTorch]]); } else if ([@"torchOn" isEqualToString:call.method]) { NSNumber *level = call.arguments[@"level"]; - [_camera setTorchMode:true level:doubleValue]; + [_camera setTorchMode:true level:level]; result(nil); } else if ([@"torchOff" isEqualToString:call.method]) { [_camera setTorchMode:false]; result(nil); + } else if ([@"aeOn" isEqualToString:call.method]) { + [_camera setAEMode:true]; + result(nil); + } else if ([@"aeOff" isEqualToString:call.method]) { + [_camera setAEMode:false]; + result(nil); } else { NSDictionary *argsMap = call.arguments; NSUInteger textureId = ((NSNumber *)argsMap[@"textureId"]).unsignedIntegerValue; From 1d8d34a0ed47701aee6637f5b25752b2510ac9cb Mon Sep 17 00:00:00 2001 From: NeKo Date: Sun, 11 Aug 2019 03:41:13 +0200 Subject: [PATCH 17/30] [camera] fix enum to choose Exposure --- packages/camera/ios/Classes/CameraPlugin.m | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/camera/ios/Classes/CameraPlugin.m b/packages/camera/ios/Classes/CameraPlugin.m index d08658257391..f0e9093c153b 100644 --- a/packages/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/ios/Classes/CameraPlugin.m @@ -260,11 +260,11 @@ - (instancetype)initWithCameraName:(NSString *)cameraName [self setCaptureSessionPreset:_resolutionPreset]; if (enableTorch) { - [self setTorchMode:[enableTorch boolValue]]; + [self setTorchMode:enableTorch]; } if (enableAE) { - [self setAEMode:[enableAE boolValue]]; + [self setAEMode:enableAE]; } return self; @@ -626,10 +626,10 @@ - (void)setAEMode:(BOOL)enable { AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; [device lockForConfiguration:nil]; if (enable) { - int exposure = AVCaptureDevice.ExposureMode.continuousAutoExposure; + int exposure = AVCaptureExposureModeContinuousAutoExposure; if (exposure && [device isExposureModeSupported:exposure]) device.exposureMode = exposure; } else { - device.exposureMode = AVCaptureDevice.ExposureMode.autoExpose; + device.exposureMode = AVCaptureExposureModeAutoExpose; } [device unlockForConfiguration]; } From 5b622cfc734ea0509c5475934e8a248785d8524a Mon Sep 17 00:00:00 2001 From: NeKo Date: Sun, 11 Aug 2019 04:19:32 +0200 Subject: [PATCH 18/30] [camera] fix float casting in iOS code --- packages/camera/ios/Classes/CameraPlugin.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/camera/ios/Classes/CameraPlugin.m b/packages/camera/ios/Classes/CameraPlugin.m index f0e9093c153b..dace338f8c71 100644 --- a/packages/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/ios/Classes/CameraPlugin.m @@ -837,7 +837,7 @@ - (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)re result([NSNumber numberWithBool:[_camera hasTorch]]); } else if ([@"torchOn" isEqualToString:call.method]) { NSNumber *level = call.arguments[@"level"]; - [_camera setTorchMode:true level:level]; + [_camera setTorchMode:true level:[level floatValue]]; result(nil); } else if ([@"torchOff" isEqualToString:call.method]) { [_camera setTorchMode:false]; From 05adac8c6d4ed3a8a61afc389afae7bc01920a7c Mon Sep 17 00:00:00 2001 From: NeKo Date: Sun, 11 Aug 2019 12:22:09 +0200 Subject: [PATCH 19/30] [camera] Update example --- packages/camera/example/lib/main.dart | 44 ++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/packages/camera/example/lib/main.dart b/packages/camera/example/lib/main.dart index 10b0ff9201a1..221eb6c3278c 100644 --- a/packages/camera/example/lib/main.dart +++ b/packages/camera/example/lib/main.dart @@ -37,6 +37,7 @@ class _CameraExampleHomeState extends State VideoPlayerController videoController; VoidCallback videoPlayerListener; bool enableAudio = true; + bool enableTorch = false; @override void initState() { @@ -96,7 +97,12 @@ class _CameraExampleHomeState extends State ), ), _captureControlRowWidget(), - _toggleAudioWidget(), + Row( + children: [ + _toggleAudioWidget(), + _toggleTorchWidget(), + ], + ), Padding( padding: const EdgeInsets.all(5.0), child: Row( @@ -152,6 +158,42 @@ class _CameraExampleHomeState extends State ); } + /// Display the Torch Switch + Widget _toggleTorchWidget() { + return Padding( + padding: const EdgeInsets.only(left: 25), + child: Row( + children: [ + const Text('Enable Torch:'), + Switch( + value: enableTorch, + onChanged: _toggleTorch + ), + ], + ), + ); + } + + /// Toggle Torch + Future _toggleTorch(bool value) async { + bool hasTorch = false; + + if(controller != null) { + hasTorch = await controller.hasTorch; + } + + if (hasTorch) { + enableTorch = value; + if(enableTorch){ + controller.torchOn(); + }else{ + controller.torchOff(); + } + } + + setState(() {}); + } + /// Display the thumbnail of the captured image or video. Widget _thumbnailWidget() { return Expanded( From 460596166b476c2db942b0c0d4cf738cc84b916a Mon Sep 17 00:00:00 2001 From: NeKo Date: Sun, 11 Aug 2019 12:29:29 +0200 Subject: [PATCH 20/30] [camera] Fix format --- packages/camera/example/lib/main.dart | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/packages/camera/example/lib/main.dart b/packages/camera/example/lib/main.dart index 221eb6c3278c..7a65de86a698 100644 --- a/packages/camera/example/lib/main.dart +++ b/packages/camera/example/lib/main.dart @@ -98,7 +98,7 @@ class _CameraExampleHomeState extends State ), _captureControlRowWidget(), Row( - children: [ + children: [ _toggleAudioWidget(), _toggleTorchWidget(), ], @@ -165,10 +165,7 @@ class _CameraExampleHomeState extends State child: Row( children: [ const Text('Enable Torch:'), - Switch( - value: enableTorch, - onChanged: _toggleTorch - ), + Switch(value: enableTorch, onChanged: _toggleTorch), ], ), ); @@ -178,15 +175,15 @@ class _CameraExampleHomeState extends State Future _toggleTorch(bool value) async { bool hasTorch = false; - if(controller != null) { + if (controller != null) { hasTorch = await controller.hasTorch; } if (hasTorch) { enableTorch = value; - if(enableTorch){ + if (enableTorch) { controller.torchOn(); - }else{ + } else { controller.torchOff(); } } From 7b64146c285606cd79d01849622869373eeba414 Mon Sep 17 00:00:00 2001 From: NeKo Date: Fri, 16 Aug 2019 09:51:08 +0200 Subject: [PATCH 21/30] [camera] Replace the term 'Torch' by 'Flash' + Increment the minor version number to 0.5.4 + Remove abbreviation AE + Add more comments --- packages/camera/CHANGELOG.md | 4 +- .../io/flutter/plugins/camera/Camera.java | 39 +++++----- .../flutter/plugins/camera/CameraPlugin.java | 30 ++++---- packages/camera/example/lib/main.dart | 30 ++++---- packages/camera/ios/Classes/CameraPlugin.m | 74 +++++++++---------- packages/camera/lib/camera.dart | 52 ++++++------- packages/camera/pubspec.yaml | 2 +- 7 files changed, 118 insertions(+), 113 deletions(-) diff --git a/packages/camera/CHANGELOG.md b/packages/camera/CHANGELOG.md index b7c25cbb3451..1a8ad41ee149 100644 --- a/packages/camera/CHANGELOG.md +++ b/packages/camera/CHANGELOG.md @@ -1,7 +1,9 @@ +## 0.5.4 +* Add support for Flash and Auto Exposure + ## 0.5.3 * Added new quality presets. * Now all quality presets can be used to control image capture quality. -* Add support for Torch and Auto Exposure ## 0.5.2+2 diff --git a/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index 4aece7713a17..89fc5b4be7c6 100644 --- a/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -49,8 +49,8 @@ public class Camera { private final Size captureSize; private final Size previewSize; private final boolean enableAudio; - private final boolean enableTorch; - private final boolean enableAE; + private final boolean enableFlash; + private final boolean enableAutoExposure; private CameraDevice cameraDevice; private CameraCaptureSession cameraCaptureSession; @@ -79,8 +79,8 @@ public Camera( final String cameraName, final String resolutionPreset, final boolean enableAudio, - final boolean enableTorch, - final boolean enableAE) + final boolean enableFlash, + final boolean enableAutoExposure) throws CameraAccessException { if (activity == null) { throw new IllegalStateException("No activity available!"); @@ -88,8 +88,8 @@ public Camera( this.cameraName = cameraName; this.enableAudio = enableAudio; - this.enableTorch = enableTorch; - this.enableAE = enableAE; + this.enableFlash = enableFlash; + this.enableAutoExposure = enableAutoExposure; this.flutterTexture = flutterView.createSurfaceTexture(); this.cameraManager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE); orientationEventListener = @@ -325,15 +325,15 @@ private void createCaptureSession( } } - // Torch + // Request initial Flash mode captureRequestBuilder.set( CaptureRequest.FLASH_MODE, - enableTorch ? CaptureRequest.FLASH_MODE_TORCH : CaptureRequest.FLASH_MODE_OFF); + enableFlash ? CaptureRequest.FLASH_MODE_TORCH : CaptureRequest.FLASH_MODE_OFF); - // Auto Exposure + // Request initial Auto Exposure mode captureRequestBuilder.set( CaptureRequest.CONTROL_AE_MODE, - enableAE ? CaptureRequest.CONTROL_AE_MODE_ON : CaptureRequest.CONTROL_AE_MODE_OFF); + enableAutoExposure ? CaptureRequest.CONTROL_AE_MODE_ON : CaptureRequest.CONTROL_AE_MODE_OFF); // Prepare the callback CameraCaptureSession.StateCallback callback = @@ -460,17 +460,20 @@ private void setImageStreamImageAvailableListener(final EventChannel.EventSink i null); } - // Torch - public void setTorchMode(@NonNull final Result result, boolean enable) { - setTorchMode(result, enable, 1.0); + public void setFlashMode(@NonNull final Result result, boolean enable) { + setFlashMode(result, enable, 1.0); } - public void setTorchMode(@NonNull final Result result, boolean enable, double level) { + public void setFlashMode(@NonNull final Result result, boolean enable, double level) { try { + // Request Flash mode captureRequestBuilder.set( CaptureRequest.FLASH_MODE, enable ? CaptureRequest.FLASH_MODE_TORCH : CaptureRequest.FLASH_MODE_OFF); + // Request Auto Exposure mode as recommended when you switch the Flash + // more information: + // https://developer.android.com/reference/android/hardware/camera2/CaptureRequest.html#FLASH_MODE captureRequestBuilder.set( CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START); @@ -478,13 +481,13 @@ public void setTorchMode(@NonNull final Result result, boolean enable, double le cameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null); result.success(null); } catch (Exception e) { - result.error("cameraTorchFailed", e.getMessage(), null); + result.error("cameraFlashFailed", e.getMessage(), null); } } - public void setAEMode(@NonNull final Result result, boolean enable) { + public void setAutoExposureMode(@NonNull final Result result, boolean enable) { try { - // Auto Exposure + // Request Auto Exposure mode captureRequestBuilder.set( CaptureRequest.CONTROL_AE_MODE, enable ? CaptureRequest.CONTROL_AE_MODE_ON : CaptureRequest.CONTROL_AE_MODE_OFF); @@ -492,7 +495,7 @@ public void setAEMode(@NonNull final Result result, boolean enable) { cameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null); result.success(null); } catch (Exception e) { - result.error("cameraAEFailed", e.getMessage(), null); + result.error("cameraAutoExposureFailed", e.getMessage(), null); } } diff --git a/packages/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java b/packages/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java index 624adc91dea9..88b2752a61c4 100644 --- a/packages/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java +++ b/packages/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java @@ -45,8 +45,8 @@ private void instantiateCamera(MethodCall call, Result result) throws CameraAcce String cameraName = call.argument("cameraName"); String resolutionPreset = call.argument("resolutionPreset"); boolean enableAudio = call.argument("enableAudio"); - boolean enableTorch = call.argument("enableTorch"); - boolean enableAE = call.argument("enableAE"); + boolean enableFlash = call.argument("enableFlash"); + boolean enableAutoExposure = call.argument("enableAutoExposure"); camera = new Camera( registrar.activity(), @@ -54,8 +54,8 @@ private void instantiateCamera(MethodCall call, Result result) throws CameraAcce cameraName, resolutionPreset, enableAudio, - enableTorch, - enableAE); + enableFlash, + enableAutoExposure); EventChannel cameraEventChannel = new EventChannel( @@ -139,29 +139,29 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull final Result result) } break; } - case "torchOn": + case "flashOn": { - camera.setTorchMode(result, true, call.argument("level")); + camera.setFlashMode(result, true, call.argument("level")); break; } - case "torchOff": + case "flashOff": { - camera.setTorchMode(result, false); + camera.setFlashMode(result, false); break; } - case "hasTorch": + case "hasFlash": { - result.success(hasTorch()); + result.success(hasFlash()); break; } - case "aeOn": + case "autoExposureOn": { - camera.setAEMode(result, true); + camera.setAutoExposureMode(result, true); break; } - case "aeOff": + case "autoExposureOff": { - camera.setAEMode(result, false); + camera.setAutoExposureMode(result, false); break; } case "dispose": @@ -178,7 +178,7 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull final Result result) } } - private boolean hasTorch() { + private boolean hasFlash() { return registrar .context() .getApplicationContext() diff --git a/packages/camera/example/lib/main.dart b/packages/camera/example/lib/main.dart index 7a65de86a698..30d50ef46ce0 100644 --- a/packages/camera/example/lib/main.dart +++ b/packages/camera/example/lib/main.dart @@ -37,7 +37,7 @@ class _CameraExampleHomeState extends State VideoPlayerController videoController; VoidCallback videoPlayerListener; bool enableAudio = true; - bool enableTorch = false; + bool enableFlash = false; @override void initState() { @@ -100,7 +100,7 @@ class _CameraExampleHomeState extends State Row( children: [ _toggleAudioWidget(), - _toggleTorchWidget(), + _toggleFlashWidget(), ], ), Padding( @@ -158,33 +158,33 @@ class _CameraExampleHomeState extends State ); } - /// Display the Torch Switch - Widget _toggleTorchWidget() { + /// Display the Flash Switch + Widget _toggleFlashWidget() { return Padding( padding: const EdgeInsets.only(left: 25), child: Row( children: [ - const Text('Enable Torch:'), - Switch(value: enableTorch, onChanged: _toggleTorch), + const Text('Enable Flash:'), + Switch(value: enableFlash, onChanged: _toggleFlash), ], ), ); } - /// Toggle Torch - Future _toggleTorch(bool value) async { - bool hasTorch = false; + /// Toggle Flash + Future _toggleFlash(bool value) async { + bool hasFlash = false; if (controller != null) { - hasTorch = await controller.hasTorch; + hasFlash = await controller.hasFlash; } - if (hasTorch) { - enableTorch = value; - if (enableTorch) { - controller.torchOn(); + if (hasFlash) { + enableFlash = value; + if (enableFlash) { + controller.flashOn(); } else { - controller.torchOff(); + controller.flashOff(); } } diff --git a/packages/camera/ios/Classes/CameraPlugin.m b/packages/camera/ios/Classes/CameraPlugin.m index dace338f8c71..7f142b980d82 100644 --- a/packages/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/ios/Classes/CameraPlugin.m @@ -158,8 +158,8 @@ @interface FLTCam : NSObject *)messenger; - (void)stopImageStream; - (void)captureToFile:(NSString *)filename result:(FlutterResult)result; -- (void)setTorchMode:(BOOL)enable level:(float)level; -- (void)setTorchMode:(BOOL)enable; -- (void)setAEMode:(BOOL)enable; +- (void)setFlashMode:(BOOL)enable level:(float)level; +- (void)setFlashMode:(BOOL)enable; +- (void)setAutoExposureMode:(BOOL)enable; @end @implementation FLTCam { @@ -211,8 +211,8 @@ @implementation FLTCam { - (instancetype)initWithCameraName:(NSString *)cameraName resolutionPreset:(NSString *)resolutionPreset enableAudio:(BOOL)enableAudio - enableTorch:(BOOL)enableTorch - enableAE:(BOOL)enableAE + enableFlash:(BOOL)enableFlash + enableAutoExposure:(BOOL)enableAutoExposure dispatchQueue:(dispatch_queue_t)dispatchQueue error:(NSError **)error { self = [super init]; @@ -259,12 +259,12 @@ - (instancetype)initWithCameraName:(NSString *)cameraName [self setCaptureSessionPreset:_resolutionPreset]; - if (enableTorch) { - [self setTorchMode:enableTorch]; + if (enableFlash) { + [self setFlashMode:enableFlash]; } - if (enableAE) { - [self setAEMode:enableAE]; + if (enableAutoExposure) { + [self setAutoExposureMode:enableAutoExposure]; } return self; @@ -596,33 +596,33 @@ - (void)stopImageStream { } } -- (bool)hasTorch { +- (bool)hasFlash { AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; - return ([device hasTorch] && [device hasFlash]); + return ([device hasFlash] && [device hasFlash]); } -- (void)setTorchMode:(BOOL)enable { - [self setTorchMode:enable level:1.0]; +- (void)setFlashMode:(BOOL)enable { + [self setFlashMode:enable level:1.0]; } -- (void)setTorchMode:(BOOL)enable level:(float)level { +- (void)setFlashMode:(BOOL)enable level:(float)level { AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; - if ([device hasTorch] && [device hasFlash]) { + if ([device hasFlash] && [device hasFlash]) { [device lockForConfiguration:nil]; if (enable) { NSError *error = nil; float acceptedLevel = - (level < AVCaptureMaxAvailableTorchLevel ? level : AVCaptureMaxAvailableTorchLevel); + (level < AVCaptureMaxAvailableFlashLevel ? level : AVCaptureMaxAvailableFlashLevel); NSLog(@"FLash level: %f", acceptedLevel); - [device setTorchModeOnWithLevel:acceptedLevel error:&error]; + [device setFlashModeOnWithLevel:acceptedLevel error:&error]; } else { - [device setTorchMode:AVCaptureTorchModeOff]; + [device setFlashMode:AVCaptureFlashModeOff]; } [device unlockForConfiguration]; } } -- (void)setAEMode:(BOOL)enable { +- (void)setAutoExposureMode:(BOOL)enable { AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; [device lockForConfiguration:nil]; if (enable) { @@ -790,14 +790,14 @@ - (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)re NSString *cameraName = call.arguments[@"cameraName"]; NSString *resolutionPreset = call.arguments[@"resolutionPreset"]; NSNumber *enableAudio = call.arguments[@"enableAudio"]; - NSNumber *enableTorch = call.arguments[@"enableTorch"]; - NSNumber *enableAE = call.arguments[@"enableAE"]; + NSNumber *enableFlash = call.arguments[@"enableFlash"]; + NSNumber *enableAutoExposure = call.arguments[@"enableAutoExposure"]; NSError *error; FLTCam *cam = [[FLTCam alloc] initWithCameraName:cameraName resolutionPreset:resolutionPreset enableAudio:[enableAudio boolValue] - enableTorch:[enableTorch boolValue] - enableAE:[enableAE boolValue] + enableFlash:[enableFlash boolValue] + enableAutoExposure:[enableAutoExposure boolValue] dispatchQueue:_dispatchQueue error:&error]; if (error) { @@ -833,20 +833,20 @@ - (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)re } else if ([@"stopImageStream" isEqualToString:call.method]) { [_camera stopImageStream]; result(nil); - } else if ([@"hasTorch" isEqualToString:call.method]) { - result([NSNumber numberWithBool:[_camera hasTorch]]); - } else if ([@"torchOn" isEqualToString:call.method]) { + } else if ([@"hasFlash" isEqualToString:call.method]) { + result([NSNumber numberWithBool:[_camera hasFlash]]); + } else if ([@"flashOn" isEqualToString:call.method]) { NSNumber *level = call.arguments[@"level"]; - [_camera setTorchMode:true level:[level floatValue]]; + [_camera setFlashMode:true level:[level floatValue]]; result(nil); - } else if ([@"torchOff" isEqualToString:call.method]) { - [_camera setTorchMode:false]; + } else if ([@"flashOff" isEqualToString:call.method]) { + [_camera setFlashMode:false]; result(nil); - } else if ([@"aeOn" isEqualToString:call.method]) { - [_camera setAEMode:true]; + } else if ([@"autoExposureOn" isEqualToString:call.method]) { + [_camera setAutoExposureMode:true]; result(nil); - } else if ([@"aeOff" isEqualToString:call.method]) { - [_camera setAEMode:false]; + } else if ([@"autoExposureOff" isEqualToString:call.method]) { + [_camera setAutoExposureMode:false]; result(nil); } else { NSDictionary *argsMap = call.arguments; diff --git a/packages/camera/lib/camera.dart b/packages/camera/lib/camera.dart index 097d21de3af5..8d495161b7b8 100644 --- a/packages/camera/lib/camera.dart +++ b/packages/camera/lib/camera.dart @@ -234,8 +234,8 @@ class CameraController extends ValueNotifier { this.description, this.resolutionPreset, { this.enableAudio = true, - this.enableTorch = false, - this.enableAE = true, + this.enableFlash = false, + this.enableAutoExposure = true, }) : super(const CameraValue.uninitialized()); final CameraDescription description; @@ -244,11 +244,11 @@ class CameraController extends ValueNotifier { /// Whether to include audio when recording a video. final bool enableAudio; - // Torch - final bool enableTorch; + /// Switch ON the flash when a camera is initialized + final bool enableFlash; - // Auto Exposure - final bool enableAE; + /// Switch ON the Auto Exposure when a camera is initialized + final bool enableAutoExposure; int _textureId; bool _isDisposed = false; @@ -272,8 +272,8 @@ class CameraController extends ValueNotifier { 'cameraName': description.name, 'resolutionPreset': serializeResolutionPreset(resolutionPreset), 'enableAudio': enableAudio, - 'enableTorch': enableTorch, - 'enableAE': enableAE, + 'enableFlash': enableFlash, + 'enableAutoExposure': enableAutoExposure, }, ); _textureId = reply['textureId']; @@ -515,82 +515,82 @@ class CameraController extends ValueNotifier { } } - /// Switch ON the torch. - Future torchOn({double level = 1.0}) async { + /// Switch ON the flash. + Future flashOn({double level = 1.0}) async { if (!value.isInitialized || _isDisposed) { throw CameraException( 'Uninitialized CameraController.', - 'torchOn was called on uninitialized CameraController', + 'flashOn was called on uninitialized CameraController', ); } try { await _channel - .invokeMethod('torchOn', {'level': level}); + .invokeMethod('flashOn', {'level': level}); } on PlatformException catch (e) { throw CameraException(e.code, e.message); } } - /// Switch OFF the torch. - Future torchOff() async { + /// Switch OFF the flash. + Future flashOff() async { if (!value.isInitialized || _isDisposed) { throw CameraException( 'Uninitialized CameraController.', - 'torchOff was called on uninitialized CameraController', + 'flashOff was called on uninitialized CameraController', ); } try { - await _channel.invokeMethod('torchOff'); + await _channel.invokeMethod('flashOff'); } on PlatformException catch (e) { throw CameraException(e.code, e.message); } } - /// check if the device has a torch. - Future get hasTorch async { + /// check if the device has a flash. + Future get hasFlash async { if (!value.isInitialized || _isDisposed) { throw CameraException( 'Uninitialized CameraController.', - 'hasTorch was called on uninitialized CameraController', + 'hasFlash was called on uninitialized CameraController', ); } try { - return await _channel.invokeMethod('hasTorch'); + return await _channel.invokeMethod('hasFlash'); } on PlatformException catch (e) { throw CameraException(e.code, e.message); } } /// Switch ON continuous Auto Exposure. - Future aeOn() async { + Future autoExposureOn() async { if (!value.isInitialized || _isDisposed) { throw CameraException( 'Uninitialized CameraController.', - 'aeOn was called on uninitialized CameraController', + 'autoExposureOn was called on uninitialized CameraController', ); } try { - await _channel.invokeMethod('aeOn'); + await _channel.invokeMethod('autoExposureOn'); } on PlatformException catch (e) { throw CameraException(e.code, e.message); } } /// Switch OFF continuous Auto Exposure. - Future aeOff() async { + Future autoExposureOff() async { if (!value.isInitialized || _isDisposed) { throw CameraException( 'Uninitialized CameraController.', - 'aeOff was called on uninitialized CameraController', + 'autoExposureOff was called on uninitialized CameraController', ); } try { - await _channel.invokeMethod('aeOff'); + await _channel.invokeMethod('autoExposureOff'); } on PlatformException catch (e) { throw CameraException(e.code, e.message); } diff --git a/packages/camera/pubspec.yaml b/packages/camera/pubspec.yaml index 3e290f10568d..e94d4bd979f0 100644 --- a/packages/camera/pubspec.yaml +++ b/packages/camera/pubspec.yaml @@ -2,7 +2,7 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.5.3 +version: 0.5.4 authors: - Flutter Team From 87418901a5730fc037eecdd9860a1ff81cc76836 Mon Sep 17 00:00:00 2001 From: NeKo Date: Fri, 16 Aug 2019 09:57:43 +0200 Subject: [PATCH 22/30] [camera] Fix format --- .../src/main/java/io/flutter/plugins/camera/Camera.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index 89fc5b4be7c6..6404d8bee34d 100644 --- a/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -328,7 +328,9 @@ private void createCaptureSession( // Request initial Flash mode captureRequestBuilder.set( CaptureRequest.FLASH_MODE, - enableFlash ? CaptureRequest.FLASH_MODE_TORCH : CaptureRequest.FLASH_MODE_OFF); + enableFlash + ? CaptureRequest.FLASH_MODE_TORCH + : CaptureRequest.FLASH_MODE_OFF); // Request initial Auto Exposure mode captureRequestBuilder.set( From 97246798696428eac30b91fb1db677219f175054 Mon Sep 17 00:00:00 2001 From: NeKo Date: Fri, 16 Aug 2019 09:57:43 +0200 Subject: [PATCH 23/30] [camera] Fix format --- .../src/main/java/io/flutter/plugins/camera/Camera.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index 89fc5b4be7c6..436ae1966787 100644 --- a/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -333,7 +333,9 @@ private void createCaptureSession( // Request initial Auto Exposure mode captureRequestBuilder.set( CaptureRequest.CONTROL_AE_MODE, - enableAutoExposure ? CaptureRequest.CONTROL_AE_MODE_ON : CaptureRequest.CONTROL_AE_MODE_OFF); + enableAutoExposure + ? CaptureRequest.CONTROL_AE_MODE_ON + : CaptureRequest.CONTROL_AE_MODE_OFF); // Prepare the callback CameraCaptureSession.StateCallback callback = From 36ddfd6b174725a86ab104f7973c4591bf543e09 Mon Sep 17 00:00:00 2001 From: NeKo Date: Fri, 16 Aug 2019 10:24:31 +0200 Subject: [PATCH 24/30] [camera] Fix format again --- .../src/main/java/io/flutter/plugins/camera/Camera.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index a7f44ce239e8..436ae1966787 100644 --- a/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -328,9 +328,7 @@ private void createCaptureSession( // Request initial Flash mode captureRequestBuilder.set( CaptureRequest.FLASH_MODE, - enableFlash - ? CaptureRequest.FLASH_MODE_TORCH - : CaptureRequest.FLASH_MODE_OFF); + enableFlash ? CaptureRequest.FLASH_MODE_TORCH : CaptureRequest.FLASH_MODE_OFF); // Request initial Auto Exposure mode captureRequestBuilder.set( From fea203b410af3c65d4c10b2944b72e8e61452010 Mon Sep 17 00:00:00 2001 From: NeKo Date: Fri, 16 Aug 2019 10:56:28 +0200 Subject: [PATCH 25/30] [camera] Fix iOS error, the iOS SDK use the term "Torch" --- packages/camera/ios/Classes/CameraPlugin.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/camera/ios/Classes/CameraPlugin.m b/packages/camera/ios/Classes/CameraPlugin.m index 739637cd22a5..af95b778d77d 100644 --- a/packages/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/ios/Classes/CameraPlugin.m @@ -616,11 +616,11 @@ - (void)setFlashMode:(BOOL)enable level:(float)level { if (enable) { NSError *error = nil; float acceptedLevel = - (level < AVCaptureMaxAvailableFlashLevel ? level : AVCaptureMaxAvailableFlashLevel); + (level < AVCaptureMaxAvailableTorchLevel ? level : AVCaptureMaxAvailableTorchLevel); NSLog(@"FLash level: %f", acceptedLevel); - [device setFlashModeOnWithLevel:acceptedLevel error:&error]; + [device setTorchModeOnWithLevel:acceptedLevel error:&error]; } else { - [device setFlashMode:AVCaptureFlashModeOff]; + [device setTorchMode:AVCaptureFlashModeOff]; } [device unlockForConfiguration]; } From 3fe609a0637b38658305e659881e0aec236c158b Mon Sep 17 00:00:00 2001 From: NeKo Date: Wed, 25 Sep 2019 20:57:21 +0200 Subject: [PATCH 26/30] [camera] Control flash and focus mode --- .../io/flutter/plugins/camera/Camera.java | 160 +++++++++++++----- .../flutter/plugins/camera/CameraPlugin.java | 26 +-- packages/camera/example/lib/main.dart | 126 ++++++++++---- packages/camera/lib/camera.dart | 98 +++++------ 4 files changed, 267 insertions(+), 143 deletions(-) diff --git a/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index 8d8260b499c6..8fa9a6d725ad 100644 --- a/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -49,9 +49,9 @@ public class Camera { private final Size captureSize; private final Size previewSize; private final boolean enableAudio; - private final boolean enableFlash; - private final boolean enableAutoExposure; + private int flashMode; + private int autoFocusMode; private CameraDevice cameraDevice; private CameraCaptureSession cameraCaptureSession; private ImageReader pictureImageReader; @@ -73,14 +73,28 @@ public enum ResolutionPreset { max, } + // Flash control setting. (Mirrors FlashMode enum in camera.dart) + // Labels respect java convention to avoid conflict with reserved word or any variable name + private final int CAMERA_FLASH_MODE_OFF = 0; + private final int CAMERA_FLASH_MODE_ALWAYS_FLASH = 1; + private final int CAMERA_FLASH_MODE_AUTO_FLASH = 2; + private final int CAMERA_FLASH_MODE_TORCH = 3; + + // Auto Focus setting. (Mirrors AutoFocusMode in camera.dart) + // Labels respect java convention to avoid conflict with reserved word or any variable name + private final int CAMERA_AUTO_FOCUS_MODE_OFF = 0; + private final int CAMERA_AUTO_FOCUS_MODE_AUTO = 1; + private final int CAMERA_AUTO_FOCUS_MODE_CONTINUOUS = 2; + private final int CAMERA_AUTO_FOCUS_MODE_MACRO = 3; + public Camera( final Activity activity, final FlutterView flutterView, final String cameraName, final String resolutionPreset, final boolean enableAudio, - final boolean enableFlash, - final boolean enableAutoExposure) + final int flashMode, + final int autoFocusMode) throws CameraAccessException { if (activity == null) { throw new IllegalStateException("No activity available!"); @@ -88,8 +102,8 @@ public Camera( this.cameraName = cameraName; this.enableAudio = enableAudio; - this.enableFlash = enableFlash; - this.enableAutoExposure = enableAutoExposure; + this.flashMode = flashMode; + this.autoFocusMode = autoFocusMode; this.flutterTexture = flutterView.createSurfaceTexture(); this.cameraManager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE); orientationEventListener = @@ -268,6 +282,9 @@ public void takePicture(String filePath, @NonNull final Result result) { cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); captureBuilder.addTarget(pictureImageReader.getSurface()); captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, getMediaOrientation()); + // Request initial Flash and Auto-Exposure + setFlashModeRequest(captureBuilder, flashMode); + setAutoFocusModeRequest(captureBuilder, autoFocusMode); cameraCaptureSession.capture( captureBuilder.build(), @@ -325,18 +342,6 @@ private void createCaptureSession( } } - // Request initial Flash mode - captureRequestBuilder.set( - CaptureRequest.FLASH_MODE, - enableFlash ? CaptureRequest.FLASH_MODE_TORCH : CaptureRequest.FLASH_MODE_OFF); - - // Request initial Auto Exposure mode - captureRequestBuilder.set( - CaptureRequest.CONTROL_AE_MODE, - enableAutoExposure - ? CaptureRequest.CONTROL_AE_MODE_ON - : CaptureRequest.CONTROL_AE_MODE_OFF); - // Prepare the callback CameraCaptureSession.StateCallback callback = new CameraCaptureSession.StateCallback() { @@ -351,6 +356,10 @@ public void onConfigured(@NonNull CameraCaptureSession session) { captureRequestBuilder.set( CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO); + // Request initial Flash and Auto-Exposure + setFlashModeRequest(captureRequestBuilder, flashMode); + setAutoFocusModeRequest(captureRequestBuilder, autoFocusMode); + cameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null); if (onSuccessCallback != null) { onSuccessCallback.run(); @@ -494,42 +503,107 @@ private void setImageStreamImageAvailableListener(final EventChannel.EventSink i null); } - public void setFlashMode(@NonNull final Result result, boolean enable) { - setFlashMode(result, enable, 1.0); - } - - public void setFlashMode(@NonNull final Result result, boolean enable, double level) { + public void setFlash(@NonNull final Result result, int mode) { try { - // Request Flash mode - captureRequestBuilder.set( - CaptureRequest.FLASH_MODE, - enable ? CaptureRequest.FLASH_MODE_TORCH : CaptureRequest.FLASH_MODE_OFF); - - // Request Auto Exposure mode as recommended when you switch the Flash - // more information: - // https://developer.android.com/reference/android/hardware/camera2/CaptureRequest.html#FLASH_MODE - captureRequestBuilder.set( - CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, - CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START); - - cameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null); + // Force turning off the torch to avoid keeping the + // light on when another flash mode is selected + if (mode != CAMERA_FLASH_MODE_TORCH && flashMode == CAMERA_FLASH_MODE_TORCH) { + setFlashModeRequest(captureRequestBuilder, CAMERA_FLASH_MODE_OFF); + setAutoFocusModeRequest(captureRequestBuilder, autoFocusMode); + CaptureRequest request = captureRequestBuilder.build(); + cameraCaptureSession.setRepeatingRequest(request, null, null); + } + + // Keep the new mode + flashMode = mode; + + // Rebuild Capture Session immediatly only if Torch Mode is requested or when turned off + if (flashMode == CAMERA_FLASH_MODE_TORCH || flashMode == CAMERA_FLASH_MODE_OFF) { + // Rebuild Capture Session with flash and focus settings + setFlashModeRequest(captureRequestBuilder, flashMode); + setAutoFocusModeRequest(captureRequestBuilder, autoFocusMode); + CaptureRequest request = captureRequestBuilder.build(); + cameraCaptureSession.setRepeatingRequest(request, null, null); + } + result.success(null); } catch (Exception e) { result.error("cameraFlashFailed", e.getMessage(), null); } } - public void setAutoExposureMode(@NonNull final Result result, boolean enable) { + private void setFlashModeRequest(CaptureRequest.Builder builderRequest, int mode) { + // Request Flash mode and set the tightly coupled auto Exposure mode + int flashRequestMode; + int autoExposureRequestMode; + switch (mode) { + case CAMERA_FLASH_MODE_ALWAYS_FLASH: + flashRequestMode = CameraMetadata.FLASH_MODE_SINGLE; + autoExposureRequestMode = CameraMetadata.CONTROL_AE_MODE_ON; + break; + case CAMERA_FLASH_MODE_AUTO_FLASH: + flashRequestMode = CameraMetadata.FLASH_MODE_SINGLE; + autoExposureRequestMode = CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE; + break; + case CAMERA_FLASH_MODE_TORCH: + flashRequestMode = CameraMetadata.FLASH_MODE_TORCH; + autoExposureRequestMode = CameraMetadata.CONTROL_AE_MODE_ON; + break; + default: + flashRequestMode = CameraMetadata.FLASH_MODE_OFF; + autoExposureRequestMode = CameraMetadata.CONTROL_AE_MODE_ON; + } + + builderRequest.set(CaptureRequest.FLASH_MODE, flashRequestMode); + builderRequest.set(CaptureRequest.CONTROL_AE_MODE, autoExposureRequestMode); + + // Request Auto Exposure mode as recommended when you switch the Flash + // more information: + // https://developer.android.com/reference/android/hardware/camera2/CaptureRequest.html#FLASH_MODE + builderRequest.set( + CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, + CameraMetadata.CONTROL_AE_PRECAPTURE_TRIGGER_START); + } + + public void setAutoFocus(@NonNull final Result result, int mode) { try { - // Request Auto Exposure mode - captureRequestBuilder.set( - CaptureRequest.CONTROL_AE_MODE, - enable ? CaptureRequest.CONTROL_AE_MODE_ON : CaptureRequest.CONTROL_AE_MODE_OFF); + // Keep the mode + autoFocusMode = mode; + + // Rebuild Capture Session with flash and focus settings + setFlashModeRequest(captureRequestBuilder, flashMode); + setAutoFocusModeRequest(captureRequestBuilder, autoFocusMode); + CaptureRequest request = captureRequestBuilder.build(); + cameraCaptureSession.setRepeatingRequest(request, null, null); - cameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null); result.success(null); } catch (Exception e) { - result.error("cameraAutoExposureFailed", e.getMessage(), null); + result.error("cameraAutoFocusFailed", e.getMessage(), null); + } + } + + private void setAutoFocusModeRequest(CaptureRequest.Builder builderRequest, int mode) { + // Request Auto Focus Mode + int autoFocusRequestMode; + switch (mode) { + case CAMERA_AUTO_FOCUS_MODE_OFF: + autoFocusRequestMode = CameraMetadata.CONTROL_AF_MODE_AUTO; + break; + case CAMERA_AUTO_FOCUS_MODE_CONTINUOUS: + autoFocusRequestMode = CameraMetadata.CONTROL_AF_MODE_CONTINUOUS_VIDEO; + break; + case CAMERA_AUTO_FOCUS_MODE_MACRO: + autoFocusRequestMode = CameraMetadata.CONTROL_AF_MODE_MACRO; + break; + default: + autoFocusRequestMode = CameraMetadata.CONTROL_AF_MODE_AUTO; + } + + builderRequest.set(CaptureRequest.CONTROL_AF_MODE, autoFocusRequestMode); + + if (mode != CAMERA_AUTO_FOCUS_MODE_OFF) { + builderRequest.set( + CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START); } } diff --git a/packages/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java b/packages/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java index 67006a8d990a..c4c081f7f0f1 100644 --- a/packages/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java +++ b/packages/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java @@ -49,8 +49,8 @@ private void instantiateCamera(MethodCall call, Result result) throws CameraAcce String cameraName = call.argument("cameraName"); String resolutionPreset = call.argument("resolutionPreset"); boolean enableAudio = call.argument("enableAudio"); - boolean enableFlash = call.argument("enableFlash"); - boolean enableAutoExposure = call.argument("enableAutoExposure"); + int flashMode = call.argument("flashMode"); + int autoFocusMode = call.argument("autoFocusMode"); camera = new Camera( registrar.activity(), @@ -58,8 +58,8 @@ private void instantiateCamera(MethodCall call, Result result) throws CameraAcce cameraName, resolutionPreset, enableAudio, - enableFlash, - enableAutoExposure); + flashMode, + autoFocusMode); EventChannel cameraEventChannel = new EventChannel( @@ -153,14 +153,9 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull final Result result) } break; } - case "flashOn": + case "setFlash": { - camera.setFlashMode(result, true, call.argument("level")); - break; - } - case "flashOff": - { - camera.setFlashMode(result, false); + camera.setFlash(result, call.argument("mode")); break; } case "hasFlash": @@ -168,14 +163,9 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull final Result result) result.success(hasFlash()); break; } - case "autoExposureOn": - { - camera.setAutoExposureMode(result, true); - break; - } - case "autoExposureOff": + case "setAutoFocus": { - camera.setAutoExposureMode(result, false); + camera.setAutoFocus(result, call.argument("mode")); break; } case "dispose": diff --git a/packages/camera/example/lib/main.dart b/packages/camera/example/lib/main.dart index b31f81d0e22c..6466130812d8 100644 --- a/packages/camera/example/lib/main.dart +++ b/packages/camera/example/lib/main.dart @@ -41,7 +41,7 @@ class _CameraExampleHomeState extends State VideoPlayerController videoController; VoidCallback videoPlayerListener; bool enableAudio = true; - bool enableFlash = false; + FlashMode flashMode = FlashMode.off; @override void initState() { @@ -101,12 +101,7 @@ class _CameraExampleHomeState extends State ), ), _captureControlRowWidget(), - Row( - children: [ - _toggleAudioWidget(), - _toggleFlashWidget(), - ], - ), + _optionsControlRowWidget(), Padding( padding: const EdgeInsets.all(5.0), child: Row( @@ -143,40 +138,60 @@ class _CameraExampleHomeState extends State /// Toggle recording audio Widget _toggleAudioWidget() { - return Padding( - padding: const EdgeInsets.only(left: 25), - child: Row( - children: [ - const Text('Enable Audio:'), - Switch( - value: enableAudio, - onChanged: (bool value) { - enableAudio = value; - if (controller != null) { - onNewCameraSelected(controller.description); - } - }, - ), - ], - ), + return Row( + children: [ + const Text('Enable Audio:'), + Switch( + value: enableAudio, + onChanged: (bool value) { + enableAudio = value; + if (controller != null) { + onNewCameraSelected(controller.description); + } + }, + ), + ], ); } - /// Display the Flash Switch - Widget _toggleFlashWidget() { + /// Display the control bar with buttons to options like audio and flash. + Widget _optionsControlRowWidget() { return Padding( - padding: const EdgeInsets.only(left: 25), + padding: const EdgeInsets.symmetric(horizontal: 10), child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + mainAxisSize: MainAxisSize.max, children: [ - const Text('Enable Flash:'), - Switch(value: enableFlash, onChanged: _toggleFlash), + _toggleAudioWidget(), + _flashButton(), + _torchButton(), ], ), ); } + /// Flash Toggle Button + Widget _flashButton() { + IconData iconData = Icons.flash_off; + Color color = Colors.black; + if (flashMode == FlashMode.alwaysFlash) { + iconData = Icons.flash_on; + color = Colors.blue; + } else if (flashMode == FlashMode.autoFlash) { + iconData = Icons.flash_auto; + color = Colors.red; + } + return IconButton( + icon: Icon(iconData), + color: color, + onPressed: controller != null && controller.value.isInitialized + ? _onFlashButtonPressed + : null, + ); + } + /// Toggle Flash - Future _toggleFlash(bool value) async { + Future _onFlashButtonPressed() async { bool hasFlash = false; if (controller != null) { @@ -184,17 +199,62 @@ class _CameraExampleHomeState extends State } if (hasFlash) { - enableFlash = value; - if (enableFlash) { - controller.flashOn(); + if (flashMode == FlashMode.off || flashMode == FlashMode.torch) { + // Turn on the flash for capture + flashMode = FlashMode.alwaysFlash; + } else if (flashMode == FlashMode.alwaysFlash) { + // Turn on the flash for capture if needed + flashMode = FlashMode.autoFlash; } else { - controller.flashOff(); + // Turn off the flash + flashMode = FlashMode.off; } + // Apply the new mode + controller.setFlash(mode: flashMode); } + // Change UI State setState(() {}); } + /// Constant Flash (Torch) Toggle Button + Widget _torchButton() { + return IconButton( + icon: Icon(Icons.lightbulb_outline), + color: flashMode == FlashMode.torch ? Colors.blue : Colors.black, + onPressed: controller != null && controller.value.isInitialized + ? onTorchButtonPressed + : null, + ); + } + + /// Toggle constant Flash (Torch) + Future onTorchButtonPressed() async { + bool hasFlash = false; + + if (controller != null) { + hasFlash = await controller.hasFlash; + } + + if (hasFlash) { + if (flashMode != FlashMode.torch) { + // Turn on the flash as a pocket light or a torch light + controller.setFlash(mode: FlashMode.torch); + // Change UI State + setState(() { + flashMode = FlashMode.torch; + }); + } else { + // Turn off the flash + controller.setFlash(); + // Change UI State + setState(() { + flashMode = FlashMode.off; + }); + } + } + } + /// Display the thumbnail of the captured image or video. Widget _thumbnailWidget() { return Expanded( diff --git a/packages/camera/lib/camera.dart b/packages/camera/lib/camera.dart index aa8c1d625f6f..5b6c38a07909 100644 --- a/packages/camera/lib/camera.dart +++ b/packages/camera/lib/camera.dart @@ -38,6 +38,35 @@ enum ResolutionPreset { max, } +/// Define the desired mode for the camera device's flash control. +enum FlashMode { + /// The flash is disabled + off, + + /// Fire flash for this capture + alwaysFlash, + + /// Fire the flash for this capture if needed + autoFlash, + + /// Flash light is continuously ON + torch, +} + +enum AutoFocusMode { + /// Auto Focus is disabled + off, + + /// Basic mode + auto, + + /// Attempt to provide constantly a sharp image stream + continuous, + + /// Close-up + macro, +} + typedef onLatestImageAvailable = Function(CameraImage image); /// Returns the resolution preset as a String. @@ -244,8 +273,8 @@ class CameraController extends ValueNotifier { this.description, this.resolutionPreset, { this.enableAudio = true, - this.enableFlash = false, - this.enableAutoExposure = true, + this.flashMode = FlashMode.off, + this.autoFocusMode = AutoFocusMode.continuous, }) : super(const CameraValue.uninitialized()); final CameraDescription description; @@ -254,11 +283,11 @@ class CameraController extends ValueNotifier { /// Whether to include audio when recording a video. final bool enableAudio; - /// Switch ON the flash when a camera is initialized - final bool enableFlash; + /// Set the initial Flash state + final FlashMode flashMode; - /// Switch ON the Auto Exposure when a camera is initialized - final bool enableAutoExposure; + /// Set the flash Auto Focus state + final AutoFocusMode autoFocusMode; int _textureId; bool _isDisposed = false; @@ -282,8 +311,8 @@ class CameraController extends ValueNotifier { 'cameraName': description.name, 'resolutionPreset': serializeResolutionPreset(resolutionPreset), 'enableAudio': enableAudio, - 'enableFlash': enableFlash, - 'enableAutoExposure': enableAutoExposure, + 'flashMode': flashMode.index, + 'autoFocusMode': autoFocusMode.index, }, ); _textureId = reply['textureId']; @@ -525,34 +554,19 @@ class CameraController extends ValueNotifier { } } - /// Switch ON the flash. - Future flashOn({double level = 1.0}) async { - if (!value.isInitialized || _isDisposed) { - throw CameraException( - 'Uninitialized CameraController.', - 'flashOn was called on uninitialized CameraController', - ); - } - - try { - await _channel - .invokeMethod('flashOn', {'level': level}); - } on PlatformException catch (e) { - throw CameraException(e.code, e.message); - } - } - - /// Switch OFF the flash. - Future flashOff() async { + /// Set the Flash light [mode] + /// See [FlashMode] enum for available options + Future setFlash({FlashMode mode = FlashMode.off}) async { if (!value.isInitialized || _isDisposed) { throw CameraException( 'Uninitialized CameraController.', - 'flashOff was called on uninitialized CameraController', + 'flashMode was called on uninitialized CameraController', ); } try { - await _channel.invokeMethod('flashOff'); + await _channel.invokeMethod( + 'setFlash', {'mode': mode.index}); } on PlatformException catch (e) { throw CameraException(e.code, e.message); } @@ -601,33 +615,19 @@ class CameraController extends ValueNotifier { } } - /// Switch ON continuous Auto Exposure. - Future autoExposureOn() async { - if (!value.isInitialized || _isDisposed) { - throw CameraException( - 'Uninitialized CameraController.', - 'autoExposureOn was called on uninitialized CameraController', - ); - } - - try { - await _channel.invokeMethod('autoExposureOn'); - } on PlatformException catch (e) { - throw CameraException(e.code, e.message); - } - } - - /// Switch OFF continuous Auto Exposure. - Future autoExposureOff() async { + /// Set the Auto Focus [mode] + /// See [AutoFocusMode] enum for available options + Future setAutoFocus({AutoFocusMode mode = AutoFocusMode.off}) async { if (!value.isInitialized || _isDisposed) { throw CameraException( 'Uninitialized CameraController.', - 'autoExposureOff was called on uninitialized CameraController', + 'autoFocusMode was called on uninitialized CameraController', ); } try { - await _channel.invokeMethod('autoExposureOff'); + await _channel.invokeMethod( + 'setAutoFocus', {'mode': mode.index}); } on PlatformException catch (e) { throw CameraException(e.code, e.message); } From c39a6e29634cdab45ab4fe98f23ca1edf5cfd977 Mon Sep 17 00:00:00 2001 From: NeKo Date: Wed, 25 Sep 2019 23:21:59 +0200 Subject: [PATCH 27/30] [camera] Fix partial enlightenment --- .../io/flutter/plugins/camera/Camera.java | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index 8fa9a6d725ad..c7a9a1d3956a 100644 --- a/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -517,14 +517,11 @@ public void setFlash(@NonNull final Result result, int mode) { // Keep the new mode flashMode = mode; - // Rebuild Capture Session immediatly only if Torch Mode is requested or when turned off - if (flashMode == CAMERA_FLASH_MODE_TORCH || flashMode == CAMERA_FLASH_MODE_OFF) { - // Rebuild Capture Session with flash and focus settings - setFlashModeRequest(captureRequestBuilder, flashMode); - setAutoFocusModeRequest(captureRequestBuilder, autoFocusMode); - CaptureRequest request = captureRequestBuilder.build(); - cameraCaptureSession.setRepeatingRequest(request, null, null); - } + // Rebuild Capture Session with flash and focus settings + setFlashModeRequest(captureRequestBuilder, flashMode); + setAutoFocusModeRequest(captureRequestBuilder, autoFocusMode); + CaptureRequest request = captureRequestBuilder.build(); + cameraCaptureSession.setRepeatingRequest(request, null, null); result.success(null); } catch (Exception e) { @@ -538,12 +535,12 @@ private void setFlashModeRequest(CaptureRequest.Builder builderRequest, int mode int autoExposureRequestMode; switch (mode) { case CAMERA_FLASH_MODE_ALWAYS_FLASH: - flashRequestMode = CameraMetadata.FLASH_MODE_SINGLE; - autoExposureRequestMode = CameraMetadata.CONTROL_AE_MODE_ON; + flashRequestMode = CameraMetadata.FLASH_MODE_OFF; + autoExposureRequestMode = CameraMetadata.CONTROL_AE_MODE_ON_ALWAYS_FLASH; break; case CAMERA_FLASH_MODE_AUTO_FLASH: - flashRequestMode = CameraMetadata.FLASH_MODE_SINGLE; - autoExposureRequestMode = CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE; + flashRequestMode = CameraMetadata.FLASH_MODE_OFF; + autoExposureRequestMode = CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH; break; case CAMERA_FLASH_MODE_TORCH: flashRequestMode = CameraMetadata.FLASH_MODE_TORCH; From 7bb389ceb13802813923fbfa2888e919af385374 Mon Sep 17 00:00:00 2001 From: NeKo Date: Thu, 26 Sep 2019 12:39:23 +0200 Subject: [PATCH 28/30] [camera] Fix missing import and increment version --- packages/camera/CHANGELOG.md | 5 ++++- .../src/main/java/io/flutter/plugins/camera/Camera.java | 1 + packages/camera/pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/camera/CHANGELOG.md b/packages/camera/CHANGELOG.md index 7f636500ba61..89c6431984d4 100644 --- a/packages/camera/CHANGELOG.md +++ b/packages/camera/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.5.5 + +* Add support for Flash and Auto Focus. + ## 0.5.4+2 * Fix Android NullPointerException on devices with only front-facing camera. @@ -8,7 +12,6 @@ ## 0.5.4 -* Add support for Flash and Auto Exposure. * Add feature to pause and resume video recording. ## 0.5.3+1 diff --git a/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index b60d185e9785..418378d85591 100644 --- a/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -21,6 +21,7 @@ import android.media.Image; import android.media.ImageReader; import android.media.MediaRecorder; +import android.os.Build; import android.util.Size; import android.view.OrientationEventListener; import android.view.Surface; diff --git a/packages/camera/pubspec.yaml b/packages/camera/pubspec.yaml index e7c8632b042f..9ed9b55203f0 100644 --- a/packages/camera/pubspec.yaml +++ b/packages/camera/pubspec.yaml @@ -2,7 +2,7 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.5.4+2 +version: 0.5.5 authors: - Flutter Team From 0f80b950c7347e7cdcf7014970c0d5535d4edbe7 Mon Sep 17 00:00:00 2001 From: NeKo Date: Tue, 8 Oct 2019 22:40:10 +0200 Subject: [PATCH 29/30] [camera] Fix continuous autofocus mode --- .../src/main/java/io/flutter/plugins/camera/Camera.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index 418378d85591..badfe15fc1de 100644 --- a/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -599,7 +599,7 @@ private void setAutoFocusModeRequest(CaptureRequest.Builder builderRequest, int autoFocusRequestMode = CameraMetadata.CONTROL_AF_MODE_AUTO; break; case CAMERA_AUTO_FOCUS_MODE_CONTINUOUS: - autoFocusRequestMode = CameraMetadata.CONTROL_AF_MODE_CONTINUOUS_VIDEO; + autoFocusRequestMode = CameraMetadata.CONTROL_AF_MODE_CONTINUOUS_PICTURE; break; case CAMERA_AUTO_FOCUS_MODE_MACRO: autoFocusRequestMode = CameraMetadata.CONTROL_AF_MODE_MACRO; @@ -610,7 +610,7 @@ private void setAutoFocusModeRequest(CaptureRequest.Builder builderRequest, int builderRequest.set(CaptureRequest.CONTROL_AF_MODE, autoFocusRequestMode); - if (mode != CAMERA_AUTO_FOCUS_MODE_OFF) { + if (mode != CAMERA_AUTO_FOCUS_MODE_OFF && mode != CAMERA_AUTO_FOCUS_MODE_CONTINUOUS) { builderRequest.set( CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START); } From 316869a58dc8bfd960e15ae5b4747ed5a4a74512 Mon Sep 17 00:00:00 2001 From: NeKo Date: Sun, 3 Nov 2019 19:05:32 +0100 Subject: [PATCH 30/30] Merge fix --- .../android/src/main/java/io/flutter/plugins/camera/Camera.java | 2 -- .../java/io/flutter/plugins/camera/MethodCallHandlerImpl.java | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index f9b505dee80f..790e50f76c07 100644 --- a/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -105,8 +105,6 @@ public Camera( this.enableAudio = enableAudio; this.flashMode = flashMode; this.autoFocusMode = autoFocusMode; - this.enableTorch = enableTorch; - this.enableAE = enableAE; this.flutterTexture = flutterTexture; this.dartMessenger = dartMessenger; this.cameraManager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE); diff --git a/packages/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java b/packages/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java index 98ad4c223c8d..9bb0bf867004 100644 --- a/packages/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java +++ b/packages/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java @@ -1,6 +1,7 @@ package io.flutter.plugins.camera; import android.app.Activity; +import android.content.pm.PackageManager; import android.hardware.camera2.CameraAccessException; import androidx.annotation.NonNull; import androidx.annotation.Nullable;