session-ios/Signal/src/AppDelegate.m

247 lines
9.2 KiB
Mathematica
Raw Normal View History

2014-05-06 19:41:08 +02:00
#import "AppDelegate.h"
#import "AppAudioManager.h"
#import "CategorizingLogger.h"
#import "DebugLogger.h"
2014-05-06 19:41:08 +02:00
#import "DialerViewController.h"
#import "DiscardingLog.h"
2014-08-02 01:24:26 +02:00
#import "Environment.h"
2014-05-06 19:41:08 +02:00
#import "InCallViewController.h"
#import "PreferencesUtil.h"
2014-05-06 19:41:08 +02:00
#import "NotificationTracker.h"
#import "PushManager.h"
2014-05-06 19:41:08 +02:00
#import "PriorityQueue.h"
#import "RecentCallManager.h"
#import "Release.h"
#import "TSStorageManager.h"
#import "TSAccountManager.h"
2014-05-06 19:41:08 +02:00
#import "Util.h"
2014-08-02 01:24:26 +02:00
#import "VersionMigrations.h"
2014-05-06 19:41:08 +02:00
#import "InitialViewController.h"
#import <PastelogKit/Pastelog.h>
2014-05-06 19:41:08 +02:00
#define kSignalVersionKey @"SignalUpdateVersionKey"
#ifdef __APPLE__
#include "TargetConditionals.h"
#endif
@interface AppDelegate ()
2014-08-09 18:27:26 +02:00
@property (nonatomic, retain) UIWindow *blankWindow;
2014-05-06 19:41:08 +02:00
@property (nonatomic, strong) NotificationTracker *notificationTracker;
@property (nonatomic) TOCFutureSource *callPickUpFuture;
2014-05-06 19:41:08 +02:00
@end
@implementation AppDelegate
2014-05-06 19:41:08 +02:00
#pragma mark Detect updates - perform migrations
- (void)performUpdateCheck{
// We check if NSUserDefaults key for version exists.
NSString *previousVersion = Environment.preferences.lastRanVersion;
NSString *currentVersion = [Environment.preferences setAndGetCurrentVersion];
2014-05-06 19:41:08 +02:00
if (!previousVersion) {
2014-07-11 00:33:51 +02:00
DDLogError(@"No previous version found. Possibly first launch since install.");
[Environment resetAppData]; // We clean previous keychain entries in case their are some entries remaining.
2014-07-20 00:25:22 +02:00
} else if ([currentVersion compare:previousVersion options:NSNumericSearch] == NSOrderedDescending){
2014-10-06 01:28:45 +02:00
[Environment resetAppData];
// Application was updated, let's see if we have a migration scheme for it.
if ([previousVersion isEqualToString:@"1.0.2"]) {
// Migrate from custom preferences to NSUserDefaults
2014-08-02 01:24:26 +02:00
[VersionMigrations migrationFrom1Dot0Dot2toLarger];
}
2014-05-06 19:41:08 +02:00
}
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
BOOL loggingIsEnabled;
#ifdef DEBUG
// Specified at Product -> Scheme -> Edit Scheme -> Test -> Arguments -> Environment to avoid things like
// the phone directory being looked up during tests.
if (getenv("runningTests_dontStartApp")) {
return YES;
}
loggingIsEnabled = TRUE;
[DebugLogger.sharedInstance enableTTYLogging];
#elif RELEASE
loggingIsEnabled = Environment.preferences.loggingIsEnabled;
#endif
if (loggingIsEnabled) {
[DebugLogger.sharedInstance enableFileLogging];
}
[[TSStorageManager sharedManager] setupDatabase];
2014-05-06 19:41:08 +02:00
[self performUpdateCheck];
2014-08-09 18:27:26 +02:00
[self prepareScreenshotProtection];
2014-05-06 19:41:08 +02:00
self.notificationTracker = [NotificationTracker notificationTracker];
CategorizingLogger* logger = [CategorizingLogger categorizingLogger];
[logger addLoggingCallback:^(NSString *category, id details, NSUInteger index) {}];
[Environment setCurrent:[Release releaseEnvironmentWithLogging:logger]];
[Environment.getCurrent.phoneDirectoryManager startUntilCancelled:nil];
[Environment.getCurrent.contactsManager doAfterEnvironmentInitSetup];
[UIApplication.sharedApplication setStatusBarStyle:UIStatusBarStyleDefault];
2014-08-02 01:24:26 +02:00
2014-05-06 19:41:08 +02:00
//Accept push notification when app is not open
NSDictionary *remoteNotif = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
2014-05-06 19:41:08 +02:00
if (remoteNotif) {
2014-07-20 00:25:22 +02:00
DDLogInfo(@"Application was launched by tapping a push notification.");
2014-05-06 19:41:08 +02:00
[self application:application didReceiveRemoteNotification:remoteNotif];
}
2014-08-02 01:24:26 +02:00
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Storyboard" bundle:[NSBundle mainBundle]];
UIViewController *viewController;
if (![TSAccountManager isRegistered]) {
viewController = [storyboard instantiateViewControllerWithIdentifier:@"RegisterInitialViewController"];
} else{
viewController = [storyboard instantiateViewControllerWithIdentifier:@"UserInitialViewController"];
}
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = viewController;
[self.window makeKeyAndVisible];
[Environment.phoneManager.currentCallObservable watchLatestValue:^(CallState* latestCall) {
if (latestCall == nil){
return;
}
2014-05-06 19:41:08 +02:00
InCallViewController *callViewController = [InCallViewController inCallViewControllerWithCallState:latestCall
andOptionallyKnownContact:latestCall.potentiallySpecifiedContact];
if (latestCall.initiatedLocally == false){
[self.callPickUpFuture.future thenDo:^(NSNumber *accept) {
if ([accept isEqualToNumber:@YES]) {
[callViewController answerButtonTapped];
} else if ([accept isEqualToNumber:@NO]){
[callViewController rejectButtonTapped];
}
}];
}
[self.window.rootViewController dismissViewControllerAnimated:NO completion:nil];
[self.window.rootViewController presentViewController:callViewController animated:NO completion:nil];
} onThread:NSThread.mainThread untilCancelled:nil];
2014-05-06 19:41:08 +02:00
return YES;
}
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken {
2014-10-06 10:05:55 +02:00
[PushManager.sharedManager.pushNotificationFutureSource trySetResult:deviceToken];
2014-05-06 19:41:08 +02:00
}
2014-05-06 19:41:08 +02:00
- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error {
2014-10-06 10:05:55 +02:00
[PushManager.sharedManager.pushNotificationFutureSource trySetFailure:error];
}
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings{
2014-10-06 10:05:55 +02:00
[PushManager.sharedManager.userNotificationFutureSource trySetResult:notificationSettings];
2014-05-06 19:41:08 +02:00
}
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
ResponderSessionDescriptor* call;
@try {
call = [ResponderSessionDescriptor responderSessionDescriptorFromEncryptedRemoteNotification:userInfo];
2014-07-03 18:45:06 +02:00
DDLogDebug(@"Received remote notification. Parsed session descriptor: %@.", call);
2014-05-06 19:41:08 +02:00
} @catch (OperationFailed* ex) {
2014-07-03 18:45:06 +02:00
DDLogError(@"Error parsing remote notification. Error: %@.", ex);
2014-05-06 19:41:08 +02:00
return;
}
2014-08-02 01:24:26 +02:00
if (!call) {
DDLogError(@"Decryption of session descriptor failed");
return;
}
self.callPickUpFuture = [TOCFutureSource new];
[Environment.phoneManager incomingCallWithSession:call];
2014-05-06 19:41:08 +02:00
}
-(void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
if([self.notificationTracker shouldProcessNotification:userInfo]){
[self application:application didReceiveRemoteNotification:userInfo];
2014-07-03 18:45:06 +02:00
} else{
DDLogDebug(@"Push already processed. Skipping.");
2014-05-06 19:41:08 +02:00
}
completionHandler(UIBackgroundFetchResultNewData);
}
-(void) applicationDidBecomeActive:(UIApplication *)application {
[AppAudioManager.sharedInstance awake];
// Hacky way to clear notification center after processed push
[UIApplication.sharedApplication setApplicationIconBadgeNumber:1];
[UIApplication.sharedApplication setApplicationIconBadgeNumber:0];
2014-08-09 18:27:26 +02:00
[self removeScreenProtection];
if (Environment.isRedPhoneRegistered) {
[PushManager.sharedManager verifyPushPermissions];
[AppAudioManager.sharedInstance requestRequiredPermissionsIfNeeded];
}
2014-05-06 19:41:08 +02:00
}
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void (^)())completionHandler{
if ([identifier isEqualToString:Signal_Accept_Identifier]) {
[self.callPickUpFuture trySetResult:@YES];
} else if ([identifier isEqualToString:Signal_Decline_Identifier]){
[self.callPickUpFuture trySetResult:@NO];
}
completionHandler();
}
2014-08-09 18:27:26 +02:00
- (void)applicationWillResignActive:(UIApplication *)application{
[self protectScreen];
}
- (void)prepareScreenshotProtection{
self.blankWindow = ({
UIWindow *window = [[UIWindow alloc] initWithFrame:self.window.bounds];
window.hidden = YES;
window.opaque = YES;
window.userInteractionEnabled = NO;
window.windowLevel = CGFLOAT_MAX;
window;
});
}
- (void)protectScreen{
if (Environment.preferences.screenSecurityIsEnabled) {
self.blankWindow.rootViewController = [UIViewController new];
2014-08-09 18:27:26 +02:00
UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.blankWindow.bounds];
if (self.blankWindow.bounds.size.height == 568) {
imageView.image = [UIImage imageNamed:@"Default-568h"];
} else {
imageView.image = [UIImage imageNamed:@"Default"];
}
imageView.opaque = YES;
[self.blankWindow.rootViewController.view addSubview:imageView];
self.blankWindow.hidden = NO;
}
}
- (void)removeScreenProtection{
if (Environment.preferences.screenSecurityIsEnabled) {
2014-08-09 18:27:26 +02:00
self.blankWindow.rootViewController = nil;
self.blankWindow.hidden = YES;
}
}
2014-05-06 19:41:08 +02:00
@end