Merge branch 'mkirk/media-permissions'
This commit is contained in:
commit
e0ea3921fc
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "AvatarViewHelper.h"
|
||||
@ -69,17 +69,22 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
OWSAssertIsOnMainThread();
|
||||
OWSAssert(self.delegate);
|
||||
|
||||
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
|
||||
picker.delegate = self;
|
||||
picker.allowsEditing = NO;
|
||||
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
|
||||
[self.delegate.fromViewController ows_askForCameraPermissions:^(BOOL granted) {
|
||||
if (!granted) {
|
||||
DDLogWarn(@"%@ Camera permission denied.", self.logTag);
|
||||
return;
|
||||
}
|
||||
|
||||
UIImagePickerController *picker = [UIImagePickerController new];
|
||||
picker.delegate = self;
|
||||
picker.allowsEditing = NO;
|
||||
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
|
||||
picker.mediaTypes = @[ (__bridge NSString *)kUTTypeImage ];
|
||||
|
||||
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
|
||||
picker.mediaTypes = [[NSArray alloc] initWithObjects:(NSString *)kUTTypeImage, nil];
|
||||
[self.delegate.fromViewController presentViewController:picker
|
||||
animated:YES
|
||||
completion:[UIUtil modalCompletionBlock]];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)chooseFromLibrary
|
||||
@ -87,16 +92,21 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
OWSAssertIsOnMainThread();
|
||||
OWSAssert(self.delegate);
|
||||
|
||||
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
|
||||
picker.delegate = self;
|
||||
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
|
||||
[self.delegate.fromViewController ows_askForMediaLibraryPermissions:^(BOOL granted) {
|
||||
if (!granted) {
|
||||
DDLogWarn(@"%@ Media Library permission denied.", self.logTag);
|
||||
return;
|
||||
}
|
||||
|
||||
UIImagePickerController *picker = [UIImagePickerController new];
|
||||
picker.delegate = self;
|
||||
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
|
||||
picker.mediaTypes = @[ (__bridge NSString *)kUTTypeImage ];
|
||||
|
||||
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
|
||||
picker.mediaTypes = [[NSArray alloc] initWithObjects:(NSString *)kUTTypeImage, nil];
|
||||
[self.delegate.fromViewController presentViewController:picker
|
||||
animated:YES
|
||||
completion:[UIUtil modalCompletionBlock]];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
// Originally based on EPContacts
|
||||
@ -161,7 +161,7 @@ open class ContactsPicker: OWSViewController, UITableViewDelegate, UITableViewDa
|
||||
})
|
||||
alert.addAction(cancelAction)
|
||||
|
||||
let settingsText = NSLocalizedString("OPEN_SETTINGS_BUTTON", comment:"Button text which opens the settings app")
|
||||
let settingsText = CommonStrings.openSettingsButton
|
||||
let openSettingsAction = UIAlertAction(title: settingsText, style: .default, handler: { (_) in
|
||||
UIApplication.shared.openSystemSettings()
|
||||
})
|
||||
|
||||
@ -2466,18 +2466,18 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) {
|
||||
{
|
||||
[self ows_askForCameraPermissions:^(BOOL granted) {
|
||||
if (!granted) {
|
||||
DDLogWarn(@"%@ camera permission denied.", self.logTag);
|
||||
return;
|
||||
}
|
||||
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
|
||||
|
||||
UIImagePickerController *picker = [UIImagePickerController new];
|
||||
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
|
||||
picker.mediaTypes = @[ (__bridge NSString *)kUTTypeImage, (__bridge NSString *)kUTTypeMovie ];
|
||||
picker.allowsEditing = NO;
|
||||
picker.delegate = self;
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self dismissKeyBoard];
|
||||
[self presentViewController:picker animated:YES completion:[UIUtil modalCompletionBlock]];
|
||||
});
|
||||
[self dismissKeyBoard];
|
||||
[self presentViewController:picker animated:YES completion:[UIUtil modalCompletionBlock]];
|
||||
}];
|
||||
}
|
||||
|
||||
@ -2485,18 +2485,20 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) {
|
||||
{
|
||||
OWSAssertIsOnMainThread();
|
||||
|
||||
if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
|
||||
DDLogError(@"PhotoLibrary ImagePicker source not available");
|
||||
return;
|
||||
}
|
||||
[self ows_askForMediaLibraryPermissions:^(BOOL granted) {
|
||||
if (!granted) {
|
||||
DDLogWarn(@"%@ Media Library permission denied.", self.logTag);
|
||||
return;
|
||||
}
|
||||
|
||||
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
|
||||
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
|
||||
picker.delegate = self;
|
||||
picker.mediaTypes = @[ (__bridge NSString *)kUTTypeImage, (__bridge NSString *)kUTTypeMovie ];
|
||||
UIImagePickerController *picker = [UIImagePickerController new];
|
||||
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
|
||||
picker.delegate = self;
|
||||
picker.mediaTypes = @[ (__bridge NSString *)kUTTypeImage, (__bridge NSString *)kUTTypeMovie ];
|
||||
|
||||
[self dismissKeyBoard];
|
||||
[self presentViewController:picker animated:YES completion:[UIUtil modalCompletionBlock]];
|
||||
[self dismissKeyBoard];
|
||||
[self presentViewController:picker animated:YES completion:[UIUtil modalCompletionBlock]];
|
||||
}];
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@ -314,8 +314,8 @@ typedef NS_ENUM(NSInteger, CellState) { kArchiveState, kInboxState };
|
||||
imageEdgeInsets.top = round((kBarButtonSize - image.size.height) * 0.5f);
|
||||
imageEdgeInsets.bottom = round(kBarButtonSize - (image.size.height + imageEdgeInsets.top));
|
||||
button.imageEdgeInsets = imageEdgeInsets;
|
||||
button.accessibilityLabel
|
||||
= NSLocalizedString(@"OPEN_SETTINGS_BUTTON", "Label for button which opens the settings UI");
|
||||
button.accessibilityLabel = CommonStrings.openSettingsButton;
|
||||
|
||||
[button addTarget:self action:@selector(settingsButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
|
||||
button.frame = CGRectMake(0,
|
||||
0,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
@ -9,7 +9,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@interface UIViewController (Permissions)
|
||||
|
||||
- (void)ows_askForCameraPermissions:(void (^)(BOOL granted))callback;
|
||||
|
||||
- (void)ows_askForMediaLibraryPermissions:(void (^)(BOOL granted))callbackParam;
|
||||
- (void)ows_askForMicrophonePermissions:(void (^)(BOOL granted))callback;
|
||||
|
||||
@end
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Signal-Swift.h"
|
||||
#import "UIViewController+Permissions.h"
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#import <Photos/Photos.h>
|
||||
#import <SignalMessaging/UIUtil.h>
|
||||
#import <SignalServiceKit/Threading.h>
|
||||
|
||||
@ -42,10 +43,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
message:NSLocalizedString(@"MISSING_CAMERA_PERMISSION_MESSAGE", @"Alert body")
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
NSString *settingsTitle
|
||||
= NSLocalizedString(@"OPEN_SETTINGS_BUTTON", @"Button text which opens the settings app");
|
||||
UIAlertAction *openSettingsAction =
|
||||
[UIAlertAction actionWithTitle:settingsTitle
|
||||
[UIAlertAction actionWithTitle:CommonStrings.openSettingsButton
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction *_Nonnull action) {
|
||||
[[UIApplication sharedApplication] openSystemSettings];
|
||||
@ -72,6 +71,84 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
}
|
||||
}
|
||||
|
||||
- (void)ows_askForMediaLibraryPermissions:(void (^)(BOOL granted))callbackParam
|
||||
{
|
||||
DDLogVerbose(@"[%@] ows_askForMediaLibraryPermissions", NSStringFromClass(self.class));
|
||||
|
||||
// Ensure callback is invoked on main thread.
|
||||
void (^completionCallback)(BOOL) = ^(BOOL granted) {
|
||||
DispatchMainThreadSafe(^{
|
||||
callbackParam(granted);
|
||||
});
|
||||
};
|
||||
|
||||
void (^presentSettingsDialog)(void) = ^(void) {
|
||||
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 presentViewController:alert animated:YES completion:nil];
|
||||
};
|
||||
|
||||
if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
|
||||
DDLogError(@"Skipping media library permissions request when app is in background.");
|
||||
completionCallback(NO);
|
||||
return;
|
||||
}
|
||||
|
||||
if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
|
||||
DDLogError(@"%@ PhotoLibrary ImagePicker source not available", self.logTag);
|
||||
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?
|
||||
OWSFail(@"PHAuthorizationStatusRestricted");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)ows_askForMicrophonePermissions:(void (^)(BOOL granted))callbackParam
|
||||
{
|
||||
DDLogVerbose(@"[%@] ows_askForMicrophonePermissions", NSStringFromClass(self.class));
|
||||
|
||||
@ -1041,6 +1041,12 @@
|
||||
Alert title when camera is not authorized */
|
||||
"MISSING_CAMERA_PERMISSION_TITLE" = "Signal needs to access your camera.";
|
||||
|
||||
/* Alert body when user has previously denied media library access */
|
||||
"MISSING_MEDIA_LIBRARY_PERMISSION_MESSAGE" = "You can grant this permission in the Settings app.";
|
||||
|
||||
/* Alert title when user has previously denied media library access */
|
||||
"MISSING_MEDIA_LIBRARY_PERMISSION_TITLE" = "Signal Requires Access to your Media Library to do this.";
|
||||
|
||||
/* notification title. Embeds {{caller's name or phone number}} */
|
||||
"MSGVIEW_MISSED_CALL_WITH_NAME" = "Missed call from %@.";
|
||||
|
||||
@ -1146,8 +1152,7 @@
|
||||
/* No comment provided by engineer. */
|
||||
"OK" = "OK";
|
||||
|
||||
/* Button text which opens the settings app
|
||||
Label for button which opens the settings UI */
|
||||
/* Button text which opens the settings app */
|
||||
"OPEN_SETTINGS_BUTTON" = "Settings";
|
||||
|
||||
/* Info Message when {{other user}} disables or doesn't support disappearing messages */
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "ContactsViewHelper.h"
|
||||
@ -282,8 +282,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
style:UIAlertActionStyleCancel
|
||||
handler:nil]];
|
||||
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"OPEN_SETTINGS_BUTTON",
|
||||
@"Button text which opens the settings app")
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:CommonStrings.openSettingsButton
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction *_Nonnull action) {
|
||||
[CurrentAppContext() openSystemSettings];
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
@ -15,6 +15,8 @@ import Foundation
|
||||
static public let cancelButton = NSLocalizedString("TXT_CANCEL_TITLE", comment:"Label for the cancel button in an alert or action sheet.")
|
||||
@objc
|
||||
static public let retryButton = NSLocalizedString("RETRY_BUTTON_TEXT", comment:"Generic text for button that retries whatever the last action was.")
|
||||
@objc
|
||||
static public let openSettingsButton = NSLocalizedString("OPEN_SETTINGS_BUTTON", comment: "Button text which opens the settings app")
|
||||
}
|
||||
|
||||
@objc public class MessageStrings: NSObject {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
@ -14,7 +14,7 @@ import Foundation
|
||||
let alertMessage = NSLocalizedString("CALL_AUDIO_PERMISSION_MESSAGE", comment:"Alert message when calling and permissions for microphone are missing")
|
||||
let alertController = UIAlertController(title: alertTitle, message: alertMessage, preferredStyle: .alert)
|
||||
let dismissAction = UIAlertAction(title: CommonStrings.dismissButton, style: .cancel)
|
||||
let settingsString = NSLocalizedString("OPEN_SETTINGS_BUTTON", comment: "Button text which opens the settings app")
|
||||
let settingsString = CommonStrings.openSettingsButton
|
||||
let settingsAction = UIAlertAction(title: settingsString, style: .default) { _ in
|
||||
CurrentAppContext().openSystemSettings()
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user