2017-01-17 22:01:19 +01:00
|
|
|
//
|
2019-01-08 17:47:40 +01:00
|
|
|
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
|
2017-01-17 22:01:19 +01:00
|
|
|
//
|
|
|
|
|
2014-05-06 19:41:08 +02:00
|
|
|
#import "AppDelegate.h"
|
2014-08-09 01:01:05 +02:00
|
|
|
#import "DebugLogger.h"
|
2018-04-24 19:15:11 +02:00
|
|
|
#import "HomeViewController.h"
|
2017-11-29 20:51:39 +01:00
|
|
|
#import "MainAppContext.h"
|
2018-03-01 20:41:45 +01:00
|
|
|
#import "OWS2FASettingsViewController.h"
|
2018-03-06 16:10:22 +01:00
|
|
|
#import "OWSBackup.h"
|
2018-08-02 21:18:40 +02:00
|
|
|
#import "OWSOrphanDataCleaner.h"
|
2018-03-21 20:46:23 +01:00
|
|
|
#import "OWSScreenLockUI.h"
|
2017-03-23 14:55:39 +01:00
|
|
|
#import "Pastelog.h"
|
2019-05-02 23:58:48 +02:00
|
|
|
#import "Session-Swift.h"
|
2017-12-04 16:35:47 +01:00
|
|
|
#import "SignalApp.h"
|
2017-07-10 22:04:03 +02:00
|
|
|
#import "SignalsNavigationController.h"
|
2017-04-28 18:18:42 +02:00
|
|
|
#import "ViewControllerUtils.h"
|
2018-03-05 21:13:19 +01:00
|
|
|
#import <PromiseKit/AnyPromise.h>
|
2018-09-21 21:41:10 +02:00
|
|
|
#import <SignalCoreKit/iOSVersions.h>
|
2017-12-07 19:53:13 +01:00
|
|
|
#import <SignalMessaging/AppSetup.h>
|
2017-12-19 03:50:51 +01:00
|
|
|
#import <SignalMessaging/Environment.h>
|
|
|
|
#import <SignalMessaging/OWSContactsManager.h>
|
2018-05-17 04:42:00 +02:00
|
|
|
#import <SignalMessaging/OWSNavigationController.h>
|
2017-12-19 03:50:51 +01:00
|
|
|
#import <SignalMessaging/OWSPreferences.h>
|
2017-12-04 16:35:47 +01:00
|
|
|
#import <SignalMessaging/OWSProfileManager.h>
|
2017-11-30 16:02:04 +01:00
|
|
|
#import <SignalMessaging/SignalMessaging.h>
|
2017-12-19 03:50:51 +01:00
|
|
|
#import <SignalMessaging/VersionMigrations.h>
|
2018-01-26 21:53:26 +01:00
|
|
|
#import <SignalServiceKit/AppReadiness.h>
|
2017-11-28 19:46:26 +01:00
|
|
|
#import <SignalServiceKit/NSUserDefaults+OWS.h>
|
2018-03-01 20:41:45 +01:00
|
|
|
#import <SignalServiceKit/OWS2FAManager.h>
|
2017-09-13 18:49:19 +02:00
|
|
|
#import <SignalServiceKit/OWSBatchMessageProcessor.h>
|
2016-09-21 14:37:51 +02:00
|
|
|
#import <SignalServiceKit/OWSDisappearingMessagesJob.h>
|
2017-03-29 00:01:31 +02:00
|
|
|
#import <SignalServiceKit/OWSFailedAttachmentDownloadsJob.h>
|
2017-02-09 19:53:03 +01:00
|
|
|
#import <SignalServiceKit/OWSFailedMessagesJob.h>
|
2018-07-11 15:58:02 +02:00
|
|
|
#import <SignalServiceKit/OWSIncompleteCallsJob.h>
|
2019-01-24 19:28:54 +01:00
|
|
|
#import <SignalServiceKit/OWSMath.h>
|
2017-09-14 17:00:30 +02:00
|
|
|
#import <SignalServiceKit/OWSMessageManager.h>
|
2016-10-14 22:59:58 +02:00
|
|
|
#import <SignalServiceKit/OWSMessageSender.h>
|
2018-03-05 15:30:58 +01:00
|
|
|
#import <SignalServiceKit/OWSPrimaryStorage+Calling.h>
|
2017-09-21 22:58:07 +02:00
|
|
|
#import <SignalServiceKit/OWSReadReceiptManager.h>
|
2018-08-31 19:12:40 +02:00
|
|
|
#import <SignalServiceKit/SSKEnvironment.h>
|
2018-10-01 17:38:40 +02:00
|
|
|
#import <SignalServiceKit/SignalServiceKit-Swift.h>
|
2016-10-10 22:02:09 +02:00
|
|
|
#import <SignalServiceKit/TSAccountManager.h>
|
2017-06-15 19:43:18 +02:00
|
|
|
#import <SignalServiceKit/TSDatabaseView.h>
|
2017-02-10 22:24:48 +01:00
|
|
|
#import <SignalServiceKit/TSPreKeyManager.h>
|
2017-05-27 02:41:27 +02:00
|
|
|
#import <SignalServiceKit/TSSocketManager.h>
|
2018-01-24 23:11:18 +01:00
|
|
|
#import <YapDatabase/YapDatabaseCryptoUtils.h>
|
2018-10-25 16:18:09 +02:00
|
|
|
#import <sys/utsname.h>
|
2020-03-06 01:54:20 +01:00
|
|
|
#import <FirebaseCore/FirebaseCore.h>
|
2016-10-10 22:02:09 +02:00
|
|
|
|
2016-11-12 18:22:29 +01:00
|
|
|
@import WebRTC;
|
2017-02-01 23:49:32 +01:00
|
|
|
@import Intents;
|
2016-11-12 18:22:29 +01:00
|
|
|
|
2016-10-10 22:02:09 +02:00
|
|
|
NSString *const AppDelegateStoryboardMain = @"Main";
|
2014-10-05 19:18:18 +02:00
|
|
|
|
2015-12-22 12:45:09 +01:00
|
|
|
static NSString *const kInitialViewControllerIdentifier = @"UserInitialViewController";
|
2020-04-15 05:40:19 +02:00
|
|
|
static NSString *const kURLSchemeSGNLKey = @"sgnl";
|
|
|
|
static NSString *const kURLHostVerifyPrefix = @"verify";
|
2015-07-10 15:00:14 +02:00
|
|
|
|
2018-04-23 15:30:37 +02:00
|
|
|
static NSTimeInterval launchStartedAt;
|
|
|
|
|
2020-03-27 05:10:34 +01:00
|
|
|
// Debug settings
|
2020-03-06 01:54:20 +01:00
|
|
|
static BOOL isInternalTestVersion = NO;
|
|
|
|
|
2019-09-20 07:53:24 +02:00
|
|
|
@interface AppDelegate () <UNUserNotificationCenterDelegate>
|
2014-05-06 19:41:08 +02:00
|
|
|
|
2017-06-15 23:15:56 +02:00
|
|
|
@property (nonatomic) BOOL hasInitialRootViewController;
|
2018-01-30 17:27:44 +01:00
|
|
|
@property (nonatomic) BOOL areVersionMigrationsComplete;
|
2018-02-12 17:41:22 +01:00
|
|
|
@property (nonatomic) BOOL didAppLaunchFail;
|
2019-08-29 07:21:45 +02:00
|
|
|
|
|
|
|
// Loki
|
2019-08-21 03:50:23 +02:00
|
|
|
@property (nonatomic) LKP2PServer *lokiP2PServer;
|
2020-03-25 00:27:43 +01:00
|
|
|
@property (nonatomic) LKPoller *lokiPoller;
|
2019-08-27 08:48:53 +02:00
|
|
|
@property (nonatomic) LKRSSFeedPoller *lokiNewsFeedPoller;
|
|
|
|
@property (nonatomic) LKRSSFeedPoller *lokiMessengerUpdatesFeedPoller;
|
2014-09-15 01:32:19 +02:00
|
|
|
|
2014-05-06 19:41:08 +02:00
|
|
|
@end
|
|
|
|
|
2017-07-04 19:24:25 +02:00
|
|
|
#pragma mark -
|
|
|
|
|
2014-08-01 07:53:58 +02:00
|
|
|
@implementation AppDelegate
|
2014-05-06 19:41:08 +02:00
|
|
|
|
2017-07-10 22:04:03 +02:00
|
|
|
@synthesize window = _window;
|
|
|
|
|
2018-10-22 18:31:28 +02:00
|
|
|
#pragma mark - Dependencies
|
|
|
|
|
|
|
|
- (OWSProfileManager *)profileManager
|
|
|
|
{
|
|
|
|
return [OWSProfileManager sharedManager];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (OWSReadReceiptManager *)readReceiptManager
|
|
|
|
{
|
|
|
|
return [OWSReadReceiptManager sharedManager];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id<OWSUDManager>)udManager
|
|
|
|
{
|
|
|
|
OWSAssertDebug(SSKEnvironment.shared.udManager);
|
|
|
|
|
|
|
|
return SSKEnvironment.shared.udManager;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (OWSPrimaryStorage *)primaryStorage
|
|
|
|
{
|
|
|
|
OWSAssertDebug(SSKEnvironment.shared.primaryStorage);
|
|
|
|
|
|
|
|
return SSKEnvironment.shared.primaryStorage;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (PushRegistrationManager *)pushRegistrationManager
|
|
|
|
{
|
|
|
|
OWSAssertDebug(AppEnvironment.shared.pushRegistrationManager);
|
|
|
|
|
|
|
|
return AppEnvironment.shared.pushRegistrationManager;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (TSAccountManager *)tsAccountManager
|
|
|
|
{
|
|
|
|
OWSAssertDebug(SSKEnvironment.shared.tsAccountManager);
|
|
|
|
|
|
|
|
return SSKEnvironment.shared.tsAccountManager;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (OWSDisappearingMessagesJob *)disappearingMessagesJob
|
|
|
|
{
|
|
|
|
OWSAssertDebug(SSKEnvironment.shared.disappearingMessagesJob);
|
|
|
|
|
|
|
|
return SSKEnvironment.shared.disappearingMessagesJob;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (TSSocketManager *)socketManager
|
|
|
|
{
|
|
|
|
OWSAssertDebug(SSKEnvironment.shared.socketManager);
|
|
|
|
|
|
|
|
return SSKEnvironment.shared.socketManager;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (OWSMessageManager *)messageManager
|
|
|
|
{
|
|
|
|
OWSAssertDebug(SSKEnvironment.shared.messageManager);
|
|
|
|
|
|
|
|
return SSKEnvironment.shared.messageManager;
|
|
|
|
}
|
|
|
|
|
2018-10-25 19:02:30 +02:00
|
|
|
- (OWSWindowManager *)windowManager
|
|
|
|
{
|
|
|
|
return Environment.shared.windowManager;
|
|
|
|
}
|
|
|
|
|
2018-11-21 23:52:34 +01:00
|
|
|
- (OWSBackup *)backup
|
|
|
|
{
|
|
|
|
return AppEnvironment.shared.backup;
|
|
|
|
}
|
|
|
|
|
2019-01-18 18:54:09 +01:00
|
|
|
- (OWSNotificationPresenter *)notificationPresenter
|
|
|
|
{
|
|
|
|
return AppEnvironment.shared.notificationPresenter;
|
|
|
|
}
|
|
|
|
|
2019-01-31 01:09:45 +01:00
|
|
|
- (OWSUserNotificationActionHandler *)userNotificationActionHandler
|
|
|
|
{
|
|
|
|
return AppEnvironment.shared.userNotificationActionHandler;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (OWSLegacyNotificationActionHandler *)legacyNotificationActionHandler
|
|
|
|
{
|
|
|
|
return AppEnvironment.shared.legacyNotificationActionHandler;
|
|
|
|
}
|
|
|
|
|
2019-05-22 05:09:01 +02:00
|
|
|
- (LKFriendRequestExpirationJob *)lokiFriendRequestExpirationJob
|
2019-05-20 03:17:58 +02:00
|
|
|
{
|
2019-05-22 05:09:01 +02:00
|
|
|
return SSKEnvironment.shared.lokiFriendRequestExpirationJob;
|
2019-05-20 03:17:58 +02:00
|
|
|
}
|
|
|
|
|
2018-10-22 18:31:28 +02:00
|
|
|
#pragma mark -
|
|
|
|
|
2019-02-22 01:05:18 +01:00
|
|
|
- (void)applicationDidEnterBackground:(UIApplication *)application
|
|
|
|
{
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSLogInfo(@"applicationDidEnterBackground");
|
2019-01-28 17:48:49 +01:00
|
|
|
|
2017-02-14 17:05:59 +01:00
|
|
|
[DDLog flushLog];
|
2019-06-11 08:22:35 +02:00
|
|
|
|
2020-02-21 04:40:44 +01:00
|
|
|
// Loki: Stop pollers
|
2020-03-25 00:27:43 +01:00
|
|
|
[self stopPollerIfNeeded];
|
2020-02-21 04:40:44 +01:00
|
|
|
[self stopOpenGroupPollersIfNeeded];
|
2017-01-17 23:10:57 +01:00
|
|
|
}
|
|
|
|
|
2019-02-22 01:05:18 +01:00
|
|
|
- (void)applicationWillEnterForeground:(UIApplication *)application
|
|
|
|
{
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSLogInfo(@"applicationWillEnterForeground");
|
2015-09-01 19:22:08 +02:00
|
|
|
}
|
|
|
|
|
2017-01-23 19:31:23 +01:00
|
|
|
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
|
|
|
|
{
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSLogInfo(@"applicationDidReceiveMemoryWarning");
|
2017-01-23 19:31:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)applicationWillTerminate:(UIApplication *)application
|
|
|
|
{
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSLogInfo(@"applicationWillTerminate");
|
2017-11-08 19:03:51 +01:00
|
|
|
|
2017-02-14 17:05:59 +01:00
|
|
|
[DDLog flushLog];
|
2020-02-21 04:40:44 +01:00
|
|
|
|
|
|
|
// Loki: Stop pollers
|
2020-03-25 00:27:43 +01:00
|
|
|
[self stopPollerIfNeeded];
|
2020-02-21 04:40:44 +01:00
|
|
|
[self stopOpenGroupPollersIfNeeded];
|
2019-08-29 07:21:45 +02:00
|
|
|
|
2019-05-22 06:29:59 +02:00
|
|
|
if (self.lokiP2PServer) { [self.lokiP2PServer stop]; }
|
2017-01-23 19:31:23 +01:00
|
|
|
}
|
|
|
|
|
2014-05-06 19:41:08 +02:00
|
|
|
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
2017-11-29 17:01:30 +01:00
|
|
|
|
|
|
|
// This should be the first thing we do.
|
2017-11-29 20:51:39 +01:00
|
|
|
SetCurrentAppContext([MainAppContext new]);
|
2017-11-29 17:01:30 +01:00
|
|
|
|
2018-04-23 15:30:37 +02:00
|
|
|
launchStartedAt = CACurrentMediaTime();
|
|
|
|
|
2017-12-01 18:20:09 +01:00
|
|
|
BOOL isLoggingEnabled;
|
2017-01-24 00:25:59 +01:00
|
|
|
#ifdef DEBUG
|
|
|
|
// Specified at Product -> Scheme -> Edit Scheme -> Test -> Arguments -> Environment to avoid things like
|
|
|
|
// the phone directory being looked up during tests.
|
2017-12-01 18:20:09 +01:00
|
|
|
isLoggingEnabled = TRUE;
|
2017-01-24 00:25:59 +01:00
|
|
|
[DebugLogger.sharedLogger enableTTYLogging];
|
|
|
|
#elif RELEASE
|
2017-12-01 18:20:09 +01:00
|
|
|
isLoggingEnabled = OWSPreferences.isLoggingEnabled;
|
2017-01-24 00:25:59 +01:00
|
|
|
#endif
|
2017-12-01 18:20:09 +01:00
|
|
|
if (isLoggingEnabled) {
|
2017-01-24 00:25:59 +01:00
|
|
|
[DebugLogger.sharedLogger enableFileLogging];
|
|
|
|
}
|
2015-12-22 12:45:09 +01:00
|
|
|
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSLogWarn(@"application:didFinishLaunchingWithOptions");
|
2018-08-03 01:21:01 +02:00
|
|
|
[Cryptography seedRandom];
|
2018-01-19 16:42:07 +01:00
|
|
|
|
2018-03-05 15:30:58 +01:00
|
|
|
// XXX - careful when moving this. It must happen before we initialize OWSPrimaryStorage.
|
2018-01-19 16:42:07 +01:00
|
|
|
[self verifyDBKeysAvailableBeforeBackgroundLaunch];
|
2017-11-28 19:46:26 +01:00
|
|
|
|
|
|
|
#if RELEASE
|
2017-11-28 22:30:08 +01:00
|
|
|
// ensureIsReadyForAppExtensions may have changed the state of the logging
|
2017-11-30 16:02:04 +01:00
|
|
|
// preference (due to [NSUserDefaults migrateToSharedUserDefaults]), so honor
|
|
|
|
// that change if necessary.
|
2017-12-01 18:20:09 +01:00
|
|
|
if (isLoggingEnabled && !OWSPreferences.isLoggingEnabled) {
|
2017-11-28 19:46:26 +01:00
|
|
|
[DebugLogger.sharedLogger disableFileLogging];
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2018-01-19 16:42:07 +01:00
|
|
|
// We need to do this _after_ we set up logging, when the keychain is unlocked,
|
|
|
|
// but before we access YapDatabase, files on disk, or NSUserDefaults
|
2018-02-12 17:41:22 +01:00
|
|
|
if (![self ensureIsReadyForAppExtensions]) {
|
|
|
|
// If this method has failed; do nothing.
|
|
|
|
//
|
|
|
|
// ensureIsReadyForAppExtensions will show a failure mode UI that
|
|
|
|
// lets users report this error.
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSLogInfo(@"application:didFinishLaunchingWithOptions failed");
|
2018-02-12 17:41:22 +01:00
|
|
|
|
|
|
|
return YES;
|
|
|
|
}
|
2018-01-19 16:42:07 +01:00
|
|
|
|
2018-08-02 21:18:40 +02:00
|
|
|
[AppVersion sharedInstance];
|
2017-05-09 21:58:40 +02:00
|
|
|
|
2017-09-14 21:24:31 +02:00
|
|
|
[self startupLogging];
|
|
|
|
|
2017-07-06 18:52:44 +02:00
|
|
|
// Prevent the device from sleeping during database view async registration
|
|
|
|
// (e.g. long database upgrades).
|
|
|
|
//
|
2017-12-19 04:56:02 +01:00
|
|
|
// This block will be cleared in storageIsReady.
|
2017-07-06 18:52:44 +02:00
|
|
|
[DeviceSleepManager.sharedInstance addBlockWithBlockObject:self];
|
|
|
|
|
2018-09-17 15:27:58 +02:00
|
|
|
[AppSetup
|
|
|
|
setupEnvironmentWithAppSpecificSingletonBlock:^{
|
2018-10-15 20:34:41 +02:00
|
|
|
// Create AppEnvironment.
|
2018-10-15 21:51:43 +02:00
|
|
|
[AppEnvironment.shared setup];
|
2018-10-15 20:34:41 +02:00
|
|
|
[SignalApp.sharedApp setup];
|
2018-04-23 21:49:20 +02:00
|
|
|
}
|
|
|
|
migrationCompletion:^{
|
|
|
|
OWSAssertIsOnMainThread();
|
|
|
|
|
|
|
|
[self versionMigrationsDidComplete];
|
2017-12-07 19:53:13 +01:00
|
|
|
}];
|
2015-12-22 12:45:09 +01:00
|
|
|
|
2020-01-20 03:20:27 +01:00
|
|
|
[LKAppearanceUtilities switchToSessionAppearance];
|
2016-09-11 22:53:12 +02:00
|
|
|
|
2017-12-04 18:38:44 +01:00
|
|
|
if (CurrentAppContext().isRunningTests) {
|
2016-09-11 22:53:12 +02:00
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
2018-04-16 23:19:06 +02:00
|
|
|
UIWindow *mainWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
|
|
|
|
self.window = mainWindow;
|
|
|
|
CurrentAppContext().mainWindow = mainWindow;
|
2018-04-23 15:30:37 +02:00
|
|
|
// Show LoadingViewController until the async database view registrations are complete.
|
|
|
|
mainWindow.rootViewController = [LoadingViewController new];
|
2018-04-16 23:19:06 +02:00
|
|
|
[mainWindow makeKeyAndVisible];
|
2015-12-22 12:45:09 +01:00
|
|
|
|
2019-01-18 18:54:09 +01:00
|
|
|
if (@available(iOS 11, *)) {
|
|
|
|
// This must happen in appDidFinishLaunching or earlier to ensure we don't
|
|
|
|
// miss notifications.
|
|
|
|
// Setting the delegate also seems to prevent us from getting the legacy notification
|
|
|
|
// notification callbacks upon launch e.g. 'didReceiveLocalNotification'
|
|
|
|
UNUserNotificationCenter.currentNotificationCenter.delegate = self;
|
|
|
|
}
|
|
|
|
|
2015-12-22 12:45:09 +01:00
|
|
|
// Accept push notification when app is not open
|
2014-08-13 02:02:29 +02:00
|
|
|
NSDictionary *remoteNotif = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
|
2014-05-06 19:41:08 +02:00
|
|
|
if (remoteNotif) {
|
2018-08-27 18:00:28 +02:00
|
|
|
OWSLogInfo(@"Application was launched by tapping a push notification.");
|
2015-12-22 12:45:09 +01:00
|
|
|
[self application:application didReceiveRemoteNotification:remoteNotif];
|
2014-05-06 19:41:08 +02:00
|
|
|
}
|
2015-12-22 12:45:09 +01:00
|
|
|
|
2018-03-21 20:46:23 +01:00
|
|
|
[OWSScreenLockUI.sharedManager setupWithRootWindow:self.window];
|
2018-04-24 23:00:39 +02:00
|
|
|
[[OWSWindowManager sharedManager] setupWithRootWindow:self.window
|
|
|
|
screenBlockingWindow:OWSScreenLockUI.sharedManager.screenBlockingWindow];
|
|
|
|
[OWSScreenLockUI.sharedManager startObserving];
|
2015-12-22 12:45:09 +01:00
|
|
|
|
2017-06-15 19:43:18 +02:00
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
2017-12-19 04:56:02 +01:00
|
|
|
selector:@selector(storageIsReady)
|
|
|
|
name:StorageIsReadyNotification
|
2017-06-15 19:43:18 +02:00
|
|
|
object:nil];
|
2017-09-14 21:29:59 +02:00
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
|
|
selector:@selector(registrationStateDidChange)
|
2017-12-04 18:38:44 +01:00
|
|
|
name:RegistrationStateDidChangeNotification
|
2017-09-14 21:29:59 +02:00
|
|
|
object:nil];
|
2018-03-05 21:13:19 +01:00
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
|
|
selector:@selector(registrationLockDidChange:)
|
|
|
|
name:NSNotificationName_2FAStateDidChange
|
|
|
|
object:nil];
|
2019-06-11 08:22:35 +02:00
|
|
|
|
2019-10-03 03:30:45 +02:00
|
|
|
// Loki - Observe thread deleted notifications
|
2019-11-20 06:27:34 +01:00
|
|
|
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(handleThreadDeleted:) name:NSNotification.threadDeleted object:nil];
|
2017-06-15 19:43:18 +02:00
|
|
|
|
2019-11-20 06:27:34 +01:00
|
|
|
// Loki - Observe data nuke request notifications
|
|
|
|
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(handleDataNukeRequested:) name:NSNotification.dataNukeRequested object:nil];
|
|
|
|
|
2018-08-27 18:51:32 +02:00
|
|
|
OWSLogInfo(@"application: didFinishLaunchingWithOptions completed.");
|
2017-06-20 18:05:06 +02:00
|
|
|
|
2017-07-21 17:49:38 +02:00
|
|
|
[OWSAnalytics appLaunchDidBegin];
|
2019-05-22 02:34:08 +02:00
|
|
|
|
|
|
|
// Loki
|
2019-06-14 03:40:54 +02:00
|
|
|
// self.lokiP2PServer = [LKP2PServer new];
|
2019-05-22 03:52:32 +02:00
|
|
|
|
|
|
|
// We try to bind to 8081, if we can't then we just fallback to any random port
|
2019-06-14 03:40:54 +02:00
|
|
|
// NSArray *ports = @[ @8081, @0 ];
|
|
|
|
// for (NSNumber *port in ports) {
|
|
|
|
// if (self.lokiP2PServer.isRunning) { break; }
|
|
|
|
// BOOL isStarted = [self.lokiP2PServer startOnPort:port.unsignedIntegerValue];
|
|
|
|
// if (isStarted) {
|
|
|
|
// NSURL *serverURL = self.lokiP2PServer.serverURL;
|
|
|
|
// [LKP2PAPI setOurP2PAddressWithUrl:self.lokiP2PServer.serverURL];
|
|
|
|
// NSString *serverURLDescription = serverURL.absoluteString;
|
|
|
|
// if ([serverURLDescription hasSuffix:@"/"]) {
|
|
|
|
// serverURLDescription = [serverURLDescription substringToIndex:serverURLDescription.length - 1];
|
|
|
|
// }
|
|
|
|
// NSLog(@"[Loki] Started server at %@.", serverURLDescription);
|
|
|
|
// break;
|
|
|
|
// }
|
|
|
|
// }
|
2019-05-22 03:52:32 +02:00
|
|
|
|
2019-06-14 03:40:54 +02:00
|
|
|
// if (!self.lokiP2PServer.isRunning) {
|
|
|
|
// NSLog(@"[Loki] Failed to start P2P server.");
|
|
|
|
// }
|
2020-03-06 01:54:20 +01:00
|
|
|
|
|
|
|
if (isInternalTestVersion) {
|
|
|
|
[FIRApp configure];
|
|
|
|
}
|
|
|
|
|
2014-05-06 19:41:08 +02:00
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
2017-12-05 17:35:43 +01:00
|
|
|
/**
|
|
|
|
* The user must unlock the device once after reboot before the database encryption key can be accessed.
|
|
|
|
*/
|
|
|
|
- (void)verifyDBKeysAvailableBeforeBackgroundLaunch
|
|
|
|
{
|
2017-12-05 19:44:25 +01:00
|
|
|
if ([UIApplication sharedApplication].applicationState != UIApplicationStateBackground) {
|
2017-12-05 17:35:43 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-03-05 15:30:58 +01:00
|
|
|
if (![OWSPrimaryStorage isDatabasePasswordAccessible]) {
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSLogInfo(@"Exiting because we are in the background and the database password is not accessible.");
|
2018-06-04 20:00:45 +02:00
|
|
|
|
|
|
|
UILocalNotification *notification = [UILocalNotification new];
|
|
|
|
NSString *messageFormat = NSLocalizedString(@"NOTIFICATION_BODY_PHONE_LOCKED_FORMAT",
|
|
|
|
@"Lock screen notification text presented after user powers on their device without unlocking. Embeds "
|
|
|
|
@"{{device model}} (either 'iPad' or 'iPhone')");
|
|
|
|
notification.alertBody = [NSString stringWithFormat:messageFormat, UIDevice.currentDevice.localizedModel];
|
|
|
|
|
|
|
|
// Make sure we clear any existing notifications so that they don't start stacking up
|
|
|
|
// if the user receives multiple pushes.
|
|
|
|
[UIApplication.sharedApplication cancelAllLocalNotifications];
|
|
|
|
[UIApplication.sharedApplication setApplicationIconBadgeNumber:0];
|
|
|
|
|
2019-05-10 04:02:04 +02:00
|
|
|
[UIApplication.sharedApplication scheduleLocalNotification:notification];
|
2018-06-04 20:00:45 +02:00
|
|
|
[UIApplication.sharedApplication setApplicationIconBadgeNumber:1];
|
|
|
|
|
2018-11-19 18:20:19 +01:00
|
|
|
[DDLog flushLog];
|
|
|
|
exit(0);
|
2017-12-05 17:35:43 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-12 17:41:22 +01:00
|
|
|
- (BOOL)ensureIsReadyForAppExtensions
|
2017-11-28 19:46:26 +01:00
|
|
|
{
|
2018-02-20 23:37:14 +01:00
|
|
|
// Given how sensitive this migration is, we verbosely
|
|
|
|
// log the contents of all involved paths before and after.
|
|
|
|
//
|
|
|
|
// TODO: Remove this logging once we have high confidence
|
|
|
|
// in our migration logic.
|
|
|
|
NSArray<NSString *> *paths = @[
|
2018-03-05 15:30:58 +01:00
|
|
|
OWSPrimaryStorage.legacyDatabaseFilePath,
|
|
|
|
OWSPrimaryStorage.legacyDatabaseFilePath_SHM,
|
|
|
|
OWSPrimaryStorage.legacyDatabaseFilePath_WAL,
|
|
|
|
OWSPrimaryStorage.sharedDataDatabaseFilePath,
|
|
|
|
OWSPrimaryStorage.sharedDataDatabaseFilePath_SHM,
|
|
|
|
OWSPrimaryStorage.sharedDataDatabaseFilePath_WAL,
|
2018-02-20 23:37:14 +01:00
|
|
|
];
|
|
|
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
|
|
for (NSString *path in paths) {
|
|
|
|
if ([fileManager fileExistsAtPath:path]) {
|
2018-08-27 18:51:32 +02:00
|
|
|
OWSLogInfo(@"storage file: %@, %@", path, [OWSFileSystem fileSizeOfPath:path]);
|
2018-02-20 23:37:14 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-28 22:30:08 +01:00
|
|
|
if ([OWSPreferences isReadyForAppExtensions]) {
|
2018-02-12 17:41:22 +01:00
|
|
|
return YES;
|
2017-11-28 19:46:26 +01:00
|
|
|
}
|
|
|
|
|
2018-02-22 19:45:19 +01:00
|
|
|
OWSBackgroundTask *_Nullable backgroundTask = [OWSBackgroundTask backgroundTaskWithLabelStr:__PRETTY_FUNCTION__];
|
2018-07-18 04:20:31 +02:00
|
|
|
SUPPRESS_DEADSTORE_WARNING(backgroundTask);
|
2018-02-22 19:45:19 +01:00
|
|
|
|
2018-03-05 15:30:58 +01:00
|
|
|
if ([NSFileManager.defaultManager fileExistsAtPath:OWSPrimaryStorage.legacyDatabaseFilePath]) {
|
2018-08-27 18:51:32 +02:00
|
|
|
OWSLogInfo(
|
|
|
|
@"Legacy Database file size: %@", [OWSFileSystem fileSizeOfPath:OWSPrimaryStorage.legacyDatabaseFilePath]);
|
|
|
|
OWSLogInfo(@"\t Legacy SHM file size: %@",
|
2018-03-05 15:30:58 +01:00
|
|
|
[OWSFileSystem fileSizeOfPath:OWSPrimaryStorage.legacyDatabaseFilePath_SHM]);
|
2018-08-27 18:51:32 +02:00
|
|
|
OWSLogInfo(@"\t Legacy WAL file size: %@",
|
2018-03-05 15:30:58 +01:00
|
|
|
[OWSFileSystem fileSizeOfPath:OWSPrimaryStorage.legacyDatabaseFilePath_WAL]);
|
2018-01-30 18:39:27 +01:00
|
|
|
}
|
2018-01-29 16:58:38 +01:00
|
|
|
|
2018-01-24 23:11:18 +01:00
|
|
|
NSError *_Nullable error = [self convertDatabaseIfNecessary];
|
2018-02-20 23:37:14 +01:00
|
|
|
|
|
|
|
if (!error) {
|
|
|
|
[NSUserDefaults migrateToSharedUserDefaults];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!error) {
|
2018-03-05 15:30:58 +01:00
|
|
|
error = [OWSPrimaryStorage migrateToSharedData];
|
2018-02-20 23:37:14 +01:00
|
|
|
}
|
|
|
|
if (!error) {
|
2018-08-01 15:39:21 +02:00
|
|
|
error = [OWSUserProfile migrateToSharedData];
|
2018-02-20 23:37:14 +01:00
|
|
|
}
|
|
|
|
if (!error) {
|
|
|
|
error = [TSAttachmentStream migrateToSharedData];
|
|
|
|
}
|
|
|
|
|
2018-02-12 17:41:22 +01:00
|
|
|
if (error) {
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSFailDebug(@"Database conversion failed: %@", error);
|
2018-02-12 17:41:22 +01:00
|
|
|
[self showLaunchFailureUI:error];
|
|
|
|
return NO;
|
|
|
|
}
|
2018-01-18 22:32:15 +01:00
|
|
|
|
2018-09-06 19:01:24 +02:00
|
|
|
OWSAssertDebug(backgroundTask);
|
2018-02-22 19:45:19 +01:00
|
|
|
backgroundTask = nil;
|
|
|
|
|
2018-02-12 17:41:22 +01:00
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)showLaunchFailureUI:(NSError *)error
|
|
|
|
{
|
|
|
|
// Disable normal functioning of app.
|
|
|
|
self.didAppLaunchFail = YES;
|
|
|
|
|
|
|
|
// We perform a subset of the [application:didFinishLaunchingWithOptions:].
|
2018-08-02 21:18:40 +02:00
|
|
|
[AppVersion sharedInstance];
|
2018-02-12 17:41:22 +01:00
|
|
|
[self startupLogging];
|
|
|
|
|
|
|
|
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
|
|
|
|
|
2018-04-23 15:30:37 +02:00
|
|
|
// Show the launch screen
|
|
|
|
self.window.rootViewController =
|
|
|
|
[[UIStoryboard storyboardWithName:@"Launch Screen" bundle:nil] instantiateInitialViewController];
|
2018-02-12 17:41:22 +01:00
|
|
|
|
|
|
|
[self.window makeKeyAndVisible];
|
|
|
|
|
2019-03-21 15:55:04 +01:00
|
|
|
UIAlertController *alert =
|
2018-02-12 17:41:22 +01:00
|
|
|
[UIAlertController alertControllerWithTitle:NSLocalizedString(@"APP_LAUNCH_FAILURE_ALERT_TITLE",
|
|
|
|
@"Title for the 'app launch failed' alert.")
|
|
|
|
message:NSLocalizedString(@"APP_LAUNCH_FAILURE_ALERT_MESSAGE",
|
|
|
|
@"Message for the 'app launch failed' alert.")
|
|
|
|
preferredStyle:UIAlertControllerStyleAlert];
|
|
|
|
|
2019-03-21 15:55:04 +01:00
|
|
|
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"SETTINGS_ADVANCED_SUBMIT_DEBUGLOG", nil)
|
|
|
|
style:UIAlertActionStyleDefault
|
|
|
|
handler:^(UIAlertAction *_Nonnull action) {
|
|
|
|
[Pastelog submitLogsWithCompletion:^{
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSFail(@"Exiting after sharing debug logs.");
|
2019-03-21 15:55:04 +01:00
|
|
|
}];
|
|
|
|
}]];
|
2018-02-12 17:41:22 +01:00
|
|
|
UIViewController *fromViewController = [[UIApplication sharedApplication] frontmostViewController];
|
2019-03-21 15:55:04 +01:00
|
|
|
[fromViewController presentAlert:alert];
|
2017-11-28 19:46:26 +01:00
|
|
|
}
|
|
|
|
|
2018-01-24 23:11:18 +01:00
|
|
|
- (nullable NSError *)convertDatabaseIfNecessary
|
|
|
|
{
|
2018-08-27 18:09:39 +02:00
|
|
|
OWSLogInfo(@"");
|
2018-02-20 23:37:14 +01:00
|
|
|
|
2018-03-05 15:30:58 +01:00
|
|
|
NSString *databaseFilePath = [OWSPrimaryStorage legacyDatabaseFilePath];
|
2018-01-30 17:54:50 +01:00
|
|
|
if (![[NSFileManager defaultManager] fileExistsAtPath:databaseFilePath]) {
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSLogVerbose(@"No legacy database file found");
|
2018-01-30 17:54:50 +01:00
|
|
|
return nil;
|
|
|
|
}
|
2018-01-24 23:11:18 +01:00
|
|
|
|
2018-02-21 22:12:21 +01:00
|
|
|
NSError *_Nullable error;
|
2018-01-31 18:15:16 +01:00
|
|
|
NSData *_Nullable databasePassword = [OWSStorage tryToLoadDatabaseLegacyPassphrase:&error];
|
2018-01-24 23:11:18 +01:00
|
|
|
if (!databasePassword || error) {
|
|
|
|
return (error
|
|
|
|
?: OWSErrorWithCodeDescription(
|
|
|
|
OWSErrorCodeDatabaseConversionFatalError, @"Failed to load database password"));
|
|
|
|
}
|
|
|
|
|
2018-02-01 02:13:42 +01:00
|
|
|
YapRecordDatabaseSaltBlock recordSaltBlock = ^(NSData *saltData) {
|
2018-08-27 18:51:32 +02:00
|
|
|
OWSLogVerbose(@"saltData: %@", saltData.hexadecimalString);
|
2018-01-31 18:15:16 +01:00
|
|
|
|
|
|
|
// Derive and store the raw cipher key spec, to avoid the ongoing tax of future KDF
|
2018-02-01 02:13:42 +01:00
|
|
|
NSData *_Nullable keySpecData =
|
2018-01-31 18:15:16 +01:00
|
|
|
[YapDatabaseCryptoUtils deriveDatabaseKeySpecForPassword:databasePassword saltData:saltData];
|
2018-02-01 02:13:42 +01:00
|
|
|
|
|
|
|
if (!keySpecData) {
|
2018-08-27 18:51:32 +02:00
|
|
|
OWSLogError(@"Failed to derive key spec.");
|
2018-02-01 02:13:42 +01:00
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
2018-01-31 18:15:16 +01:00
|
|
|
[OWSStorage storeDatabaseCipherKeySpec:keySpecData];
|
2018-02-01 02:13:42 +01:00
|
|
|
|
|
|
|
return YES;
|
2018-01-24 23:11:18 +01:00
|
|
|
};
|
|
|
|
|
2019-01-11 23:20:32 +01:00
|
|
|
YapDatabaseOptions *dbOptions = [OWSStorage defaultDatabaseOptions];
|
2018-02-21 22:12:21 +01:00
|
|
|
error = [YapDatabaseCryptoUtils convertDatabaseIfNecessary:databaseFilePath
|
|
|
|
databasePassword:databasePassword
|
2019-01-11 23:20:32 +01:00
|
|
|
options:dbOptions
|
2018-02-21 22:12:21 +01:00
|
|
|
recordSaltBlock:recordSaltBlock];
|
|
|
|
if (!error) {
|
|
|
|
[OWSStorage removeLegacyPassphrase];
|
|
|
|
}
|
|
|
|
|
|
|
|
return error;
|
2018-01-24 23:11:18 +01:00
|
|
|
}
|
|
|
|
|
2017-09-14 21:24:31 +02:00
|
|
|
- (void)startupLogging
|
|
|
|
{
|
2018-08-27 18:00:28 +02:00
|
|
|
OWSLogInfo(@"iOS Version: %@", [UIDevice currentDevice].systemVersion);
|
2017-09-14 21:24:31 +02:00
|
|
|
|
|
|
|
NSString *localeIdentifier = [NSLocale.currentLocale objectForKey:NSLocaleIdentifier];
|
|
|
|
if (localeIdentifier.length > 0) {
|
2018-08-27 18:00:28 +02:00
|
|
|
OWSLogInfo(@"Locale Identifier: %@", localeIdentifier);
|
2017-09-14 21:24:31 +02:00
|
|
|
}
|
|
|
|
NSString *countryCode = [NSLocale.currentLocale objectForKey:NSLocaleCountryCode];
|
|
|
|
if (countryCode.length > 0) {
|
2018-08-27 18:00:28 +02:00
|
|
|
OWSLogInfo(@"Country Code: %@", countryCode);
|
2017-09-14 21:24:31 +02:00
|
|
|
}
|
|
|
|
NSString *languageCode = [NSLocale.currentLocale objectForKey:NSLocaleLanguageCode];
|
|
|
|
if (languageCode.length > 0) {
|
2018-08-27 18:00:28 +02:00
|
|
|
OWSLogInfo(@"Language Code: %@", languageCode);
|
2017-09-14 21:24:31 +02:00
|
|
|
}
|
2018-03-02 15:04:55 +01:00
|
|
|
|
2018-10-25 16:18:09 +02:00
|
|
|
struct utsname systemInfo;
|
|
|
|
uname(&systemInfo);
|
|
|
|
|
|
|
|
OWSLogInfo(@"Device Model: %@ (%@)",
|
|
|
|
UIDevice.currentDevice.model,
|
|
|
|
[NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding]);
|
2018-03-02 15:04:55 +01:00
|
|
|
|
2018-10-25 22:08:02 +02:00
|
|
|
NSDictionary<NSString *, NSString *> *buildDetails =
|
|
|
|
[[NSBundle mainBundle] objectForInfoDictionaryKey:@"BuildDetails"];
|
|
|
|
OWSLogInfo(@"WebRTC Commit: %@", buildDetails[@"WebRTCCommit"]);
|
|
|
|
OWSLogInfo(@"Build XCode Version: %@", buildDetails[@"XCodeVersion"]);
|
|
|
|
OWSLogInfo(@"Build OS X Version: %@", buildDetails[@"OSXVersion"]);
|
|
|
|
OWSLogInfo(@"Build Cocoapods Version: %@", buildDetails[@"CocoapodsVersion"]);
|
|
|
|
OWSLogInfo(@"Build Carthage Version: %@", buildDetails[@"CarthageVersion"]);
|
|
|
|
OWSLogInfo(@"Build Date/Time: %@", buildDetails[@"DateTime"]);
|
2017-09-14 21:24:31 +02:00
|
|
|
}
|
|
|
|
|
2016-09-14 18:19:05 +02:00
|
|
|
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
|
|
|
|
{
|
2018-01-29 17:25:23 +01:00
|
|
|
OWSAssertIsOnMainThread();
|
|
|
|
|
2018-02-12 17:41:22 +01:00
|
|
|
if (self.didAppLaunchFail) {
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSFailDebug(@"App launch failed");
|
2018-02-12 17:41:22 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSLogInfo(@"Registering for push notifications with token: %@.", deviceToken);
|
2020-04-14 08:32:10 +02:00
|
|
|
BOOL isUsingFullAPNs = [NSUserDefaults.standardUserDefaults boolForKey:@"isUsingFullAPNs"];
|
2020-03-27 05:10:34 +01:00
|
|
|
if (isUsingFullAPNs) {
|
2020-04-16 05:58:43 +02:00
|
|
|
__unused AnyPromise *promise = [LKPushNotificationManager registerWithToken:deviceToken hexEncodedPublicKey:self.tsAccountManager.localNumber];
|
|
|
|
} else {
|
|
|
|
__unused AnyPromise *promise = [LKPushNotificationManager registerWithToken:deviceToken];
|
2020-03-27 05:10:34 +01:00
|
|
|
}
|
2014-05-06 19:41:08 +02:00
|
|
|
}
|
2014-08-01 07:53:58 +02:00
|
|
|
|
2016-09-14 18:19:05 +02:00
|
|
|
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
|
|
|
|
{
|
2018-01-29 17:25:23 +01:00
|
|
|
OWSAssertIsOnMainThread();
|
|
|
|
|
2018-02-12 17:41:22 +01:00
|
|
|
if (self.didAppLaunchFail) {
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSFailDebug(@"App launch failed");
|
2018-02-12 17:41:22 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSLogError(@"Failed to register push token with error: %@.", error);
|
2015-01-18 10:28:11 +01:00
|
|
|
#ifdef DEBUG
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSLogWarn(@"We're in debug mode. Faking success for remote registration with a fake push identifier.");
|
2018-10-22 18:31:28 +02:00
|
|
|
[self.pushRegistrationManager didReceiveVanillaPushToken:[[NSMutableData dataWithLength:32] copy]];
|
2015-01-18 10:28:11 +01:00
|
|
|
#else
|
2017-10-06 18:00:29 +02:00
|
|
|
OWSProdError([OWSAnalyticsEvents appDelegateErrorFailedToRegisterForRemoteNotifications]);
|
2018-10-22 18:31:28 +02:00
|
|
|
[self.pushRegistrationManager didFailToReceiveVanillaPushTokenWithError:error];
|
2015-01-18 10:28:11 +01:00
|
|
|
#endif
|
2014-09-15 01:32:19 +02:00
|
|
|
}
|
|
|
|
|
2015-12-22 12:45:09 +01:00
|
|
|
- (void)application:(UIApplication *)application
|
2017-10-06 18:00:29 +02:00
|
|
|
didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
|
|
|
|
{
|
2018-01-29 17:25:23 +01:00
|
|
|
OWSAssertIsOnMainThread();
|
|
|
|
|
2018-02-12 17:41:22 +01:00
|
|
|
if (self.didAppLaunchFail) {
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSFailDebug(@"App launch failed");
|
2018-02-12 17:41:22 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSLogInfo(@"Registered legacy notification settings.");
|
2019-01-18 18:54:09 +01:00
|
|
|
[self.notificationPresenter didRegisterLegacyNotificationSettings];
|
2014-05-06 19:41:08 +02:00
|
|
|
}
|
|
|
|
|
2015-12-22 12:45:09 +01:00
|
|
|
- (BOOL)application:(UIApplication *)application
|
2017-12-07 20:52:38 +01:00
|
|
|
openURL:(NSURL *)url
|
|
|
|
sourceApplication:(NSString *)sourceApplication
|
|
|
|
annotation:(id)annotation
|
|
|
|
{
|
2018-01-29 17:25:23 +01:00
|
|
|
OWSAssertIsOnMainThread();
|
|
|
|
|
2018-02-12 17:41:22 +01:00
|
|
|
if (self.didAppLaunchFail) {
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSFailDebug(@"App launch failed");
|
2018-02-12 17:41:22 +01:00
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
2018-01-29 17:25:23 +01:00
|
|
|
if (!AppReadiness.isAppReady) {
|
2018-08-27 18:51:32 +02:00
|
|
|
OWSLogWarn(@"Ignoring openURL: app not ready.");
|
2018-11-02 18:51:46 +01:00
|
|
|
// We don't need to use [AppReadiness runNowOrWhenAppDidBecomeReady:];
|
2018-02-12 18:56:58 +01:00
|
|
|
// the only URLs we handle in Signal iOS at the moment are used
|
|
|
|
// for resuming the verification step of the registration flow.
|
2018-01-29 17:25:23 +01:00
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
2015-07-10 15:00:14 +02:00
|
|
|
if ([url.scheme isEqualToString:kURLSchemeSGNLKey]) {
|
2018-10-22 18:31:28 +02:00
|
|
|
if ([url.host hasPrefix:kURLHostVerifyPrefix] && ![self.tsAccountManager isRegistered]) {
|
2017-12-04 16:56:59 +01:00
|
|
|
id signupController = SignalApp.sharedApp.signUpFlowNavigationController;
|
2018-05-17 04:42:00 +02:00
|
|
|
if ([signupController isKindOfClass:[OWSNavigationController class]]) {
|
|
|
|
OWSNavigationController *navController = (OWSNavigationController *)signupController;
|
|
|
|
UIViewController *controller = [navController.childViewControllers lastObject];
|
2019-02-20 23:35:46 +01:00
|
|
|
if ([controller isKindOfClass:[OnboardingVerificationViewController class]]) {
|
|
|
|
OnboardingVerificationViewController *verificationView
|
|
|
|
= (OnboardingVerificationViewController *)controller;
|
2015-12-22 12:45:09 +01:00
|
|
|
NSString *verificationCode = [url.path substringFromIndex:1];
|
2019-02-20 23:35:46 +01:00
|
|
|
[verificationView setVerificationCodeAndTryToVerify:verificationCode];
|
2017-12-07 20:52:38 +01:00
|
|
|
return YES;
|
2015-12-22 12:45:09 +01:00
|
|
|
} else {
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSLogWarn(@"Not the verification view controller we expected. Got %@ instead.",
|
2018-08-27 18:00:28 +02:00
|
|
|
NSStringFromClass(controller.class));
|
2014-12-31 21:30:20 +01:00
|
|
|
}
|
2014-11-25 23:52:53 +01:00
|
|
|
}
|
2015-12-22 12:45:09 +01:00
|
|
|
} else {
|
2018-08-27 16:29:51 +02:00
|
|
|
OWSFailDebug(@"Application opened with an unknown URL action: %@", url.host);
|
2017-04-25 04:30:46 +02:00
|
|
|
}
|
2014-11-25 23:52:53 +01:00
|
|
|
} else {
|
2018-08-27 16:29:51 +02:00
|
|
|
OWSFailDebug(@"Application opened with an unknown URL scheme: %@", url.scheme);
|
2014-11-25 23:52:53 +01:00
|
|
|
}
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
2015-12-22 12:45:09 +01:00
|
|
|
- (void)applicationDidBecomeActive:(UIApplication *)application {
|
2018-01-29 17:25:23 +01:00
|
|
|
OWSAssertIsOnMainThread();
|
|
|
|
|
2018-02-12 17:41:22 +01:00
|
|
|
if (self.didAppLaunchFail) {
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSFailDebug(@"App launch failed");
|
2018-02-12 17:41:22 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSLogWarn(@"applicationDidBecomeActive");
|
2017-12-04 18:38:44 +01:00
|
|
|
if (CurrentAppContext().isRunningTests) {
|
2015-12-24 18:20:04 +01:00
|
|
|
return;
|
|
|
|
}
|
2017-02-10 22:24:48 +01:00
|
|
|
|
2017-06-15 23:15:56 +02:00
|
|
|
[self ensureRootViewController];
|
2017-06-15 19:43:18 +02:00
|
|
|
|
2018-11-02 18:51:46 +01:00
|
|
|
[AppReadiness runNowOrWhenAppDidBecomeReady:^{
|
2018-01-26 21:53:26 +01:00
|
|
|
[self handleActivation];
|
|
|
|
}];
|
|
|
|
|
2018-05-10 19:55:31 +02:00
|
|
|
// Clear all notifications whenever we become active.
|
|
|
|
// When opening the app from a notification,
|
|
|
|
// AppDelegate.didReceiveLocalNotification will always
|
|
|
|
// be called _before_ we become active.
|
2018-05-11 21:45:38 +02:00
|
|
|
[self clearAllNotificationsAndRestoreBadgeCount];
|
2018-05-10 19:55:31 +02:00
|
|
|
|
2019-03-26 22:45:12 +01:00
|
|
|
// On every activation, clear old temp directories.
|
|
|
|
ClearOldTemporaryDirectories();
|
|
|
|
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSLogInfo(@"applicationDidBecomeActive completed");
|
2018-01-26 21:53:26 +01:00
|
|
|
}
|
|
|
|
|
2018-03-05 21:13:19 +01:00
|
|
|
- (void)enableBackgroundRefreshIfNecessary
|
|
|
|
{
|
2020-04-14 08:32:10 +02:00
|
|
|
BOOL isUsingFullAPNs = [NSUserDefaults.standardUserDefaults boolForKey:@"isUsingFullAPNs"];
|
2020-04-07 03:24:47 +02:00
|
|
|
if (isUsingFullAPNs) { return; }
|
2018-11-02 18:51:46 +01:00
|
|
|
[AppReadiness runNowOrWhenAppDidBecomeReady:^{
|
2019-05-10 04:04:39 +02:00
|
|
|
[UIApplication.sharedApplication setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
|
2019-05-08 03:30:02 +02:00
|
|
|
// Loki: Original code
|
|
|
|
// ========
|
|
|
|
// if (OWS2FAManager.sharedManager.is2FAEnabled && [self.tsAccountManager isRegisteredAndReady]) {
|
|
|
|
// // Ping server once a day to keep-alive 2FA clients.
|
|
|
|
// const NSTimeInterval kBackgroundRefreshInterval = 24 * 60 * 60;
|
|
|
|
// [[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:kBackgroundRefreshInterval];
|
|
|
|
// } else {
|
|
|
|
// [[UIApplication sharedApplication]
|
|
|
|
// setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalNever];
|
|
|
|
// }
|
|
|
|
// ========
|
2018-03-05 21:13:19 +01:00
|
|
|
}];
|
|
|
|
}
|
|
|
|
|
2018-01-26 21:53:26 +01:00
|
|
|
- (void)handleActivation
|
|
|
|
{
|
|
|
|
OWSAssertIsOnMainThread();
|
|
|
|
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSLogWarn(@"handleActivation");
|
2018-01-26 21:53:26 +01:00
|
|
|
|
2017-02-17 18:43:43 +01:00
|
|
|
// Always check prekeys after app launches, and sometimes check on app activation.
|
|
|
|
[TSPreKeyManager checkPreKeysIfNecessary];
|
2017-06-20 18:05:06 +02:00
|
|
|
|
2017-07-05 23:54:22 +02:00
|
|
|
static dispatch_once_t onceToken;
|
|
|
|
dispatch_once(&onceToken, ^{
|
2017-08-04 15:42:15 +02:00
|
|
|
RTCInitializeSSL();
|
|
|
|
|
2018-10-22 18:31:28 +02:00
|
|
|
if ([self.tsAccountManager isRegistered]) {
|
2017-08-04 15:42:15 +02:00
|
|
|
// At this point, potentially lengthy DB locking migrations could be running.
|
|
|
|
// Avoid blocking app launch by putting all further possible DB access in async block
|
|
|
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSLogInfo(@"Running post launch block for registered user: %@.", [self.tsAccountManager localNumber]);
|
2017-11-08 19:03:51 +01:00
|
|
|
|
2017-08-04 15:42:15 +02:00
|
|
|
// Clean up any messages that expired since last launch immediately
|
|
|
|
// and continue cleaning in the background.
|
2018-10-22 18:31:28 +02:00
|
|
|
[self.disappearingMessagesJob startIfNecessary];
|
2019-05-20 03:17:58 +02:00
|
|
|
|
2019-10-03 03:30:45 +02:00
|
|
|
// Loki: Start friend request expiration job
|
2019-05-22 05:09:01 +02:00
|
|
|
[self.lokiFriendRequestExpirationJob startIfNecessary];
|
2017-09-20 17:15:46 +02:00
|
|
|
|
2018-03-05 21:13:19 +01:00
|
|
|
[self enableBackgroundRefreshIfNecessary];
|
|
|
|
|
2017-08-04 15:42:15 +02:00
|
|
|
// Mark all "attempting out" messages as "unsent", i.e. any messages that were not successfully
|
|
|
|
// sent before the app exited should be marked as failures.
|
2018-10-22 18:31:28 +02:00
|
|
|
[[[OWSFailedMessagesJob alloc] initWithPrimaryStorage:self.primaryStorage] run];
|
2018-07-11 15:58:02 +02:00
|
|
|
// Mark all "incomplete" calls as missed, e.g. any incoming or outgoing calls that were not
|
|
|
|
// connected, failed or hung up before the app existed should be marked as missed.
|
2018-10-22 18:31:28 +02:00
|
|
|
[[[OWSIncompleteCallsJob alloc] initWithPrimaryStorage:self.primaryStorage] run];
|
|
|
|
[[[OWSFailedAttachmentDownloadsJob alloc] initWithPrimaryStorage:self.primaryStorage] run];
|
2017-08-04 15:42:15 +02:00
|
|
|
});
|
|
|
|
} else {
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSLogInfo(@"Running post launch block for unregistered user.");
|
2017-08-04 15:42:15 +02:00
|
|
|
|
|
|
|
// Unregistered user should have no unread messages. e.g. if you delete your account.
|
2019-02-13 00:57:37 +01:00
|
|
|
[AppEnvironment.shared.notificationPresenter clearAllNotifications];
|
2017-08-04 15:42:15 +02:00
|
|
|
|
2018-10-22 18:31:28 +02:00
|
|
|
[self.socketManager requestSocketOpen];
|
2017-08-04 15:42:15 +02:00
|
|
|
|
|
|
|
UITapGestureRecognizer *gesture =
|
|
|
|
[[UITapGestureRecognizer alloc] initWithTarget:[Pastelog class] action:@selector(submitLogs)];
|
|
|
|
gesture.numberOfTapsRequired = 8;
|
|
|
|
[self.window addGestureRecognizer:gesture];
|
|
|
|
}
|
|
|
|
}); // end dispatchOnce for first time we become active
|
|
|
|
|
|
|
|
// Every time we become active...
|
2018-10-22 18:31:28 +02:00
|
|
|
if ([self.tsAccountManager isRegistered]) {
|
2017-07-05 23:54:22 +02:00
|
|
|
// At this point, potentially lengthy DB locking migrations could be running.
|
2017-08-04 15:42:15 +02:00
|
|
|
// Avoid blocking app launch by putting all further possible DB access in async block
|
|
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
2018-10-22 18:31:28 +02:00
|
|
|
[self.socketManager requestSocketOpen];
|
2018-08-31 19:16:31 +02:00
|
|
|
[Environment.shared.contactsManager fetchSystemContactsOnceIfAlreadyAuthorized];
|
2019-09-26 06:43:37 +02:00
|
|
|
|
2020-02-20 06:59:05 +01:00
|
|
|
NSString *userHexEncodedPublicKey = self.tsAccountManager.localNumber;
|
|
|
|
|
2019-05-23 03:49:05 +02:00
|
|
|
// Loki: Tell our friends that we are online
|
2019-06-12 06:50:36 +02:00
|
|
|
[LKP2PAPI broadcastOnlineStatus];
|
2019-09-26 06:43:37 +02:00
|
|
|
|
2020-02-21 04:40:44 +01:00
|
|
|
// Loki: Start pollers
|
2020-03-25 00:27:43 +01:00
|
|
|
[self startPollerIfNeeded];
|
2020-02-21 04:40:44 +01:00
|
|
|
[self startOpenGroupPollersIfNeeded];
|
2019-09-26 06:43:37 +02:00
|
|
|
|
|
|
|
// Loki: Get device links
|
2020-02-20 06:59:05 +01:00
|
|
|
[[LKFileServerAPI getDeviceLinksAssociatedWith:userHexEncodedPublicKey] retainUntilComplete];
|
|
|
|
|
|
|
|
// Loki: Update profile picture if needed
|
|
|
|
NSUserDefaults *userDefaults = NSUserDefaults.standardUserDefaults;
|
|
|
|
NSDate *now = [NSDate new];
|
|
|
|
NSDate *lastProfilePictureUpload = (NSDate *)[userDefaults objectForKey:@"lastProfilePictureUpload"];
|
2020-02-21 04:07:28 +01:00
|
|
|
if (lastProfilePictureUpload != nil && [now timeIntervalSinceDate:lastProfilePictureUpload] > 14 * 24 * 60 * 60) {
|
2020-02-20 06:59:05 +01:00
|
|
|
OWSProfileManager *profileManager = OWSProfileManager.sharedManager;
|
|
|
|
NSString *displayName = [profileManager profileNameForRecipientId:userHexEncodedPublicKey];
|
|
|
|
UIImage *profilePicture = [profileManager profileAvatarForRecipientId:userHexEncodedPublicKey];
|
|
|
|
[profileManager updateLocalProfileName:displayName avatarImage:profilePicture success:^{
|
2020-02-21 04:07:28 +01:00
|
|
|
// Do nothing; the user defaults flag is updated in LokiFileServerAPI
|
2020-02-20 06:59:05 +01:00
|
|
|
} failure:^(NSError *error) {
|
|
|
|
// Do nothing
|
|
|
|
} requiresSync:YES];
|
|
|
|
}
|
2019-05-08 03:42:31 +02:00
|
|
|
|
2017-10-11 16:23:24 +02:00
|
|
|
if (![UIApplication sharedApplication].isRegisteredForRemoteNotifications) {
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSLogInfo(@"Retrying remote notification registration since user hasn't registered yet.");
|
2017-10-11 16:23:24 +02:00
|
|
|
// Push tokens don't normally change while the app is launched, so checking once during launch is
|
|
|
|
// usually sufficient, but e.g. on iOS11, users who have disabled "Allow Notifications" and disabled
|
|
|
|
// "Background App Refresh" will not be able to obtain an APN token. Enabling those settings does not
|
|
|
|
// restart the app, so we check every activation for users who haven't yet registered.
|
2019-05-08 07:51:08 +02:00
|
|
|
__unused AnyPromise *promise =
|
|
|
|
[OWSSyncPushTokensJob runWithAccountManager:AppEnvironment.shared.accountManager
|
|
|
|
preferences:Environment.shared.preferences];
|
2017-10-11 16:23:24 +02:00
|
|
|
}
|
2018-03-01 20:41:45 +01:00
|
|
|
|
|
|
|
if ([OWS2FAManager sharedManager].isDueForReminder) {
|
|
|
|
if (!self.hasInitialRootViewController || self.window.rootViewController == nil) {
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSLogDebug(@"Skipping 2FA reminder since there isn't yet an initial view controller.");
|
2018-03-01 20:41:45 +01:00
|
|
|
} else {
|
|
|
|
UIViewController *rootViewController = self.window.rootViewController;
|
2018-05-17 04:42:00 +02:00
|
|
|
OWSNavigationController *reminderNavController =
|
2018-03-01 20:41:45 +01:00
|
|
|
[OWS2FAReminderViewController wrappedInNavController];
|
|
|
|
|
|
|
|
[rootViewController presentViewController:reminderNavController animated:YES completion:nil];
|
|
|
|
}
|
|
|
|
}
|
2017-08-04 15:42:15 +02:00
|
|
|
});
|
|
|
|
}
|
2017-07-06 00:12:06 +02:00
|
|
|
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSLogInfo(@"handleActivation completed");
|
2014-12-01 23:24:35 +01:00
|
|
|
}
|
|
|
|
|
2019-02-22 01:05:18 +01:00
|
|
|
- (void)applicationWillResignActive:(UIApplication *)application
|
|
|
|
{
|
2018-01-29 17:25:23 +01:00
|
|
|
OWSAssertIsOnMainThread();
|
|
|
|
|
2018-02-12 17:41:22 +01:00
|
|
|
if (self.didAppLaunchFail) {
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSFailDebug(@"App launch failed");
|
2018-02-12 17:41:22 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSLogWarn(@"applicationWillResignActive");
|
2015-12-22 12:45:09 +01:00
|
|
|
|
2019-02-13 00:57:37 +01:00
|
|
|
[self clearAllNotificationsAndRestoreBadgeCount];
|
2019-01-28 17:48:49 +01:00
|
|
|
|
2017-02-14 17:05:59 +01:00
|
|
|
[DDLog flushLog];
|
2014-09-15 01:32:19 +02:00
|
|
|
}
|
|
|
|
|
2018-05-11 21:45:38 +02:00
|
|
|
- (void)clearAllNotificationsAndRestoreBadgeCount
|
|
|
|
{
|
|
|
|
OWSAssertIsOnMainThread();
|
|
|
|
|
2018-11-02 18:51:46 +01:00
|
|
|
[AppReadiness runNowOrWhenAppDidBecomeReady:^{
|
2019-02-13 00:57:37 +01:00
|
|
|
[AppEnvironment.shared.notificationPresenter clearAllNotifications];
|
2018-05-11 21:45:38 +02:00
|
|
|
[OWSMessageUtils.sharedManager updateApplicationBadgeCount];
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
|
2015-10-31 23:13:28 +01:00
|
|
|
- (void)application:(UIApplication *)application
|
2015-12-22 12:45:09 +01:00
|
|
|
performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem
|
|
|
|
completionHandler:(void (^)(BOOL succeeded))completionHandler {
|
2018-01-29 17:25:23 +01:00
|
|
|
OWSAssertIsOnMainThread();
|
|
|
|
|
2018-02-12 17:41:22 +01:00
|
|
|
if (self.didAppLaunchFail) {
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSFailDebug(@"App launch failed");
|
2018-11-21 23:52:34 +01:00
|
|
|
completionHandler(NO);
|
|
|
|
return;
|
|
|
|
}
|
2018-02-12 17:41:22 +01:00
|
|
|
|
2018-11-02 18:51:46 +01:00
|
|
|
[AppReadiness runNowOrWhenAppDidBecomeReady:^{
|
2018-11-26 17:19:11 +01:00
|
|
|
if (![self.tsAccountManager isRegisteredAndReady]) {
|
2018-02-12 18:56:58 +01:00
|
|
|
UIAlertController *controller =
|
|
|
|
[UIAlertController alertControllerWithTitle:NSLocalizedString(@"REGISTER_CONTACTS_WELCOME", nil)
|
|
|
|
message:NSLocalizedString(@"REGISTRATION_RESTRICTED_MESSAGE", nil)
|
|
|
|
preferredStyle:UIAlertControllerStyleAlert];
|
|
|
|
|
|
|
|
[controller addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil)
|
|
|
|
style:UIAlertActionStyleDefault
|
|
|
|
handler:^(UIAlertAction *_Nonnull action){
|
|
|
|
|
|
|
|
}]];
|
|
|
|
UIViewController *fromViewController = [[UIApplication sharedApplication] frontmostViewController];
|
|
|
|
[fromViewController presentViewController:controller
|
|
|
|
animated:YES
|
|
|
|
completion:^{
|
|
|
|
completionHandler(NO);
|
|
|
|
}];
|
|
|
|
return;
|
|
|
|
}
|
2018-01-29 17:25:23 +01:00
|
|
|
|
2020-03-02 06:27:33 +01:00
|
|
|
[SignalApp.sharedApp.homeViewController createNewPrivateChat];
|
2018-02-12 18:56:58 +01:00
|
|
|
|
2018-02-13 04:41:52 +01:00
|
|
|
completionHandler(YES);
|
|
|
|
}];
|
2015-10-31 23:13:28 +01:00
|
|
|
}
|
|
|
|
|
2019-03-21 19:48:23 +01:00
|
|
|
|
2018-10-25 19:02:30 +02:00
|
|
|
#pragma mark - Orientation
|
|
|
|
|
|
|
|
- (UIInterfaceOrientationMask)application:(UIApplication *)application
|
|
|
|
supportedInterfaceOrientationsForWindow:(nullable UIWindow *)window
|
|
|
|
{
|
2020-04-15 05:40:19 +02:00
|
|
|
return UIInterfaceOrientationMaskPortrait;
|
2019-02-27 03:21:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)hasCall
|
|
|
|
{
|
|
|
|
return self.windowManager.hasCall;
|
2018-10-25 19:02:30 +02:00
|
|
|
}
|
|
|
|
|
2015-04-14 21:49:00 +02:00
|
|
|
#pragma mark Push Notifications Delegate Methods
|
|
|
|
|
|
|
|
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
|
2018-01-29 17:25:23 +01:00
|
|
|
OWSAssertIsOnMainThread();
|
|
|
|
|
2018-02-12 17:41:22 +01:00
|
|
|
if (self.didAppLaunchFail) {
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSFailDebug(@"App launch failed");
|
2018-02-12 17:41:22 +01:00
|
|
|
return;
|
|
|
|
}
|
2018-11-26 17:19:11 +01:00
|
|
|
if (!(AppReadiness.isAppReady && [self.tsAccountManager isRegisteredAndReady])) {
|
|
|
|
OWSLogInfo(@"Ignoring remote notification; app not ready.");
|
2018-11-21 23:52:34 +01:00
|
|
|
return;
|
|
|
|
}
|
2019-12-17 03:56:36 +01:00
|
|
|
|
2020-01-06 03:16:43 +01:00
|
|
|
[LKLogger print:@"[Loki] Silent push notification received; fetching messages."];
|
2020-01-22 05:32:23 +01:00
|
|
|
|
|
|
|
__block AnyPromise *fetchMessagesPromise = [AppEnvironment.shared.messageFetcherJob run].then(^{
|
|
|
|
fetchMessagesPromise = nil;
|
2019-12-17 03:56:36 +01:00
|
|
|
}).catch(^{
|
2020-01-22 05:32:23 +01:00
|
|
|
fetchMessagesPromise = nil;
|
2019-12-17 03:56:36 +01:00
|
|
|
});
|
2020-01-22 05:32:23 +01:00
|
|
|
[fetchMessagesPromise retainUntilComplete];
|
|
|
|
|
|
|
|
__block NSDictionary<NSString *, LKPublicChat *> *publicChats;
|
|
|
|
[OWSPrimaryStorage.sharedManager.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
|
|
|
publicChats = [LKDatabaseUtilities getAllPublicChats:transaction];
|
|
|
|
}];
|
|
|
|
for (LKPublicChat *publicChat in publicChats) {
|
2020-04-15 05:40:19 +02:00
|
|
|
if (![publicChat isKindOfClass:LKPublicChat.class]) { continue; }
|
2020-01-22 05:32:23 +01:00
|
|
|
LKPublicChatPoller *poller = [[LKPublicChatPoller alloc] initForPublicChat:publicChat];
|
|
|
|
[poller stop];
|
|
|
|
AnyPromise *fetchGroupMessagesPromise = [poller pollForNewMessages];
|
|
|
|
[fetchGroupMessagesPromise retainUntilComplete];
|
|
|
|
}
|
2015-04-14 21:49:00 +02:00
|
|
|
}
|
2017-01-17 23:10:57 +01:00
|
|
|
|
2015-12-22 12:45:09 +01:00
|
|
|
- (void)application:(UIApplication *)application
|
|
|
|
didReceiveRemoteNotification:(NSDictionary *)userInfo
|
|
|
|
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
|
2018-01-29 17:25:23 +01:00
|
|
|
OWSAssertIsOnMainThread();
|
|
|
|
|
2018-02-12 17:41:22 +01:00
|
|
|
if (self.didAppLaunchFail) {
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSFailDebug(@"App launch failed");
|
2018-02-12 17:41:22 +01:00
|
|
|
return;
|
|
|
|
}
|
2018-11-26 17:19:11 +01:00
|
|
|
if (!(AppReadiness.isAppReady && [self.tsAccountManager isRegisteredAndReady])) {
|
|
|
|
OWSLogInfo(@"Ignoring remote notification; app not ready.");
|
2018-11-21 23:52:34 +01:00
|
|
|
return;
|
|
|
|
}
|
2020-02-20 04:41:16 +01:00
|
|
|
|
2020-02-21 04:24:03 +01:00
|
|
|
CurrentAppContext().wasWokenUpBySilentPushNotification = true;
|
2019-12-17 03:56:36 +01:00
|
|
|
|
2020-01-06 03:16:43 +01:00
|
|
|
[LKLogger print:@"[Loki] Silent push notification received; fetching messages."];
|
2020-01-22 05:32:23 +01:00
|
|
|
|
|
|
|
NSMutableArray *promises = [NSMutableArray new];
|
|
|
|
|
|
|
|
__block AnyPromise *fetchMessagesPromise = [AppEnvironment.shared.messageFetcherJob run].then(^{
|
|
|
|
fetchMessagesPromise = nil;
|
2019-12-17 03:56:36 +01:00
|
|
|
}).catch(^{
|
2020-01-22 05:32:23 +01:00
|
|
|
fetchMessagesPromise = nil;
|
|
|
|
});
|
|
|
|
[promises addObject:fetchMessagesPromise];
|
|
|
|
[fetchMessagesPromise retainUntilComplete];
|
|
|
|
|
|
|
|
__block NSDictionary<NSString *, LKPublicChat *> *publicChats;
|
|
|
|
[OWSPrimaryStorage.sharedManager.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
|
|
|
publicChats = [LKDatabaseUtilities getAllPublicChats:transaction];
|
|
|
|
}];
|
2020-02-20 04:41:16 +01:00
|
|
|
for (LKPublicChat *publicChat in publicChats.allValues) {
|
2020-01-22 05:32:23 +01:00
|
|
|
if (![publicChat isKindOfClass:LKPublicChat.class]) { continue; } // For some reason publicChat is sometimes a base 64 encoded string...
|
|
|
|
LKPublicChatPoller *poller = [[LKPublicChatPoller alloc] initForPublicChat:publicChat];
|
|
|
|
[poller stop];
|
|
|
|
AnyPromise *fetchGroupMessagesPromise = [poller pollForNewMessages];
|
|
|
|
[promises addObject:fetchGroupMessagesPromise];
|
|
|
|
[fetchGroupMessagesPromise retainUntilComplete];
|
|
|
|
}
|
|
|
|
|
|
|
|
PMKJoin(promises).then(^(id results) {
|
|
|
|
completionHandler(UIBackgroundFetchResultNewData);
|
2020-02-21 04:24:03 +01:00
|
|
|
CurrentAppContext().wasWokenUpBySilentPushNotification = false;
|
2020-01-22 05:32:23 +01:00
|
|
|
}).catch(^(id error) {
|
2019-12-17 03:56:36 +01:00
|
|
|
completionHandler(UIBackgroundFetchResultFailed);
|
2020-02-21 04:24:03 +01:00
|
|
|
CurrentAppContext().wasWokenUpBySilentPushNotification = false;
|
2019-12-17 03:56:36 +01:00
|
|
|
});
|
2015-04-14 21:49:00 +02:00
|
|
|
}
|
|
|
|
|
2015-12-22 12:45:09 +01:00
|
|
|
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
|
2017-12-19 17:38:25 +01:00
|
|
|
OWSAssertIsOnMainThread();
|
2017-11-06 18:37:15 +01:00
|
|
|
|
2018-02-12 17:41:22 +01:00
|
|
|
if (self.didAppLaunchFail) {
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSFailDebug(@"App launch failed");
|
2018-02-12 17:41:22 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-08-27 18:09:39 +02:00
|
|
|
OWSLogInfo(@"%@", notification);
|
2018-11-02 18:51:46 +01:00
|
|
|
[AppReadiness runNowOrWhenAppDidBecomeReady:^{
|
2018-11-26 17:19:11 +01:00
|
|
|
if (![self.tsAccountManager isRegisteredAndReady]) {
|
|
|
|
OWSLogInfo(@"Ignoring action; app not ready.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-01-31 01:09:45 +01:00
|
|
|
[self.legacyNotificationActionHandler
|
|
|
|
handleNotificationResponseWithActionIdentifier:OWSLegacyNotificationActionHandler.kDefaultActionIdentifier
|
2019-01-18 18:54:09 +01:00
|
|
|
notification:notification
|
|
|
|
responseInfo:@{}
|
|
|
|
completionHandler:^{
|
|
|
|
}];
|
2018-01-29 17:25:23 +01:00
|
|
|
}];
|
2015-04-14 21:49:00 +02:00
|
|
|
}
|
|
|
|
|
2015-12-22 12:45:09 +01:00
|
|
|
- (void)application:(UIApplication *)application
|
|
|
|
handleActionWithIdentifier:(NSString *)identifier
|
|
|
|
forLocalNotification:(UILocalNotification *)notification
|
2018-07-18 04:20:31 +02:00
|
|
|
completionHandler:(void (^)())completionHandler
|
2017-09-20 17:15:46 +02:00
|
|
|
{
|
2018-01-29 17:25:23 +01:00
|
|
|
OWSAssertIsOnMainThread();
|
|
|
|
|
2018-02-12 17:41:22 +01:00
|
|
|
if (self.didAppLaunchFail) {
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSFailDebug(@"App launch failed");
|
2018-11-21 23:52:34 +01:00
|
|
|
completionHandler();
|
|
|
|
return;
|
|
|
|
}
|
2018-02-12 17:41:22 +01:00
|
|
|
|
2018-02-12 18:56:58 +01:00
|
|
|
// The docs for handleActionWithIdentifier:... state:
|
|
|
|
// "You must call [completionHandler] at the end of your method.".
|
|
|
|
// Nonetheless, it is presumably safe to call the completion handler
|
|
|
|
// later, after this method returns.
|
|
|
|
//
|
|
|
|
// https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623068-application?language=objc
|
2018-11-02 18:51:46 +01:00
|
|
|
[AppReadiness runNowOrWhenAppDidBecomeReady:^{
|
2018-11-26 17:19:11 +01:00
|
|
|
if (![self.tsAccountManager isRegisteredAndReady]) {
|
|
|
|
OWSLogInfo(@"Ignoring action; app not ready.");
|
|
|
|
completionHandler();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-01-31 01:09:45 +01:00
|
|
|
[self.legacyNotificationActionHandler handleNotificationResponseWithActionIdentifier:identifier
|
|
|
|
notification:notification
|
|
|
|
responseInfo:@{}
|
|
|
|
completionHandler:completionHandler];
|
2018-02-12 18:56:58 +01:00
|
|
|
}];
|
2015-04-14 21:49:00 +02:00
|
|
|
}
|
|
|
|
|
2015-12-22 12:45:09 +01:00
|
|
|
- (void)application:(UIApplication *)application
|
|
|
|
handleActionWithIdentifier:(NSString *)identifier
|
|
|
|
forLocalNotification:(UILocalNotification *)notification
|
|
|
|
withResponseInfo:(NSDictionary *)responseInfo
|
2018-05-25 23:17:15 +02:00
|
|
|
completionHandler:(void (^)())completionHandler
|
2017-09-20 17:15:46 +02:00
|
|
|
{
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSLogInfo(@"Handling action with identifier: %@", identifier);
|
2018-07-07 01:55:37 +02:00
|
|
|
|
2018-01-29 17:25:23 +01:00
|
|
|
OWSAssertIsOnMainThread();
|
|
|
|
|
2018-02-12 17:41:22 +01:00
|
|
|
if (self.didAppLaunchFail) {
|
2020-04-15 05:40:19 +02:00
|
|
|
OWSFailDebug(@"App launch failed");
|
2018-11-21 23:52:34 +01:00
|
|
|
completionHandler();
|
|
|
|
return;
|
|
|
|
}
|
2018-02-12 17:41:22 +01:00
|
|
|
|
2018-02-12 18:56:58 +01:00
|
|
|
// The docs for handleActionWithIdentifier:... state:
|
|
|
|
// "You must call [completionHandler] at the end of your method.".
|
|
|
|
// Nonetheless, it is presumably safe to call the completion handler
|
|
|
|
// later, after this method returns.
|
|
|
|
//
|
|
|
|
// https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623068-application?language=objc
|
2018-11-02 18:51:46 +01:00
|
|
|
[AppReadiness runNowOrWhenAppDidBecomeReady:^{
|
2018-11-26 17:19:11 +01:00
|
|
|
if (![self.tsAccountManager isRegisteredAndReady]) {
|
|
|
|
OWSLogInfo(@"Ignoring action; app not ready.");
|
|
|
|
completionHandler();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-01-31 01:09:45 +01:00
|
|
|
[self.legacyNotificationActionHandler handleNotificationResponseWithActionIdentifier:identifier
|
|
|
|
notification:notification
|
|
|
|
responseInfo:responseInfo
|
|
|
|
completionHandler:completionHandler];
|
2018-02-12 18:56:58 +01:00
|
|
|
}];
|
2015-09-01 19:22:08 +02:00
|
|
|
}
|
|
|
|
|
2018-03-05 21:13:19 +01:00
|
|
|
- (void)application:(UIApplication *)application
|
|
|
|
performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler
|
|
|
|
{
|
2019-06-17 06:53:20 +02:00
|
|
|
NSLog(@"[Loki] Performing background fetch.");
|
2018-11-02 18:51:46 +01:00
|
|
|
[AppReadiness runNowOrWhenAppDidBecomeReady:^{
|
2020-01-22 05:32:23 +01:00
|
|
|
NSMutableArray *promises = [NSMutableArray new];
|
|
|
|
|
|
|
|
__block AnyPromise *fetchMessagesPromise = [AppEnvironment.shared.messageFetcherJob run].then(^{
|
|
|
|
fetchMessagesPromise = nil;
|
2019-06-17 06:53:20 +02:00
|
|
|
}).catch(^{
|
2020-01-22 05:32:23 +01:00
|
|
|
fetchMessagesPromise = nil;
|
|
|
|
});
|
|
|
|
[promises addObject:fetchMessagesPromise];
|
|
|
|
[fetchMessagesPromise retainUntilComplete];
|
|
|
|
|
|
|
|
__block NSDictionary<NSString *, LKPublicChat *> *publicChats;
|
|
|
|
[OWSPrimaryStorage.sharedManager.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
|
|
|
publicChats = [LKDatabaseUtilities getAllPublicChats:transaction];
|
|
|
|
}];
|
|
|
|
for (LKPublicChat *publicChat in publicChats) {
|
|
|
|
if (![publicChat isKindOfClass:LKPublicChat.class]) { continue; } // For some reason publicChat is sometimes a base 64 encoded string...
|
|
|
|
LKPublicChatPoller *poller = [[LKPublicChatPoller alloc] initForPublicChat:publicChat];
|
|
|
|
[poller stop];
|
|
|
|
AnyPromise *fetchGroupMessagesPromise = [poller pollForNewMessages];
|
|
|
|
[promises addObject:fetchGroupMessagesPromise];
|
|
|
|
[fetchGroupMessagesPromise retainUntilComplete];
|
|
|
|
}
|
|
|
|
|
|
|
|
PMKJoin(promises).then(^(id results) {
|
|
|
|
completionHandler(UIBackgroundFetchResultNewData);
|
|
|
|
}).catch(^(id error) {
|
2019-06-17 06:53:20 +02:00
|
|
|
completionHandler(UIBackgroundFetchResultFailed);
|
2019-05-10 03:17:09 +02:00
|
|
|
});
|
2018-03-05 21:13:19 +01:00
|
|
|
}];
|
|
|
|
}
|
|
|
|
|
2018-01-30 17:27:44 +01:00
|
|
|
- (void)versionMigrationsDidComplete
|
|
|
|
{
|
|
|
|
OWSAssertIsOnMainThread();
|
|
|
|
|
2018-08-27 18:51:32 +02:00
|
|
|
OWSLogInfo(@"versionMigrationsDidComplete");
|
2018-01-30 17:27:44 +01:00
|
|
|
|
|
|
|
self.areVersionMigrationsComplete = YES;
|
|
|
|
|
|
|
|
[self checkIfAppIsReady];
|
|
|
|
}
|
|
|
|
|
2017-12-19 04:56:02 +01:00
|
|
|
- (void)storageIsReady
|
2017-06-15 19:43:18 +02:00
|
|
|
{
|
2018-01-26 21:53:26 +01:00
|
|
|
OWSAssertIsOnMainThread();
|
2018-08-27 18:51:32 +02:00
|
|
|
OWSLogInfo(@"storageIsReady");
|
2017-06-15 19:43:18 +02:00
|
|
|
|
2018-01-30 17:27:44 +01:00
|
|
|
[self checkIfAppIsReady];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)checkIfAppIsReady
|
|
|
|
{
|
|
|
|
OWSAssertIsOnMainThread();
|
|
|
|
|
|
|
|
// App isn't ready until storage is ready AND all version migrations are complete.
|
|
|
|
if (!self.areVersionMigrationsComplete) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (![OWSStorage isStorageReady]) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if ([AppReadiness isAppReady]) {
|
|
|
|
// Only mark the app as ready once.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-08-27 18:51:32 +02:00
|
|
|
OWSLogInfo(@"checkIfAppIsReady");
|
2018-01-30 17:27:44 +01:00
|
|
|
|
2018-02-12 16:00:20 +01:00
|
|
|
// TODO: Once "app ready" logic is moved into AppSetup, move this line there.
|
2018-10-22 18:31:28 +02:00
|
|
|
[self.profileManager ensureLocalProfileCached];
|
|
|
|
|
2018-01-29 19:43:37 +01:00
|
|
|
// Note that this does much more than set a flag;
|
|
|
|
// it will also run all deferred blocks.
|
2018-01-26 21:58:36 +01:00
|
|
|
[AppReadiness setAppIsReady];
|
2018-01-26 21:53:26 +01:00
|
|
|
|
2018-09-28 16:56:53 +02:00
|
|
|
if (CurrentAppContext().isRunningTests) {
|
|
|
|
OWSLogVerbose(@"Skipping post-launch logic in tests.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-10-22 18:31:28 +02:00
|
|
|
if ([self.tsAccountManager isRegistered]) {
|
2018-10-22 18:33:09 +02:00
|
|
|
OWSLogInfo(@"localNumber: %@", [TSAccountManager localNumber]);
|
2017-10-06 18:00:29 +02:00
|
|
|
|
2020-04-15 05:40:19 +02:00
|
|
|
// This should happen at any launch, background or foreground
|
2019-05-08 07:51:08 +02:00
|
|
|
__unused AnyPromise *pushTokenpromise =
|
|
|
|
[OWSSyncPushTokensJob runWithAccountManager:AppEnvironment.shared.accountManager
|
|
|
|
preferences:Environment.shared.preferences];
|
2017-09-14 21:30:22 +02:00
|
|
|
}
|
|
|
|
|
2017-07-06 18:52:44 +02:00
|
|
|
[DeviceSleepManager.sharedInstance removeBlockWithBlockObject:self];
|
|
|
|
|
2018-08-02 21:18:40 +02:00
|
|
|
[AppVersion.sharedInstance mainAppLaunchDidComplete];
|
2017-06-16 16:52:36 +02:00
|
|
|
|
2018-10-23 02:55:39 +02:00
|
|
|
[Environment.shared.audioSession setup];
|
2017-08-29 19:07:34 +02:00
|
|
|
|
2018-10-22 17:42:53 +02:00
|
|
|
[SSKEnvironment.shared.reachabilityManager setup];
|
2018-10-20 19:51:48 +02:00
|
|
|
|
2018-08-31 19:44:13 +02:00
|
|
|
if (!Environment.shared.preferences.hasGeneratedThumbnails) {
|
2018-10-22 18:31:28 +02:00
|
|
|
[self.primaryStorage.newDatabaseConnection
|
2018-03-19 18:00:19 +01:00
|
|
|
asyncReadWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) {
|
|
|
|
[TSAttachmentStream enumerateCollectionObjectsUsingBlock:^(id _Nonnull obj, BOOL *_Nonnull stop){
|
|
|
|
// no-op. It's sufficient to initWithCoder: each object.
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
completionBlock:^{
|
2018-08-31 19:44:13 +02:00
|
|
|
[Environment.shared.preferences setHasGeneratedThumbnails:YES];
|
2018-03-19 18:00:19 +01:00
|
|
|
}];
|
|
|
|
}
|
|
|
|
|
2018-01-29 19:54:25 +01:00
|
|
|
#ifdef DEBUG
|
|
|
|
// A bug in orphan cleanup could be disastrous so let's only
|
|
|
|
// run it in DEBUG builds for a few releases.
|
|
|
|
//
|
|
|
|
// TODO: Release to production once we have analytics.
|
|
|
|
// TODO: Orphan cleanup is somewhat expensive - not least in doing a bunch
|
|
|
|
// of disk access. We might want to only run it "once per version"
|
|
|
|
// or something like that in production.
|
2018-08-02 21:18:40 +02:00
|
|
|
[OWSOrphanDataCleaner auditOnLaunchIfNecessary];
|
2018-01-29 19:54:25 +01:00
|
|
|
#endif
|
|
|
|
|
2018-10-22 18:31:28 +02:00
|
|
|
[self.profileManager fetchLocalUsersProfile];
|
|
|
|
[self.readReceiptManager prepareCachedValues];
|
2017-12-19 03:34:22 +01:00
|
|
|
|
|
|
|
// Disable the SAE until the main app has successfully completed launch process
|
|
|
|
// at least once in the post-SAE world.
|
|
|
|
[OWSPreferences setIsReadyForAppExtensions];
|
2017-12-19 04:56:02 +01:00
|
|
|
|
|
|
|
[self ensureRootViewController];
|
2018-03-06 16:10:22 +01:00
|
|
|
|
2018-10-22 18:31:28 +02:00
|
|
|
[self.messageManager startObserving];
|
2018-09-20 18:52:43 +02:00
|
|
|
|
2018-10-22 18:31:28 +02:00
|
|
|
[self.udManager setup];
|
2018-12-13 17:40:52 +01:00
|
|
|
|
|
|
|
[self preheatDatabaseViews];
|
2018-12-19 21:26:34 +01:00
|
|
|
|
2019-01-24 16:22:15 +01:00
|
|
|
[self.primaryStorage touchDbAsync];
|
|
|
|
|
2019-01-29 22:32:30 +01:00
|
|
|
// Every time the user upgrades to a new version:
|
|
|
|
//
|
|
|
|
// * Update account attributes.
|
|
|
|
// * Sync configuration.
|
2018-12-19 21:26:34 +01:00
|
|
|
if ([self.tsAccountManager isRegistered]) {
|
|
|
|
AppVersion *appVersion = AppVersion.sharedInstance;
|
|
|
|
if (appVersion.lastAppVersion.length > 0
|
|
|
|
&& ![appVersion.lastAppVersion isEqualToString:appVersion.currentAppVersion]) {
|
|
|
|
[[self.tsAccountManager updateAccountAttributes] retainUntilComplete];
|
2019-01-29 22:32:30 +01:00
|
|
|
|
|
|
|
[SSKEnvironment.shared.syncManager sendConfigurationSyncMessage];
|
2018-12-19 21:26:34 +01:00
|
|
|
}
|
|
|
|
}
|
2018-12-13 17:40:52 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)preheatDatabaseViews
|
|
|
|
{
|
|
|
|
[self.primaryStorage.uiDatabaseConnection asyncReadWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
|
|
|
for (NSString *viewName in @[
|
|
|
|
TSThreadDatabaseViewExtensionName,
|
|
|
|
TSMessageDatabaseViewExtensionName,
|
|
|
|
TSThreadOutgoingMessageDatabaseViewExtensionName,
|
2018-12-13 18:27:38 +01:00
|
|
|
TSUnreadDatabaseViewExtensionName,
|
|
|
|
TSUnseenDatabaseViewExtensionName,
|
|
|
|
TSThreadSpecialMessagesDatabaseViewExtensionName,
|
2018-12-13 17:40:52 +01:00
|
|
|
]) {
|
|
|
|
YapDatabaseViewTransaction *databaseView = [transaction ext:viewName];
|
|
|
|
OWSAssertDebug([databaseView isKindOfClass:[YapDatabaseViewTransaction class]]);
|
|
|
|
}
|
|
|
|
}];
|
2017-06-15 19:43:18 +02:00
|
|
|
}
|
|
|
|
|
2017-09-14 21:29:59 +02:00
|
|
|
- (void)registrationStateDidChange
|
|
|
|
{
|
2017-12-19 17:38:25 +01:00
|
|
|
OWSAssertIsOnMainThread();
|
2017-09-14 21:29:59 +02:00
|
|
|
|
2018-08-27 18:00:28 +02:00
|
|
|
OWSLogInfo(@"registrationStateDidChange");
|
2017-09-14 21:29:59 +02:00
|
|
|
|
2018-03-05 21:13:19 +01:00
|
|
|
[self enableBackgroundRefreshIfNecessary];
|
|
|
|
|
2018-10-22 18:31:28 +02:00
|
|
|
if ([self.tsAccountManager isRegistered]) {
|
|
|
|
OWSLogInfo(@"localNumber: %@", [self.tsAccountManager localNumber]);
|
2017-09-14 21:29:59 +02:00
|
|
|
|
2018-10-22 18:31:28 +02:00
|
|
|
[self.primaryStorage.newDatabaseConnection
|
2017-09-14 21:29:59 +02:00
|
|
|
readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
|
2017-12-07 16:33:27 +01:00
|
|
|
[ExperienceUpgradeFinder.sharedManager markAllAsSeenWithTransaction:transaction];
|
2017-09-14 21:29:59 +02:00
|
|
|
}];
|
2020-04-15 05:40:19 +02:00
|
|
|
|
2017-09-14 21:29:59 +02:00
|
|
|
// Start running the disappearing messages job in case the newly registered user
|
|
|
|
// enables this feature
|
2018-10-22 18:31:28 +02:00
|
|
|
[self.disappearingMessagesJob startIfNecessary];
|
|
|
|
[self.profileManager ensureLocalProfileCached];
|
2017-09-14 22:01:10 +02:00
|
|
|
|
|
|
|
// For non-legacy users, read receipts are on by default.
|
2018-10-22 18:31:28 +02:00
|
|
|
[self.readReceiptManager setAreReadReceiptsEnabled:YES];
|
2019-09-26 06:43:37 +02:00
|
|
|
|
|
|
|
// Loki: Start friend request expiration job
|
|
|
|
[self.lokiFriendRequestExpirationJob startIfNecessary];
|
2019-06-11 08:22:35 +02:00
|
|
|
|
2020-02-21 04:40:44 +01:00
|
|
|
// Loki: Start pollers
|
2020-03-25 00:27:43 +01:00
|
|
|
[self startPollerIfNeeded];
|
2020-02-21 04:40:44 +01:00
|
|
|
[self startOpenGroupPollersIfNeeded];
|
2019-09-26 06:43:37 +02:00
|
|
|
|
|
|
|
// Loki: Get device links
|
2020-02-20 06:59:05 +01:00
|
|
|
[[LKFileServerAPI getDeviceLinksAssociatedWith:self.tsAccountManager.localNumber] retainUntilComplete]; // TODO: Is this even needed?
|
2017-09-14 21:29:59 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-05 21:13:19 +01:00
|
|
|
- (void)registrationLockDidChange:(NSNotification *)notification
|
|
|
|
{
|
|
|
|
[self enableBackgroundRefreshIfNecessary];
|
|
|
|
}
|
|
|
|
|
2017-06-15 23:15:56 +02:00
|
|
|
- (void)ensureRootViewController
|
2017-06-15 19:43:18 +02:00
|
|
|
{
|
2018-01-26 21:53:26 +01:00
|
|
|
OWSAssertIsOnMainThread();
|
|
|
|
|
2018-08-27 18:51:32 +02:00
|
|
|
OWSLogInfo(@"ensureRootViewController");
|
2017-06-15 19:43:18 +02:00
|
|
|
|
2018-01-30 17:34:00 +01:00
|
|
|
if (!AppReadiness.isAppReady || self.hasInitialRootViewController) {
|
2017-06-15 19:43:18 +02:00
|
|
|
return;
|
|
|
|
}
|
2017-06-15 23:15:56 +02:00
|
|
|
self.hasInitialRootViewController = YES;
|
2017-06-15 19:43:18 +02:00
|
|
|
|
2018-04-23 15:30:37 +02:00
|
|
|
NSTimeInterval startupDuration = CACurrentMediaTime() - launchStartedAt;
|
2018-08-27 18:51:32 +02:00
|
|
|
OWSLogInfo(@"Presenting app %.2f seconds after launch started.", startupDuration);
|
2017-06-15 19:43:18 +02:00
|
|
|
|
2018-11-21 23:52:34 +01:00
|
|
|
UIViewController *rootViewController;
|
2018-11-22 01:39:40 +01:00
|
|
|
BOOL navigationBarHidden = NO;
|
2018-10-22 18:31:28 +02:00
|
|
|
if ([self.tsAccountManager isRegistered]) {
|
2018-11-21 23:52:34 +01:00
|
|
|
if (self.backup.hasPendingRestoreDecision) {
|
|
|
|
rootViewController = [BackupRestoreViewController new];
|
|
|
|
} else {
|
2019-11-28 06:42:07 +01:00
|
|
|
rootViewController = [HomeVC new];
|
2018-11-21 23:52:34 +01:00
|
|
|
}
|
2017-06-15 23:15:56 +02:00
|
|
|
} else {
|
2019-02-20 16:23:11 +01:00
|
|
|
rootViewController = [[OnboardingController new] initialViewController];
|
2019-12-06 04:42:43 +01:00
|
|
|
navigationBarHidden = NO;
|
2017-06-15 19:43:18 +02:00
|
|
|
}
|
2018-11-21 23:52:34 +01:00
|
|
|
OWSAssertDebug(rootViewController);
|
|
|
|
OWSNavigationController *navigationController =
|
|
|
|
[[OWSNavigationController alloc] initWithRootViewController:rootViewController];
|
2018-11-22 01:39:40 +01:00
|
|
|
navigationController.navigationBarHidden = navigationBarHidden;
|
2018-11-21 23:52:34 +01:00
|
|
|
self.window.rootViewController = navigationController;
|
2017-07-04 19:24:25 +02:00
|
|
|
|
|
|
|
[AppUpdateNag.sharedInstance showAppUpgradeNagIfNecessary];
|
2019-01-16 21:24:19 +01:00
|
|
|
|
|
|
|
[UIViewController attemptRotationToDeviceOrientation];
|
2017-06-15 19:43:18 +02:00
|
|
|
}
|
|
|
|
|
2018-05-18 15:37:59 +02:00
|
|
|
#pragma mark - status bar touches
|
|
|
|
|
|
|
|
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
|
|
|
|
{
|
|
|
|
[super touchesBegan:touches withEvent:event];
|
|
|
|
CGPoint location = [[[event allTouches] anyObject] locationInView:[self window]];
|
|
|
|
CGRect statusBarFrame = [UIApplication sharedApplication].statusBarFrame;
|
|
|
|
if (CGRectContainsPoint(statusBarFrame, location)) {
|
2018-08-27 18:51:32 +02:00
|
|
|
OWSLogDebug(@"touched status bar");
|
2018-05-18 15:37:59 +02:00
|
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:TappedStatusBarNotification object:nil];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-18 18:54:09 +01:00
|
|
|
#pragma mark - UNUserNotificationsDelegate
|
|
|
|
|
|
|
|
// The method will be called on the delegate only if the application is in the foreground. If the method is not
|
|
|
|
// implemented or the handler is not called in a timely manner then the notification will not be presented. The
|
|
|
|
// application can choose to have the notification presented as a sound, badge, alert and/or in the notification list.
|
|
|
|
// This decision should be based on whether the information in the notification is otherwise visible to the user.
|
|
|
|
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
|
|
|
|
willPresentNotification:(UNNotification *)notification
|
|
|
|
withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
|
|
|
|
__IOS_AVAILABLE(10.0)__TVOS_AVAILABLE(10.0)__WATCHOS_AVAILABLE(3.0)__OSX_AVAILABLE(10.14)
|
|
|
|
{
|
|
|
|
OWSLogInfo(@"");
|
2020-03-25 01:50:46 +01:00
|
|
|
if (notification.request.content.userInfo[@"remote"]) {
|
2020-03-27 05:13:24 +01:00
|
|
|
OWSLogInfo(@"[Loki] Ignoring remote notifications while the app is in the foreground.");
|
2020-03-25 01:50:46 +01:00
|
|
|
return;
|
|
|
|
}
|
2019-01-18 18:54:09 +01:00
|
|
|
[AppReadiness runNowOrWhenAppDidBecomeReady:^() {
|
2019-01-30 23:27:53 +01:00
|
|
|
// We need to respect the in-app notification sound preference. This method, which is called
|
|
|
|
// for modern UNUserNotification users, could be a place to do that, but since we'd still
|
|
|
|
// need to handle this behavior for legacy UINotification users anyway, we "allow" all
|
|
|
|
// notification options here, and rely on the shared logic in NotificationPresenter to
|
|
|
|
// honor notification sound preferences for both modern and legacy users.
|
2019-01-18 18:54:09 +01:00
|
|
|
UNNotificationPresentationOptions options = UNNotificationPresentationOptionAlert
|
|
|
|
| UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionSound;
|
|
|
|
completionHandler(options);
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
|
|
|
|
// The method will be called on the delegate when the user responded to the notification by opening the application,
|
|
|
|
// dismissing the notification or choosing a UNNotificationAction. The delegate must be set before the application
|
|
|
|
// returns from application:didFinishLaunchingWithOptions:.
|
|
|
|
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
|
|
|
|
didReceiveNotificationResponse:(UNNotificationResponse *)response
|
|
|
|
withCompletionHandler:(void (^)(void))completionHandler __IOS_AVAILABLE(10.0)__WATCHOS_AVAILABLE(3.0)
|
|
|
|
__OSX_AVAILABLE(10.14)__TVOS_PROHIBITED
|
|
|
|
{
|
|
|
|
OWSLogInfo(@"");
|
|
|
|
[AppReadiness runNowOrWhenAppDidBecomeReady:^() {
|
2019-01-31 01:09:45 +01:00
|
|
|
[self.userNotificationActionHandler handleNotificationResponse:response completionHandler:completionHandler];
|
2019-01-18 18:54:09 +01:00
|
|
|
}];
|
|
|
|
}
|
|
|
|
|
|
|
|
// The method will be called on the delegate when the application is launched in response to the user's request to view
|
|
|
|
// in-app notification settings. Add UNAuthorizationOptionProvidesAppNotificationSettings as an option in
|
|
|
|
// requestAuthorizationWithOptions:completionHandler: to add a button to inline notification settings view and the
|
|
|
|
// notification settings view in Settings. The notification will be nil when opened from Settings.
|
|
|
|
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
|
|
|
|
openSettingsForNotification:(nullable UNNotification *)notification __IOS_AVAILABLE(12.0)
|
|
|
|
__OSX_AVAILABLE(10.14)__WATCHOS_PROHIBITED __TVOS_PROHIBITED
|
|
|
|
{
|
|
|
|
OWSLogInfo(@"");
|
|
|
|
}
|
|
|
|
|
2019-08-21 03:50:23 +02:00
|
|
|
#pragma mark - Loki
|
|
|
|
|
2020-03-25 00:27:43 +01:00
|
|
|
- (void)setUpPollerIfNeeded
|
2019-08-29 07:21:45 +02:00
|
|
|
{
|
2020-03-25 00:27:43 +01:00
|
|
|
if (self.lokiPoller != nil) { return; }
|
2019-08-29 07:21:45 +02:00
|
|
|
NSString *userHexEncodedPublicKey = OWSIdentityManager.sharedManager.identityKeyPair.hexEncodedPublicKey;
|
|
|
|
if (userHexEncodedPublicKey == nil) { return; }
|
2020-03-25 00:27:43 +01:00
|
|
|
self.lokiPoller = [[LKPoller alloc] initOnMessagesReceived:^(NSArray<SSKProtoEnvelope *> *messages) {
|
2019-08-29 07:21:45 +02:00
|
|
|
for (SSKProtoEnvelope *message in messages) {
|
|
|
|
NSData *data = [message serializedDataAndReturnError:nil];
|
|
|
|
if (data != nil) {
|
|
|
|
[SSKEnvironment.shared.messageReceiver handleReceivedEnvelopeData:data];
|
|
|
|
} else {
|
|
|
|
NSLog(@"[Loki] Failed to deserialize envelope.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
|
2020-03-25 00:27:43 +01:00
|
|
|
- (void)startPollerIfNeeded
|
2019-08-29 07:21:45 +02:00
|
|
|
{
|
2020-03-25 00:27:43 +01:00
|
|
|
[self setUpPollerIfNeeded];
|
|
|
|
[self.lokiPoller startIfNeeded];
|
2019-08-29 07:21:45 +02:00
|
|
|
}
|
|
|
|
|
2020-03-25 00:27:43 +01:00
|
|
|
- (void)stopPollerIfNeeded
|
2019-08-29 07:21:45 +02:00
|
|
|
{
|
2020-03-25 00:27:43 +01:00
|
|
|
[self.lokiPoller stopIfNeeded];
|
2019-08-27 02:44:00 +02:00
|
|
|
}
|
|
|
|
|
2019-10-15 01:50:06 +02:00
|
|
|
- (void)setUpDefaultPublicChatsIfNeeded
|
2019-08-27 02:44:00 +02:00
|
|
|
{
|
2019-10-15 01:50:06 +02:00
|
|
|
for (LKPublicChat *chat in LKPublicChatAPI.defaultChats) {
|
|
|
|
NSString *userDefaultsKey = [@"isGroupChatSetUp." stringByAppendingString:chat.id]; // Should ideally be isPublicChatSetUp
|
2019-10-09 03:40:39 +02:00
|
|
|
BOOL isChatSetUp = [NSUserDefaults.standardUserDefaults boolForKey:userDefaultsKey];
|
|
|
|
if (!isChatSetUp || !chat.isDeletable) {
|
|
|
|
[LKPublicChatManager.shared addChatWithServer:chat.server channel:chat.channel name:chat.displayName];
|
|
|
|
[OWSPrimaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
2020-01-28 05:08:42 +01:00
|
|
|
TSGroupThread *thread = [TSGroupThread threadWithGroupId:[LKGroupUtilities getEncodedOpenGroupIDAsData:chat.id] transaction:transaction];
|
2019-10-09 03:40:39 +02:00
|
|
|
if (thread != nil) { [OWSProfileManager.sharedManager addThreadToProfileWhitelist:thread]; }
|
|
|
|
}];
|
|
|
|
[NSUserDefaults.standardUserDefaults setBool:YES forKey:userDefaultsKey];
|
|
|
|
}
|
2019-08-27 08:48:53 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-21 04:40:44 +01:00
|
|
|
- (void)startOpenGroupPollersIfNeeded
|
|
|
|
{
|
|
|
|
[LKPublicChatManager.shared startPollersIfNeeded];
|
|
|
|
[SSKEnvironment.shared.attachmentDownloads continueDownloadIfPossible];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)stopOpenGroupPollersIfNeeded
|
|
|
|
{
|
|
|
|
[LKPublicChatManager.shared stopPollers];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (LKRSSFeed *)lokiNewsFeed
|
|
|
|
{
|
|
|
|
return [[LKRSSFeed alloc] initWithId:@"loki.network.feed" server:@"https://loki.network/feed/" displayName:@"Loki News" isDeletable:true];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (LKRSSFeed *)lokiMessengerUpdatesFeed
|
|
|
|
{
|
|
|
|
return [[LKRSSFeed alloc] initWithId:@"loki.network.messenger-updates.feed" server:@"https://loki.network/category/messenger-updates/feed/" displayName:@"Session Updates" isDeletable:false];
|
|
|
|
}
|
|
|
|
|
2019-08-27 08:48:53 +02:00
|
|
|
- (void)createRSSFeedsIfNeeded
|
|
|
|
{
|
2020-02-14 01:03:25 +01:00
|
|
|
NSArray *feeds = @[ /*self.lokiNewsFeed,*/ self.lokiMessengerUpdatesFeed ];
|
2019-08-27 08:48:53 +02:00
|
|
|
NSString *userHexEncodedPublicKey = OWSIdentityManager.sharedManager.identityKeyPair.hexEncodedPublicKey;
|
|
|
|
for (LKRSSFeed *feed in feeds) {
|
|
|
|
NSString *userDefaultsKey = [@"isRSSFeedSetUp." stringByAppendingString:feed.id];
|
|
|
|
BOOL isFeedSetUp = [NSUserDefaults.standardUserDefaults boolForKey:userDefaultsKey];
|
|
|
|
if (!isFeedSetUp || !feed.isDeletable) {
|
2020-01-28 05:08:42 +01:00
|
|
|
TSGroupModel *group = [[TSGroupModel alloc] initWithTitle:feed.displayName memberIds:@[ userHexEncodedPublicKey, feed.server ] image:nil groupId:[LKGroupUtilities getEncodedRSSFeedIDAsData:feed.id] groupType:rssFeed adminIds:@[ userHexEncodedPublicKey, feed.server ]];
|
2019-08-27 06:56:33 +02:00
|
|
|
__block TSGroupThread *thread;
|
|
|
|
[OWSPrimaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
|
|
|
thread = [TSGroupThread getOrCreateThreadWithGroupModel:group transaction:transaction];
|
|
|
|
}];
|
|
|
|
[OWSProfileManager.sharedManager addThreadToProfileWhitelist:thread];
|
|
|
|
[NSUserDefaults.standardUserDefaults setBool:YES forKey:userDefaultsKey];
|
|
|
|
}
|
2019-08-27 02:44:00 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-27 08:48:53 +02:00
|
|
|
- (void)createRSSFeedPollersIfNeeded
|
|
|
|
{
|
2019-09-12 02:06:42 +02:00
|
|
|
// Only create the RSS feed pollers if their threads aren't deleted
|
2019-09-11 02:39:32 +02:00
|
|
|
__block TSGroupThread *lokiNewsFeedThread;
|
2019-09-12 02:06:42 +02:00
|
|
|
[OWSPrimaryStorage.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
2020-01-28 05:08:42 +01:00
|
|
|
lokiNewsFeedThread = [TSGroupThread threadWithGroupId:[LKGroupUtilities getEncodedRSSFeedIDAsData:self.lokiNewsFeed.id] transaction:transaction];
|
2019-09-11 02:39:32 +02:00
|
|
|
}];
|
|
|
|
if (lokiNewsFeedThread != nil && self.lokiNewsFeedPoller == nil) {
|
|
|
|
self.lokiNewsFeedPoller = [[LKRSSFeedPoller alloc] initForFeed:self.lokiNewsFeed];
|
|
|
|
}
|
2020-02-04 03:03:09 +01:00
|
|
|
// The user can't delete the Session Updates RSS feed
|
2019-09-12 02:06:42 +02:00
|
|
|
if (self.lokiMessengerUpdatesFeedPoller == nil) {
|
|
|
|
self.lokiMessengerUpdatesFeedPoller = [[LKRSSFeedPoller alloc] initForFeed:self.lokiMessengerUpdatesFeed];
|
|
|
|
}
|
2019-08-21 03:50:23 +02:00
|
|
|
}
|
|
|
|
|
2019-08-27 08:48:53 +02:00
|
|
|
- (void)startRSSFeedPollersIfNeeded
|
|
|
|
{
|
|
|
|
[self createRSSFeedPollersIfNeeded];
|
2019-09-11 02:39:32 +02:00
|
|
|
if (self.lokiNewsFeedPoller != nil) { [self.lokiNewsFeedPoller startIfNeeded]; }
|
|
|
|
if (self.lokiMessengerUpdatesFeedPoller != nil) { [self.lokiMessengerUpdatesFeedPoller startIfNeeded]; }
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)handleThreadDeleted:(NSNotification *)notification {
|
|
|
|
NSDictionary *userInfo = notification.userInfo;
|
2019-09-12 02:06:42 +02:00
|
|
|
NSString *threadID = (NSString *)userInfo[@"threadId"];
|
|
|
|
if (threadID == nil) { return; }
|
2020-01-28 05:08:42 +01:00
|
|
|
if ([threadID isEqualToString:[TSGroupThread threadIdFromGroupId:[LKGroupUtilities getEncodedRSSFeedIDAsData:self.lokiNewsFeed.id]]] && self.lokiNewsFeedPoller != nil) {
|
2019-09-11 02:39:32 +02:00
|
|
|
[self.lokiNewsFeedPoller stop];
|
|
|
|
self.lokiNewsFeedPoller = nil;
|
|
|
|
}
|
2019-08-21 03:50:23 +02:00
|
|
|
}
|
|
|
|
|
2019-11-20 06:27:34 +01:00
|
|
|
- (void)handleDataNukeRequested:(NSNotification *)notification {
|
|
|
|
[ThreadUtil deleteAllContent];
|
2019-11-21 05:40:30 +01:00
|
|
|
[SSKEnvironment.shared.messageSenderJobQueue clearAllJobs];
|
2019-11-20 06:27:34 +01:00
|
|
|
[SSKEnvironment.shared.identityManager clearIdentityKey];
|
|
|
|
[LKAPI clearRandomSnodePool];
|
2020-03-25 00:27:43 +01:00
|
|
|
[self stopPollerIfNeeded];
|
2020-02-21 04:40:44 +01:00
|
|
|
[self stopOpenGroupPollersIfNeeded];
|
2019-11-21 00:56:27 +01:00
|
|
|
[self.lokiNewsFeedPoller stop];
|
|
|
|
[self.lokiMessengerUpdatesFeedPoller stop];
|
|
|
|
[LKPublicChatManager.shared stopPollers];
|
2019-12-03 00:28:09 +01:00
|
|
|
bool wasUnlinked = [NSUserDefaults.standardUserDefaults boolForKey:@"wasUnlinked"];
|
|
|
|
[SignalApp resetAppData:^{
|
|
|
|
// Resetting the data clears the old user defaults. We need to restore the unlink default.
|
|
|
|
[NSUserDefaults.standardUserDefaults setBool:wasUnlinked forKey:@"wasUnlinked"];
|
|
|
|
}];
|
2019-11-20 06:27:34 +01:00
|
|
|
}
|
|
|
|
|
2014-05-06 19:41:08 +02:00
|
|
|
@end
|