cordova-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From fil...@apache.org
Subject cordova-plugin-media-capture git commit: CB-12882: (ios): adds support for permissions checks for captureVideo and captureImage methods
Date Sat, 10 Jun 2017 15:25:24 GMT
Repository: cordova-plugin-media-capture
Updated Branches:
  refs/heads/master f38f507a9 -> d19be5be1


CB-12882: (ios): adds support for permissions checks for captureVideo and captureImage methods


Project: http://git-wip-us.apache.org/repos/asf/cordova-plugin-media-capture/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-plugin-media-capture/commit/d19be5be
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-media-capture/tree/d19be5be
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-media-capture/diff/d19be5be

Branch: refs/heads/master
Commit: d19be5be1fa5dfbc30fbd997f5e780a056616138
Parents: f38f507
Author: Sergii Stotskyi <sergii.stotskyi@concreteplatform.com>
Authored: Mon Jun 5 13:02:29 2017 +0300
Committer: Sergii Stotskyi <sergiy.stotskiy@gmail.com>
Committed: Wed Jun 7 08:07:21 2017 +0300

----------------------------------------------------------------------
 package.json         |  3 +++
 src/ios/CDVCapture.h |  1 +
 src/ios/CDVCapture.m | 62 ++++++++++++++++++++++++++++++++++++++++-------
 tests/tests.js       | 36 ++++++++++++++++++++++++++-
 4 files changed, 92 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-plugin-media-capture/blob/d19be5be/package.json
----------------------------------------------------------------------
diff --git a/package.json b/package.json
index ea4a23b..6d45d64 100644
--- a/package.json
+++ b/package.json
@@ -47,6 +47,9 @@
   "license": "Apache-2.0",
   "engines": {
     "cordovaDependencies": {
+      ">=1.4.4": {
+        "cordova-ios": ">=4.0.0"
+      },
       "2.0.0": {
         "cordova": ">100"
       }

http://git-wip-us.apache.org/repos/asf/cordova-plugin-media-capture/blob/d19be5be/src/ios/CDVCapture.h
----------------------------------------------------------------------
diff --git a/src/ios/CDVCapture.h b/src/ios/CDVCapture.h
index 2cd8db8..c7433a4 100644
--- a/src/ios/CDVCapture.h
+++ b/src/ios/CDVCapture.h
@@ -28,6 +28,7 @@ enum CDVCaptureError {
     CAPTURE_APPLICATION_BUSY = 1,
     CAPTURE_INVALID_ARGUMENT = 2,
     CAPTURE_NO_MEDIA_FILES = 3,
+    CAPTURE_PERMISSION_DENIED = 4,
     CAPTURE_NOT_SUPPORTED = 20
 };
 typedef NSUInteger CDVCaptureError;

http://git-wip-us.apache.org/repos/asf/cordova-plugin-media-capture/blob/d19be5be/src/ios/CDVCapture.m
----------------------------------------------------------------------
diff --git a/src/ios/CDVCapture.m b/src/ios/CDVCapture.m
index 53e1b2b..7ab0832 100644
--- a/src/ios/CDVCapture.m
+++ b/src/ios/CDVCapture.m
@@ -58,17 +58,17 @@
 - (BOOL)prefersStatusBarHidden {
     return YES;
 }
-    
+
 - (UIViewController*)childViewControllerForStatusBarHidden {
     return nil;
 }
-    
+
 - (void)viewWillAppear:(BOOL)animated {
     SEL sel = NSSelectorFromString(@"setNeedsStatusBarAppearanceUpdate");
     if ([self respondsToSelector:sel]) {
         [self performSelector:sel withObject:nil afterDelay:0];
     }
-    
+
     [super viewWillAppear:animated];
 }
 
@@ -141,6 +141,7 @@
             pickerController = [[CDVImagePicker alloc] init];
         }
 
+        [self showAlertIfAccessProhibited];
         pickerController.delegate = self;
         pickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
         pickerController.allowsEditing = NO;
@@ -247,6 +248,8 @@
         [self.commandDelegate sendPluginResult:result callbackId:callbackId];
         pickerController = nil;
     } else {
+        [self showAlertIfAccessProhibited];
+
         pickerController.delegate = self;
         pickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
         pickerController.allowsEditing = NO;
@@ -292,6 +295,47 @@
     return [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:fileArray];
 }
 
+- (void)showAlertIfAccessProhibited
+{
+    if (![self hasCameraAccess]) {
+        [self showPermissionsAlert];
+    }
+}
+
+- (BOOL)hasCameraAccess
+{
+    AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
+
+    return status != AVAuthorizationStatusDenied && status != AVAuthorizationStatusRestricted;
+}
+
+- (void)showPermissionsAlert
+{
+    __weak CDVCapture* weakSelf = self;
+    dispatch_async(dispatch_get_main_queue(), ^{
+        [[[UIAlertView alloc] initWithTitle:[[NSBundle mainBundle]
+                                             objectForInfoDictionaryKey:@"CFBundleDisplayName"]
+                                    message:NSLocalizedString(@"Access to the camera has
been prohibited; please enable it in the Settings app to continue.", nil)
+                                   delegate:weakSelf
+                          cancelButtonTitle:NSLocalizedString(@"OK", nil)
+                          otherButtonTitles:NSLocalizedString(@"Settings", nil), nil] show];
+    });
+}
+
+- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+    if (buttonIndex == 1) {
+        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
+    }
+
+    CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageToErrorObject:CAPTURE_PERMISSION_DENIED];
+
+    [[pickerController presentingViewController] dismissViewControllerAnimated:YES completion:nil];
+    [self.commandDelegate sendPluginResult:result callbackId:pickerController.callbackId];
+    pickerController = nil;
+    self.inUse = NO;
+}
+
 - (void)getMediaModes:(CDVInvokedUrlCommand*)command
 {
     // NSString* callbackId = [command argumentAtIndex:0];
@@ -337,7 +381,7 @@
         movieArray ? (NSObject*)                          movieArray:[NSNull null], @"video",
         audioArray ? (NSObject*)                          audioArray:[NSNull null], @"audio",
         nil];
-    
+
     NSData* jsonData = [NSJSONSerialization dataWithJSONObject:modes options:0 error:nil];
     NSString* jsonStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
 
@@ -608,7 +652,7 @@
 	if ([self respondsToSelector:@selector(edgesForExtendedLayout)]) {
         self.edgesForExtendedLayout = UIRectEdgeNone;
     }
-    
+
     // create view and display
     CGRect viewRect = [[UIScreen mainScreen] applicationFrame];
     UIView* tmp = [[UIView alloc] initWithFrame:viewRect];
@@ -737,7 +781,7 @@
 {
     UIInterfaceOrientationMask orientation = UIInterfaceOrientationMaskPortrait;
     UIInterfaceOrientationMask supported = [captureCommand.viewController supportedInterfaceOrientations];
-    
+
     orientation = orientation | (supported & UIInterfaceOrientationMaskPortraitUpsideDown);
     return orientation;
 }
@@ -746,7 +790,7 @@
 {
     NSUInteger orientation = UIInterfaceOrientationMaskPortrait; // must support portrait
     NSUInteger supported = [captureCommand.viewController supportedInterfaceOrientations];
-    
+
     orientation = orientation | (supported & UIInterfaceOrientationMaskPortraitUpsideDown);
     return orientation;
 }
@@ -773,7 +817,7 @@
         __block NSError* error = nil;
 
         __weak CDVAudioRecorderViewController* weakSelf = self;
-        
+
         void (^startRecording)(void) = ^{
             [weakSelf.avSession setCategory:AVAudioSessionCategoryRecord error:&error];
             [weakSelf.avSession setActive:YES error:&error];
@@ -794,7 +838,7 @@
             }
             UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, nil);
         };
-        
+
         SEL rrpSel = NSSelectorFromString(@"requestRecordPermission:");
         if ([self.avSession respondsToSelector:rrpSel])
         {

http://git-wip-us.apache.org/repos/asf/cordova-plugin-media-capture/blob/d19be5be/tests/tests.js
----------------------------------------------------------------------
diff --git a/tests/tests.js b/tests/tests.js
index fd2f60b..9434fc1 100644
--- a/tests/tests.js
+++ b/tests/tests.js
@@ -243,6 +243,28 @@ exports.defineManualTests = function (contentEl, createActionButton)
{
         navigator.device.capture.captureVideo(captureVideoWin, captureVideoFail, options);
     }
 
+    function permissionWasNotAllowed() {
+        log('Media has been captured. Have you forgotten to disallow camera for this app?');
+    }
+
+    function catchPermissionError(error) {
+        if (CaptureError.CAPTURE_PERMISSION_DENIED === error.code) {
+            log('Sucess: permission error has been detected!');
+        } else {
+            log('Error: another error with code: ' + error.code);
+        }
+    }
+
+    function getVideoPermissionError() {
+        var options = { limit: 1, duration: 10 };
+        navigator.device.capture.captureVideo(permissionWasNotAllowed, catchPermissionError,
options);
+    }
+
+    function getImagePermissionError() {
+        var options = { limit: 1 };
+        navigator.device.capture.captureImage(permissionWasNotAllowed, catchPermissionError,
options);
+    }
+
     function resolveMediaFileURL(mediaFile, callback) {
         resolveLocalFileSystemURL(mediaFile.localURL, function (entry) {
             log("Resolved by URL: " + mediaFile.localURL);
@@ -300,7 +322,11 @@ exports.defineManualTests = function (contentEl, createActionButton)
{
         '<p/> <div id="video"></div>' +
         'Expected result: Record 10 second video. Status box will update with video file
that you can play.' +
         '<p/> <div id="video_and_resolve"></div>' +
-        'Expected result: Record 5 second video. Status box will show that URL was resolved
and video will get added at the bottom of the status box for playback.';
+        'Expected result: Record 5 second video. Status box will show that URL was resolved
and video will get added at the bottom of the status box for playback.' +
+        '<p/> <div id="prohibited_camera_video"></div>' +
+        'Expected result (iOS only): camera picker and alert with message that camera access
is prohibited are shown. The alert has 2 buttons: OK and Settings. By click on "OK" camera
is hidden, by pressing Settings it shows privacy settings for the app' +
+        '<p/> <div id="prohibited_camera_image"></div>' +
+        'Expected result (iOS only): camera picker and alert with message that camera access
is prohibited are shown. The alert has 2 buttons: OK and Settings. By click on "OK" camera
is hidden, by pressing Settings it shows privacy settings for the app';
 
     createActionButton('Capture 10 sec of audio and play', function () {
         getAudio();
@@ -321,4 +347,12 @@ exports.defineManualTests = function (contentEl, createActionButton)
{
     createActionButton('Capture 5 sec of video and resolve', function () {
         resolveVideo();
     }, 'video_and_resolve');
+
+    createActionButton('Disable access to Camera and click to capture video', function()
{
+      getVideoPermissionError();
+    }, 'prohibited_camera_video');
+
+    createActionButton('Disable access to Camera and click to capture image', function()
{
+      getImagePermissionError();
+    }, 'prohibited_camera_image');
 };


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org


Mime
View raw message