mirror of https://github.com/oxen-io/session-ios
				
				
				
			
			You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			177 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			Objective-C
		
	
			
		
		
	
	
			177 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			Objective-C
		
	
| //
 | |
| //  Copyright (c) 2019 Open Whisper Systems. All rights reserved.
 | |
| //
 | |
| 
 | |
| #import "UIViewController+Permissions.h"
 | |
| #import "Session-Swift.h"
 | |
| #import <AVFoundation/AVFoundation.h>
 | |
| #import <Photos/Photos.h>
 | |
| #import <SignalCoreKit/Threading.h>
 | |
| #import <SignalUtilitiesKit/UIUtil.h>
 | |
| 
 | |
| NS_ASSUME_NONNULL_BEGIN
 | |
| 
 | |
| @implementation UIViewController (Permissions)
 | |
| 
 | |
| - (void)ows_askForCameraPermissions:(void (^)(BOOL granted))callbackParam
 | |
| {
 | |
|     OWSLogVerbose(@"[%@] ows_askForCameraPermissions", NSStringFromClass(self.class));
 | |
| 
 | |
|     // Ensure callback is invoked on main thread.
 | |
|     void (^callback)(BOOL) = ^(BOOL granted) {
 | |
|         DispatchMainThreadSafe(^{
 | |
|             callbackParam(granted);
 | |
|         });
 | |
|     };
 | |
| 
 | |
|     if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
 | |
|         OWSLogError(@"Skipping camera permissions request when app is in background.");
 | |
|         callback(NO);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
 | |
|         OWSLogError(@"Camera ImagePicker source not available");
 | |
|         callback(NO);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
 | |
|     if (status == AVAuthorizationStatusDenied) {
 | |
|         UIAlertController *alert = [UIAlertController
 | |
|             alertControllerWithTitle:NSLocalizedString(@"Session needs camera access to scan QR codes.", @"")
 | |
|                              message:NSLocalizedString(@"You can enable camera access in your device settings.", @"")
 | |
|                       preferredStyle:UIAlertControllerStyleAlert];
 | |
| 
 | |
|         UIAlertAction *openSettingsAction =
 | |
|             [UIAlertAction actionWithTitle:CommonStrings.openSettingsButton
 | |
|                                      style:UIAlertActionStyleDefault
 | |
|                                    handler:^(UIAlertAction *_Nonnull action) {
 | |
|                                        [[UIApplication sharedApplication] openSystemSettings];
 | |
|                                        callback(NO);
 | |
|                                    }];
 | |
|         [alert addAction:openSettingsAction];
 | |
| 
 | |
|         UIAlertAction *dismissAction = [UIAlertAction actionWithTitle:CommonStrings.dismissButton
 | |
|                                                                 style:UIAlertActionStyleCancel
 | |
|                                                               handler:^(UIAlertAction *action) {
 | |
|                                                                   callback(NO);
 | |
|                                                               }];
 | |
|         [alert addAction:dismissAction];
 | |
| 
 | |
|         [self presentAlert:alert];
 | |
|     } else if (status == AVAuthorizationStatusAuthorized) {
 | |
|         callback(YES);
 | |
|     } else if (status == AVAuthorizationStatusNotDetermined) {
 | |
|         [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo
 | |
|                                  completionHandler:callback];
 | |
|     } else {
 | |
|         OWSLogError(@"Unknown AVAuthorizationStatus: %ld", (long)status);
 | |
|         callback(NO);
 | |
|     }
 | |
| }
 | |
| 
 | |
| - (void)ows_askForMediaLibraryPermissions:(void (^)(BOOL granted))callbackParam
 | |
| {
 | |
|     OWSLogVerbose(@"[%@] ows_askForMediaLibraryPermissions", NSStringFromClass(self.class));
 | |
| 
 | |
|     // Ensure callback is invoked on main thread.
 | |
|     void (^completionCallback)(BOOL) = ^(BOOL granted) {
 | |
|         DispatchMainThreadSafe(^{
 | |
|             callbackParam(granted);
 | |
|         });
 | |
|     };
 | |
| 
 | |
|     void (^presentSettingsDialog)(void) = ^(void) {
 | |
|         DispatchMainThreadSafe(^{
 | |
|             UIAlertController *alert = [UIAlertController
 | |
|                 alertControllerWithTitle:NSLocalizedString(@"MISSING_MEDIA_LIBRARY_PERMISSION_TITLE",
 | |
|                                              @"Alert title when user has previously denied media library access")
 | |
|                                  message:NSLocalizedString(@"MISSING_MEDIA_LIBRARY_PERMISSION_MESSAGE",
 | |
|                                              @"Alert body when user has previously denied media library access")
 | |
|                           preferredStyle:UIAlertControllerStyleAlert];
 | |
| 
 | |
|             UIAlertAction *openSettingsAction =
 | |
|                 [UIAlertAction actionWithTitle:CommonStrings.openSettingsButton
 | |
|                                          style:UIAlertActionStyleDefault
 | |
|                                        handler:^(UIAlertAction *_Nonnull action) {
 | |
|                                            [[UIApplication sharedApplication] openSystemSettings];
 | |
|                                            completionCallback(NO);
 | |
|                                        }];
 | |
|             [alert addAction:openSettingsAction];
 | |
| 
 | |
|             UIAlertAction *dismissAction = [UIAlertAction actionWithTitle:CommonStrings.dismissButton
 | |
|                                                                     style:UIAlertActionStyleCancel
 | |
|                                                                   handler:^(UIAlertAction *action) {
 | |
|                                                                       completionCallback(NO);
 | |
|                                                                   }];
 | |
|             [alert addAction:dismissAction];
 | |
| 
 | |
|             [self presentAlert:alert];
 | |
|         });
 | |
|     };
 | |
| 
 | |
|     if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
 | |
|         OWSLogError(@"Skipping media library permissions request when app is in background.");
 | |
|         completionCallback(NO);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
 | |
|         OWSLogError(@"PhotoLibrary ImagePicker source not available");
 | |
|         completionCallback(NO);
 | |
|     }
 | |
| 
 | |
|     PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
 | |
| 
 | |
|     switch (status) {
 | |
|         case PHAuthorizationStatusAuthorized: {
 | |
|             completionCallback(YES);
 | |
|             return;
 | |
|         }
 | |
|         case PHAuthorizationStatusDenied: {
 | |
|             presentSettingsDialog();
 | |
|             return;
 | |
|         }
 | |
|         case PHAuthorizationStatusNotDetermined: {
 | |
|             [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus newStatus) {
 | |
|                 if (newStatus == PHAuthorizationStatusAuthorized) {
 | |
|                     completionCallback(YES);
 | |
|                 } else {
 | |
|                     presentSettingsDialog();
 | |
|                 }
 | |
|             }];
 | |
|             return;
 | |
|         }
 | |
|         case PHAuthorizationStatusRestricted: {
 | |
|             // when does this happen?
 | |
|             OWSFailDebug(@"PHAuthorizationStatusRestricted");
 | |
|             return;
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| - (void)ows_askForMicrophonePermissions:(void (^)(BOOL granted))callbackParam
 | |
| {
 | |
|     OWSLogVerbose(@"[%@] ows_askForMicrophonePermissions", NSStringFromClass(self.class));
 | |
| 
 | |
|     // Ensure callback is invoked on main thread.
 | |
|     void (^callback)(BOOL) = ^(BOOL granted) {
 | |
|         DispatchMainThreadSafe(^{
 | |
|             callbackParam(granted);
 | |
|         });
 | |
|     };
 | |
| 
 | |
|     if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
 | |
|         OWSLogError(@"Skipping microphone permissions request when app is in background.");
 | |
|         callback(NO);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     [[AVAudioSession sharedInstance] requestRecordPermission:callback];
 | |
| }
 | |
| 
 | |
| @end
 | |
| 
 | |
| NS_ASSUME_NONNULL_END
 |