From b308d08e9a21c7c31b88990cd54b0f02a5c02842 Mon Sep 17 00:00:00 2001 From: Ron Heft Date: Thu, 8 Dec 2016 21:05:35 -0500 Subject: [PATCH] Race conditions initializing flashMode (#436) * Fix race condition initializing Android camera * Fix race condition initializing flashMode iOS --- .../com/lwansbrough/RCTCamera/RCTCamera.java | 10 ++--- ios/RCTCameraManager.m | 43 +++++++++++-------- 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCamera.java b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCamera.java index 063a40a..9dc3df3 100644 --- a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCamera.java +++ b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCamera.java @@ -35,7 +35,7 @@ public class RCTCamera { } - public Camera acquireCameraInstance(int type) { + public synchronized Camera acquireCameraInstance(int type) { if (null == _cameras.get(type) && null != _cameraTypeToIndex.get(type)) { try { Camera camera = Camera.open(_cameraTypeToIndex.get(type)); @@ -206,7 +206,7 @@ public class RCTCamera { } public void setCaptureQuality(int cameraType, String captureQuality) { - Camera camera = _cameras.get(cameraType); + Camera camera = this.acquireCameraInstance(cameraType); if (camera == null) { return; } @@ -246,7 +246,7 @@ public class RCTCamera { } public CamcorderProfile setCaptureVideoQuality(int cameraType, String captureQuality) { - Camera camera = _cameras.get(cameraType); + Camera camera = this.acquireCameraInstance(cameraType); if (camera == null) { return null; } @@ -294,7 +294,7 @@ public class RCTCamera { } public void setTorchMode(int cameraType, int torchMode) { - Camera camera = _cameras.get(cameraType); + Camera camera = this.acquireCameraInstance(cameraType); if (null == camera) { return; } @@ -318,7 +318,7 @@ public class RCTCamera { } public void setFlashMode(int cameraType, int flashMode) { - Camera camera = _cameras.get(cameraType); + Camera camera = this.acquireCameraInstance(cameraType); if (null == camera) { return; } diff --git a/ios/RCTCameraManager.m b/ios/RCTCameraManager.m index fc9c52e..bd611f0 100644 --- a/ios/RCTCameraManager.m +++ b/ios/RCTCameraManager.m @@ -14,6 +14,7 @@ @interface RCTCameraManager () @property (strong, nonatomic) RCTSensorOrientationChecker * sensorOrientationChecker; +@property (assign, nonatomic) NSInteger* flashMode; @end @@ -212,6 +213,7 @@ RCT_CUSTOM_VIEW_PROPERTY(type, NSInteger, RCTCamera) { [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(subjectAreaDidChange:) name:AVCaptureDeviceSubjectAreaDidChangeNotification object:captureDevice]; self.videoCaptureDeviceInput = captureDeviceInput; + [self setFlashMode]; } else { @@ -225,29 +227,33 @@ RCT_CUSTOM_VIEW_PROPERTY(type, NSInteger, RCTCamera) { } RCT_CUSTOM_VIEW_PROPERTY(flashMode, NSInteger, RCTCamera) { - AVCaptureDevice *device = [self.videoCaptureDeviceInput device]; - NSError *error = nil; - NSInteger *flashMode = [RCTConvert NSInteger:json]; + self.flashMode = [RCTConvert NSInteger:json]; + [self setFlashMode]; +} - if (![device hasFlash]) return; - if (![device lockForConfiguration:&error]) { - NSLog(@"%@", error); - return; - } - if (device.hasFlash && [device isFlashModeSupported:flashMode]) - { +- (void)setFlashMode { + AVCaptureDevice *device = [self.videoCaptureDeviceInput device]; NSError *error = nil; - if ([device lockForConfiguration:&error]) - { - [device setFlashMode:flashMode]; - [device unlockForConfiguration]; + + if (![device hasFlash]) return; + if (![device lockForConfiguration:&error]) { + NSLog(@"%@", error); + return; } - else + if (device.hasFlash && [device isFlashModeSupported:self.flashMode]) { - NSLog(@"%@", error); + NSError *error = nil; + if ([device lockForConfiguration:&error]) + { + [device setFlashMode:self.flashMode]; + [device unlockForConfiguration]; + } + else + { + NSLog(@"%@", error); + } } - } - [device unlockForConfiguration]; + [device unlockForConfiguration]; } RCT_CUSTOM_VIEW_PROPERTY(torchMode, NSInteger, RCTCamera) { @@ -513,6 +519,7 @@ RCT_EXPORT_METHOD(hasFlash:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRej } else if (type == AVMediaTypeVideo) { self.videoCaptureDeviceInput = captureDeviceInput; + [self setFlashMode]; } [self.metadataOutput setMetadataObjectTypes:self.metadataOutput.availableMetadataObjectTypes]; }