From 788aa8cb4f0ce10f5de9e3253bdaf957f802f32b Mon Sep 17 00:00:00 2001 From: Frederic Jacobs Date: Sun, 22 Mar 2015 12:38:15 +0100 Subject: [PATCH] Dropping some required permissions. Smarter microphone permission. --- Signal/src/AppDelegate.m | 17 +---- Signal/src/audio/AppAudioManager.h | 3 +- Signal/src/audio/AppAudioManager.m | 21 ++++-- Signal/src/contact/ContactsManager.m | 4 +- Signal/src/environment/Environment.h | 2 + Signal/src/environment/Environment.m | 14 ++++ Signal/src/network/PushManager.h | 7 -- Signal/src/network/PushManager.m | 34 +--------- Signal/src/phone/PhoneManager.m | 67 +++++++++++-------- .../RegistrationViewController.m | 1 + 10 files changed, 80 insertions(+), 90 deletions(-) diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index 775549565..f8551ba88 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -26,8 +26,6 @@ #endif -static NSString* const kCallSegue = @"2.0_6.0_Call_Segue"; - @interface AppDelegate () @property (nonatomic, retain) UIWindow *blankWindow; @@ -68,7 +66,6 @@ static NSString* const kCallSegue = @"2.0_6.0_Call_Segue"; } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - [self setupAppearance]; if (getenv("runningTests_dontStartApp")) { @@ -82,6 +79,7 @@ static NSString* const kCallSegue = @"2.0_6.0_Call_Segue"; [Environment setCurrent:[Release releaseEnvironmentWithLogging:logger]]; [Environment.getCurrent.phoneDirectoryManager startUntilCancelled:nil]; [Environment.getCurrent.contactsManager doAfterEnvironmentInitSetup]; + [Environment.getCurrent initCallListener]; [[TSStorageManager sharedManager] setupDatabase]; @@ -120,16 +118,6 @@ static NSString* const kCallSegue = @"2.0_6.0_Call_Segue"; [self prepareScreenshotProtection]; - [Environment.phoneManager.currentCallObservable watchLatestValue:^(CallState* latestCall) { - if (latestCall == nil){ - return; - } - SignalsViewController *vc = [[Environment getCurrent] signalsViewController]; - [vc dismissViewControllerAnimated:NO completion:nil]; - vc.latestCall = latestCall; - [vc performSegueWithIdentifier:kCallSegue sender:self]; - } onThread:NSThread.mainThread untilCancelled:nil]; - if ([TSAccountManager isRegistered]) { [TSSocketManager becomeActive]; [self refreshContacts]; @@ -236,9 +224,6 @@ static NSString* const kCallSegue = @"2.0_6.0_Call_Segue"; -(void) applicationDidBecomeActive:(UIApplication *)application { if ([TSAccountManager isRegistered]) { [TSSocketManager becomeActive]; - [AppAudioManager.sharedInstance awake]; - [PushManager.sharedManager verifyPushPermissions]; - [AppAudioManager.sharedInstance requestRequiredPermissionsIfNeeded]; } // Hacky way to clear notification center after processed push [UIApplication.sharedApplication setApplicationIconBadgeNumber:1]; diff --git a/Signal/src/audio/AppAudioManager.h b/Signal/src/audio/AppAudioManager.h index c9a4c1358..aff1bf7b3 100644 --- a/Signal/src/audio/AppAudioManager.h +++ b/Signal/src/audio/AppAudioManager.h @@ -1,5 +1,6 @@ #import +#import #import "CallProgress.h" #import "CallTermination.h" #import "SoundPlayer.h" @@ -33,7 +34,7 @@ enum AudioProfile { -(BOOL) toggleSpeakerPhone; -(void) cancellAllAudio; --(void) requestRequiredPermissionsIfNeeded; +-(void) requestRequiredPermissionsIfNeededWithCompletion:(PermissionBlock)permissionBlock incoming:(BOOL)isIncoming; -(BOOL) requestRecordingPrivilege; -(BOOL) releaseRecordingPrivilege; diff --git a/Signal/src/audio/AppAudioManager.m b/Signal/src/audio/AppAudioManager.m index c3ff2eb30..40c62965c 100644 --- a/Signal/src/audio/AppAudioManager.m +++ b/Signal/src/audio/AppAudioManager.m @@ -1,7 +1,5 @@ #import "AppAudioManager.h" -#import - #import "AudioRouter.h" #import "SoundBoard.h" #import "SoundPlayer.h" @@ -13,7 +11,7 @@ AppAudioManager* sharedAppAudioManager; -@interface AppAudioManager (){ +@interface AppAudioManager () { enum AudioProfile _audioProfile; BOOL isSpeakerphoneActive; } @@ -79,7 +77,6 @@ AppAudioManager* sharedAppAudioManager; switch (progressType){ case CallProgressType_Connecting: [sharedAppAudioManager setAudioEnabled:YES]; - [_soundPlayer stopAllAudio]; case CallProgressType_Ringing: (initiatedLocally) ? [self handleOutboundRing] : [self handleInboundRing]; break; @@ -160,15 +157,27 @@ AppAudioManager* sharedAppAudioManager; return [self changeAudioSessionCategoryTo:DEFAULT_CATEGORY]; } --(void) requestRequiredPermissionsIfNeeded { +-(void) requestRequiredPermissionsIfNeededWithCompletion:(PermissionBlock)permissionBlock incoming:(BOOL)isIncoming { [AVAudioSession.sharedInstance requestRecordPermission:^(BOOL granted) { if (!granted) { - UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"ACTION_REQUIRED_TITLE", @"") message:NSLocalizedString(@"AUDIO_PERMISSION_MESSAGE", @"") delegate:nil cancelButtonTitle:NSLocalizedString(@"OK", @"") otherButtonTitles:nil, nil]; + UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"ACTION_REQUIRED_TITLE", @"") message:NSLocalizedString(@"AUDIO_PERMISSION_MESSAGE", @"") delegate:nil cancelButtonTitle:NSLocalizedString(@"TXT_CANCEL_TITLE", @"") otherButtonTitles:NSLocalizedString(@"SETTINGS_NAV_BAR_TITLE",nil), nil]; + + [alertView setDelegate:self]; + [alertView show]; } + + permissionBlock(granted); }]; } +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{ + if (buttonIndex == 1) { // Tapped the Settings button + NSURL *appSettings = [NSURL URLWithString:UIApplicationOpenSettingsURLString]; + [[UIApplication sharedApplication] openURL:appSettings]; + } +} + -(BOOL) changeAudioSessionCategoryTo:(NSString*) category { NSError* e; [AVAudioSession.sharedInstance setCategory:category error:&e]; diff --git a/Signal/src/contact/ContactsManager.m b/Signal/src/contact/ContactsManager.m index 1b1a7ff67..426792f4d 100644 --- a/Signal/src/contact/ContactsManager.m +++ b/Signal/src/contact/ContactsManager.m @@ -90,7 +90,9 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in CFErrorRef creationError = nil; ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, &creationError); checkOperationDescribe(nil == creationError, [((__bridge NSError *)creationError) localizedDescription]) ; - ABAddressBookRequestAccessWithCompletion(addressBookRef, nil); + ABAddressBookRequestAccessWithCompletion(addressBookRef, ^(bool granted, CFErrorRef error) { + // TO DO: DISPLAY ALERT + }); [observableContactsController updateValue:[self getContactsFromAddressBook:addressBookRef]]; } diff --git a/Signal/src/environment/Environment.h b/Signal/src/environment/Environment.h index c3b6c5318..63a240440 100644 --- a/Signal/src/environment/Environment.h +++ b/Signal/src/environment/Environment.h @@ -80,6 +80,8 @@ andCurrentRegionCodeForPhoneNumbers:(NSString*)currentRegionCodeForPhoneNumbers +(BOOL)isRedPhoneRegistered; +(void)resetAppData; + +- (void)initCallListener; - (void)setSignalsViewController:(SignalsViewController *)signalsViewController; - (void)setSignUpFlowNavigationController:(UINavigationController *)signUpFlowNavigationController; diff --git a/Signal/src/environment/Environment.m b/Signal/src/environment/Environment.m index 2dc5fbdca..6dce37161 100644 --- a/Signal/src/environment/Environment.m +++ b/Signal/src/environment/Environment.m @@ -13,6 +13,7 @@ #import "SignalsViewController.h" #import "TSStorageManager.h" +static NSString* const kCallSegue = @"2.0_6.0_Call_Segue"; #define isRegisteredUserDefaultString @"isRegistered" static Environment* environment = nil; @@ -158,6 +159,19 @@ phoneDirectoryManager; return signalingKey && macKey && extra && serverAuth; } +- (void)initCallListener { + [self.phoneManager.currentCallObservable watchLatestValue:^(CallState* latestCall) { + if (latestCall == nil){ + return; + } + + SignalsViewController *vc = [[Environment getCurrent] signalsViewController]; + [vc dismissViewControllerAnimated:NO completion:nil]; + vc.latestCall = latestCall; + [vc performSegueWithIdentifier:kCallSegue sender:self]; + } onThread:NSThread.mainThread untilCancelled:nil]; +} + +(PropertyListPreferences*)preferences{ return [PropertyListPreferences new]; } diff --git a/Signal/src/network/PushManager.h b/Signal/src/network/PushManager.h index bc42d6493..0d08a618a 100644 --- a/Signal/src/network/PushManager.h +++ b/Signal/src/network/PushManager.h @@ -28,13 +28,6 @@ typedef void(^failedPushRegistrationBlock)(NSError *error); + (PushManager*)sharedManager; -/** - * Push notification token is always registered during signup. User can however revoke notifications. - * Therefore, we check on startup if mandatory permissions are granted. - */ - -- (void)verifyPushPermissions; - /** * Push notification registration method * diff --git a/Signal/src/network/PushManager.m b/Signal/src/network/PushManager.m index 51cf9c65a..a18c166e4 100644 --- a/Signal/src/network/PushManager.m +++ b/Signal/src/network/PushManager.m @@ -16,8 +16,7 @@ @interface PushManager () @property TOCFutureSource *registerWithServerFutureSource; -@property UIAlertView *missingPermissionsAlertView; - +@property UIAlertView *missingPermissionsAlertView; @end @@ -44,18 +43,7 @@ return self; } -- (void)verifyPushPermissions{ - if (self.isMissingMandatoryNotificationTypes || self.needToRegisterForRemoteNotifications){ - [self registrationWithSuccess:^{ - DDLogInfo(@"Re-enabled push succesfully"); - } failure:^(NSError *error) { - DDLogError(@"Failed to re-register for push"); - }]; - } -} - - (void)registrationWithSuccess:(void (^)())success failure:(failedPushRegistrationBlock)failure{ - if (!self.wantRemoteNotifications) { success(); return; @@ -69,7 +57,6 @@ } failure:failure]; } - #pragma mark Private Methods #pragma mark Register Push Notification Token with server @@ -128,7 +115,6 @@ }]; } - - (void)registrationAndRedPhoneTokenRequestWithSuccess:(void (^)(NSData* pushToken, NSString* signupToken))success failure:(failedPushRegistrationBlock)failure{ [self registrationForPushWithSuccess:^(NSData *pushToken) { [RPServerRequestsManager.sharedInstance performRequest:[RPAPICall requestTextSecureVerificationCode] success:^(NSURLSessionDataTask *task, id responseObject) { @@ -165,11 +151,7 @@ }]; [registrerUserNotificationFuture thenDo:^(id types) { - if (self.isMissingMandatoryNotificationTypes) { - failure(); - } else{ - success(); - } + success(); }]; } @@ -188,20 +170,8 @@ return YES; } - --(BOOL)isMissingMandatoryNotificationTypes { - int mandatoryTypes = self.mandatoryNotificationTypes; - int currentTypes = UIApplication.sharedApplication.currentUserNotificationSettings.types; - - return (mandatoryTypes & currentTypes) != mandatoryTypes; -} - -(int)allNotificationTypes{ return UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge; } --(int)mandatoryNotificationTypes{ - return UIUserNotificationTypeAlert | UIUserNotificationTypeSound; -} - @end diff --git a/Signal/src/phone/PhoneManager.m b/Signal/src/phone/PhoneManager.m index 290545ca5..222af1353 100644 --- a/Signal/src/phone/PhoneManager.m +++ b/Signal/src/phone/PhoneManager.m @@ -1,3 +1,4 @@ +#import "AppAudioManager.h" #import "CallAudioManager.h" #import "PhoneManager.h" #import "ThreadManager.h" @@ -52,22 +53,30 @@ -(void) initiateOutgoingCallToRemoteNumber:(PhoneNumber*)remoteNumber withOptionallyKnownContact:(Contact*)contact { require(remoteNumber != nil); - + + [[AppAudioManager sharedInstance] requestRequiredPermissionsIfNeededWithCompletion:^(BOOL granted) { + if (granted) { + [self callToRemoteNumber:remoteNumber withOptionallyKnownContact:contact]; + } + } incoming:NO]; +} + +- (void)callToRemoteNumber:(PhoneNumber*)remoteNumber withOptionallyKnownContact:(Contact*)contact { CallController* callController = [self cancelExistingCallAndInitNewCallWork:true remote:remoteNumber optionalContact:contact]; [callController acceptCall]; // initiator implicitly accepts call TOCCancelToken* lifetime = [callController untilCancelledToken]; - + TOCFuture* futureConnected = [CallConnectUtil asyncInitiateCallToRemoteNumber:remoteNumber andCallController:callController]; TOCFuture* futureCalling = [futureConnected thenTry:^id(CallConnectResult* connectResult) { [callController advanceCallProgressToConversingWithShortAuthenticationString:connectResult.shortAuthenticationString]; CallAudioManager *cam = [CallAudioManager callAudioManagerStartedWithAudioSocket:connectResult.audioSocket - andErrorHandler:callController.errorHandler - untilCancelled:lifetime]; - [callController setCallAudioManager:cam]; + andErrorHandler:callController.errorHandler + untilCancelled:lifetime]; + [callController setCallAudioManager:cam]; return nil; }]; @@ -96,28 +105,32 @@ return; } - Contact* callingContact = [Environment.getCurrent.contactsManager latestContactForPhoneNumber:session.initiatorNumber]; - CallController* callController = [self cancelExistingCallAndInitNewCallWork:false - remote:session.initiatorNumber - optionalContact:callingContact]; - - TOCCancelToken* lifetime = [callController untilCancelledToken]; - - TOCFuture* futureConnected = [CallConnectUtil asyncRespondToCallWithSessionDescriptor:session - andCallController:callController]; - - TOCFuture* futureStarted = [futureConnected thenTry:^id(CallConnectResult* connectResult) { - [callController advanceCallProgressToConversingWithShortAuthenticationString:connectResult.shortAuthenticationString]; - CallAudioManager* cam = [CallAudioManager callAudioManagerStartedWithAudioSocket:connectResult.audioSocket - andErrorHandler:callController.errorHandler - untilCancelled:lifetime]; - [callController setCallAudioManager:cam]; - return nil; - }]; - - [futureStarted catchDo:^(id error) { - callController.errorHandler(error, nil, true); - }]; + [[AppAudioManager sharedInstance] requestRequiredPermissionsIfNeededWithCompletion:^(BOOL granted) { + if (granted) { + Contact* callingContact = [Environment.getCurrent.contactsManager latestContactForPhoneNumber:session.initiatorNumber]; + CallController* callController = [self cancelExistingCallAndInitNewCallWork:false + remote:session.initiatorNumber + optionalContact:callingContact]; + + TOCCancelToken* lifetime = [callController untilCancelledToken]; + + TOCFuture* futureConnected = [CallConnectUtil asyncRespondToCallWithSessionDescriptor:session + andCallController:callController]; + + TOCFuture* futureStarted = [futureConnected thenTry:^id(CallConnectResult* connectResult) { + [callController advanceCallProgressToConversingWithShortAuthenticationString:connectResult.shortAuthenticationString]; + CallAudioManager* cam = [CallAudioManager callAudioManagerStartedWithAudioSocket:connectResult.audioSocket + andErrorHandler:callController.errorHandler + untilCancelled:lifetime]; + [callController setCallAudioManager:cam]; + return nil; + }]; + + [futureStarted catchDo:^(id error) { + callController.errorHandler(error, nil, true); + }]; + } + } incoming:YES]; } -(CallController*) curCallController { return currentCallControllerObservable.currentValue; diff --git a/Signal/src/view controllers/RegistrationViewController.m b/Signal/src/view controllers/RegistrationViewController.m index 3160f855f..c35b332e7 100644 --- a/Signal/src/view controllers/RegistrationViewController.m +++ b/Signal/src/view controllers/RegistrationViewController.m @@ -49,6 +49,7 @@ static NSString *const kCodeSentSegue = @"codeSent"; [_countryNameButton setTitle:NSLocalizedString(@"REGISTRATION_DEFAULT_COUNTRY_NAME", @"") forState:UIControlStateNormal]; _phoneNumberTextField.placeholder = NSLocalizedString(@"REGISTRATION_ENTERNUMBER_DEFAULT_TEXT", @""); [_phoneNumberButton setTitle:NSLocalizedString(@"REGISTRATION_PHONENUMBER_BUTTON",@"") forState:UIControlStateNormal]; + [_phoneNumberButton.titleLabel setAdjustsFontSizeToFitWidth:YES]; [_sendCodeButton setTitle:NSLocalizedString(@"REGISTRATION_VERIFY_DEVICE", @"") forState:UIControlStateNormal]; }