Merge branch 'mkirk/media-permissions'

pull/1/head
Michael Kirk 7 years ago
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…
Cancel
Save