diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index d340779b7..22a328f57 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -57,6 +57,7 @@ 34386A54207D271D009F5D9C /* NeverClearView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34386A53207D271C009F5D9C /* NeverClearView.swift */; }; 343A65951FC47D5E000477A1 /* DebugUISyncMessages.m in Sources */ = {isa = PBXBuildFile; fileRef = 343A65941FC47D5E000477A1 /* DebugUISyncMessages.m */; }; 343A65981FC4CFE7000477A1 /* ConversationScrollButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 343A65961FC4CFE6000477A1 /* ConversationScrollButton.m */; }; + 3441FD9F21A3604F00BB9542 /* BackupRestoreViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3441FD9E21A3604F00BB9542 /* BackupRestoreViewController.swift */; }; 34480B361FD0929200BC14EF /* ShareAppExtensionContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 34480B351FD0929200BC14EF /* ShareAppExtensionContext.m */; }; 34480B491FD0A60200BC14EF /* OWSMath.h in Headers */ = {isa = PBXBuildFile; fileRef = 34480B481FD0A60200BC14EF /* OWSMath.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34480B551FD0A7A400BC14EF /* DebugLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 34480B4D1FD0A7A300BC14EF /* DebugLogger.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -695,6 +696,7 @@ 343A65971FC4CFE7000477A1 /* ConversationScrollButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConversationScrollButton.h; sourceTree = ""; }; 343D3D991E9283F100165CA4 /* BlockListUIUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlockListUIUtils.h; sourceTree = ""; }; 343D3D9A1E9283F100165CA4 /* BlockListUIUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BlockListUIUtils.m; sourceTree = ""; }; + 3441FD9E21A3604F00BB9542 /* BackupRestoreViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BackupRestoreViewController.swift; sourceTree = ""; }; 34480B341FD0929200BC14EF /* ShareAppExtensionContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShareAppExtensionContext.h; sourceTree = ""; }; 34480B351FD0929200BC14EF /* ShareAppExtensionContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ShareAppExtensionContext.m; sourceTree = ""; }; 34480B371FD092A900BC14EF /* SignalShareExtension-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SignalShareExtension-Bridging-Header.h"; sourceTree = ""; }; @@ -1422,6 +1424,7 @@ 340FC875204DAC8C007AEB0F /* Registration */ = { isa = PBXGroup; children = ( + 3441FD9E21A3604F00BB9542 /* BackupRestoreViewController.swift */, 340FC879204DAC8C007AEB0F /* CodeVerificationViewController.h */, 340FC877204DAC8C007AEB0F /* CodeVerificationViewController.m */, 340FC878204DAC8C007AEB0F /* RegistrationViewController.h */, @@ -3496,6 +3499,7 @@ 45D308AD2049A439000189E4 /* PinEntryView.m in Sources */, 340FC8B1204DAC8D007AEB0F /* BlockListViewController.m in Sources */, 45B5360E206DD8BB00D61655 /* UIResponder+OWS.swift in Sources */, + 3441FD9F21A3604F00BB9542 /* BackupRestoreViewController.swift in Sources */, 45F659821E1BE77000444429 /* NonCallKitCallUIAdaptee.swift in Sources */, 45AE48511E0732D6004D96C2 /* TurnServerInfo.swift in Sources */, 34B3F8771E8DF1700035BE1A /* ContactsPicker.swift in Sources */, diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index eb2176fc8..268e80fcd 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -142,6 +142,11 @@ static NSTimeInterval launchStartedAt; return Environment.shared.windowManager; } +- (OWSBackup *)backup +{ + return AppEnvironment.shared.backup; +} + #pragma mark - - (void)applicationDidEnterBackground:(UIApplication *)application { @@ -617,7 +622,7 @@ static NSTimeInterval launchStartedAt; - (void)enableBackgroundRefreshIfNecessary { [AppReadiness runNowOrWhenAppDidBecomeReady:^{ - if (OWS2FAManager.sharedManager.is2FAEnabled && [self.tsAccountManager isRegistered]) { + 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]; @@ -744,11 +749,12 @@ static NSTimeInterval launchStartedAt; if (self.didAppLaunchFail) { OWSFailDebug(@"app launch failed"); + completionHandler(NO); return; } [AppReadiness runNowOrWhenAppDidBecomeReady:^{ - if (![self.tsAccountManager isRegistered]) { + if (![self.tsAccountManager isRegisteredAndReady]) { UIAlertController *controller = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"REGISTER_CONTACTS_WELCOME", nil) message:NSLocalizedString(@"REGISTRATION_RESTRICTED_MESSAGE", nil) @@ -819,6 +825,11 @@ static NSTimeInterval launchStartedAt; } [AppReadiness runNowOrWhenAppDidBecomeReady:^{ + if (![self.tsAccountManager isRegisteredAndReady]) { + OWSLogInfo(@"Ignoring user activity; app not ready."); + return; + } + NSString *_Nullable phoneNumber = handle; if ([handle hasPrefix:CallKitCallManager.kAnonymousCallHandlePrefix]) { phoneNumber = [self.primaryStorage phoneNumberForCallKitId:handle]; @@ -876,6 +887,11 @@ static NSTimeInterval launchStartedAt; } [AppReadiness runNowOrWhenAppDidBecomeReady:^{ + if (![self.tsAccountManager isRegisteredAndReady]) { + OWSLogInfo(@"Ignoring user activity; app not ready."); + return; + } + NSString *_Nullable phoneNumber = handle; if ([handle hasPrefix:CallKitCallManager.kAnonymousCallHandlePrefix]) { phoneNumber = [self.primaryStorage phoneNumberForCallKitId:handle]; @@ -950,6 +966,10 @@ static NSTimeInterval launchStartedAt; OWSFailDebug(@"app launch failed"); return; } + if (!(AppReadiness.isAppReady && [self.tsAccountManager isRegisteredAndReady])) { + OWSLogInfo(@"Ignoring remote notification; app not ready."); + return; + } // It is safe to continue even if the app isn't ready. [[PushManager sharedManager] application:application didReceiveRemoteNotification:userInfo]; @@ -964,6 +984,10 @@ static NSTimeInterval launchStartedAt; OWSFailDebug(@"app launch failed"); return; } + if (!(AppReadiness.isAppReady && [self.tsAccountManager isRegisteredAndReady])) { + OWSLogInfo(@"Ignoring remote notification; app not ready."); + return; + } // It is safe to continue even if the app isn't ready. [[PushManager sharedManager] application:application @@ -981,6 +1005,11 @@ static NSTimeInterval launchStartedAt; OWSLogInfo(@"%@", notification); [AppReadiness runNowOrWhenAppDidBecomeReady:^{ + if (![self.tsAccountManager isRegisteredAndReady]) { + OWSLogInfo(@"Ignoring action; app not ready."); + return; + } + [[PushManager sharedManager] application:application didReceiveLocalNotification:notification]; }]; } @@ -994,6 +1023,7 @@ static NSTimeInterval launchStartedAt; if (self.didAppLaunchFail) { OWSFailDebug(@"app launch failed"); + completionHandler(); return; } @@ -1004,6 +1034,12 @@ static NSTimeInterval launchStartedAt; // // https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623068-application?language=objc [AppReadiness runNowOrWhenAppDidBecomeReady:^{ + if (![self.tsAccountManager isRegisteredAndReady]) { + OWSLogInfo(@"Ignoring action; app not ready."); + completionHandler(); + return; + } + [[PushManager sharedManager] application:application handleActionWithIdentifier:identifier forLocalNotification:notification @@ -1023,6 +1059,7 @@ static NSTimeInterval launchStartedAt; if (self.didAppLaunchFail) { OWSFailDebug(@"app launch failed"); + completionHandler(); return; } @@ -1033,6 +1070,12 @@ static NSTimeInterval launchStartedAt; // // https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623068-application?language=objc [AppReadiness runNowOrWhenAppDidBecomeReady:^{ + if (![self.tsAccountManager isRegisteredAndReady]) { + OWSLogInfo(@"Ignoring action; app not ready."); + completionHandler(); + return; + } + [[PushManager sharedManager] application:application handleActionWithIdentifier:identifier forLocalNotification:notification @@ -1220,18 +1263,23 @@ static NSTimeInterval launchStartedAt; NSTimeInterval startupDuration = CACurrentMediaTime() - launchStartedAt; OWSLogInfo(@"Presenting app %.2f seconds after launch started.", startupDuration); + UIViewController *rootViewController; + BOOL navigationBarHidden = NO; if ([self.tsAccountManager isRegistered]) { - HomeViewController *homeView = [HomeViewController new]; - SignalsNavigationController *navigationController = - [[SignalsNavigationController alloc] initWithRootViewController:homeView]; - self.window.rootViewController = navigationController; + if (self.backup.hasPendingRestoreDecision) { + rootViewController = [BackupRestoreViewController new]; + } else { + rootViewController = [HomeViewController new]; + } } else { - RegistrationViewController *viewController = [RegistrationViewController new]; - OWSNavigationController *navigationController = - [[OWSNavigationController alloc] initWithRootViewController:viewController]; - navigationController.navigationBarHidden = YES; - self.window.rootViewController = navigationController; + rootViewController = [RegistrationViewController new]; + navigationBarHidden = YES; } + OWSAssertDebug(rootViewController); + OWSNavigationController *navigationController = + [[OWSNavigationController alloc] initWithRootViewController:rootViewController]; + navigationController.navigationBarHidden = navigationBarHidden; + self.window.rootViewController = navigationController; [AppUpdateNag.sharedInstance showAppUpgradeNagIfNecessary]; } diff --git a/Signal/src/Models/AccountManager.swift b/Signal/src/Models/AccountManager.swift index eda61a06c..de6714cab 100644 --- a/Signal/src/Models/AccountManager.swift +++ b/Signal/src/Models/AccountManager.swift @@ -25,7 +25,7 @@ public class AccountManager: NSObject { SwiftSingletons.register(self) } - // MARK: - Singletons + // MARK: - Dependencies private var networkManager: TSNetworkManager { return SSKEnvironment.shared.networkManager diff --git a/Signal/src/ViewControllers/AppSettings/AppSettingsViewController.m b/Signal/src/ViewControllers/AppSettings/AppSettingsViewController.m index d376dd3de..22f1e2944 100644 --- a/Signal/src/ViewControllers/AppSettings/AppSettingsViewController.m +++ b/Signal/src/ViewControllers/AppSettings/AppSettingsViewController.m @@ -248,7 +248,8 @@ - (OWSTableItem *)destructiveButtonItemWithTitle:(NSString *)title selector:(SEL)selector color:(UIColor *)color { - return [OWSTableItem + __weak AppSettingsViewController *weakSelf = self; + return [OWSTableItem itemWithCustomCellBlock:^{ UITableViewCell *cell = [OWSTableItem newCell]; cell.preservesSuperviewLayoutMargins = YES; @@ -260,7 +261,7 @@ font:[OWSFlatButton fontForHeight:kButtonHeight] titleColor:[UIColor whiteColor] backgroundColor:color - target:self + target:weakSelf selector:selector]; [cell.contentView addSubview:button]; [button autoSetDimension:ALDimensionHeight toSize:kButtonHeight]; @@ -423,6 +424,8 @@ - (void)showDeleteAccountUI:(BOOL)isRegistered { + __weak AppSettingsViewController *weakSelf = self; + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"CONFIRM_ACCOUNT_DESTRUCTION_TITLE", @"") message:NSLocalizedString(@"CONFIRM_ACCOUNT_DESTRUCTION_TEXT", @"") @@ -430,7 +433,7 @@ [alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"PROCEED_BUTTON", @"") style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) { - [self deleteAccount:isRegistered]; + [weakSelf deleteAccount:isRegistered]; }]]; [alertController addAction:[OWSAlerts cancelAction]]; diff --git a/Signal/src/ViewControllers/AppSettings/OWSBackupSettingsViewController.m b/Signal/src/ViewControllers/AppSettings/OWSBackupSettingsViewController.m index 68139aa8a..a49910188 100644 --- a/Signal/src/ViewControllers/AppSettings/OWSBackupSettingsViewController.m +++ b/Signal/src/ViewControllers/AppSettings/OWSBackupSettingsViewController.m @@ -75,9 +75,10 @@ NS_ASSUME_NONNULL_BEGIN // Enabling backup will involve entering and registering a PIN. OWSTableSection *progressSection = [OWSTableSection new]; [progressSection - addItem:[OWSTableItem labelItemWithText:NSLocalizedString(@"SETTINGS_BACKUP_STATUS", - @"Label for status row in the in the backup settings view.") - accessoryText:[self backupExportStateLocalizedDescription]]]; + addItem:[OWSTableItem + labelItemWithText:NSLocalizedString(@"SETTINGS_BACKUP_STATUS", + @"Label for status row in the in the backup settings view.") + accessoryText:NSStringForBackupExportState(OWSBackup.sharedManager.backupExportState)]]; if (OWSBackup.sharedManager.backupExportState == OWSBackupState_InProgress) { if (OWSBackup.sharedManager.backupExportDescription) { [progressSection @@ -131,20 +132,6 @@ NS_ASSUME_NONNULL_BEGIN self.contents = contents; } -- (NSString *)backupExportStateLocalizedDescription -{ - switch (OWSBackup.sharedManager.backupExportState) { - case OWSBackupState_Idle: - return NSLocalizedString(@"SETTINGS_BACKUP_STATUS_IDLE", @"Indicates that app is not backing up."); - case OWSBackupState_InProgress: - return NSLocalizedString(@"SETTINGS_BACKUP_STATUS_IN_PROGRESS", @"Indicates that app is backing up."); - case OWSBackupState_Failed: - return NSLocalizedString(@"SETTINGS_BACKUP_STATUS_FAILED", @"Indicates that the last backup failed."); - case OWSBackupState_Succeeded: - return NSLocalizedString(@"SETTINGS_BACKUP_STATUS_SUCCEEDED", @"Indicates that the last backup succeeded."); - } -} - - (void)isBackupEnabledDidChange:(UISwitch *)sender { [OWSBackup.sharedManager setIsBackupEnabled:sender.isOn]; diff --git a/Signal/src/ViewControllers/HomeView/HomeViewController.m b/Signal/src/ViewControllers/HomeView/HomeViewController.m index f0d49cc5c..e21204abd 100644 --- a/Signal/src/ViewControllers/HomeView/HomeViewController.m +++ b/Signal/src/ViewControllers/HomeView/HomeViewController.m @@ -187,8 +187,8 @@ NSString *const kArchivedConversationsReuseIdentifier = @"kArchivedConversations name:YapDatabaseModifiedExternallyNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(deregistrationStateDidChange:) - name:DeregistrationStateDidChangeNotification + selector:@selector(registrationStateDidChange:) + name:RegistrationStateDidChangeNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(outageStateDidChange:) @@ -218,7 +218,7 @@ NSString *const kArchivedConversationsReuseIdentifier = @"kArchivedConversations [self reloadTableViewData]; } -- (void)deregistrationStateDidChange:(id)notification +- (void)registrationStateDidChange:(id)notification { OWSAssertIsOnMainThread(); diff --git a/Signal/src/ViewControllers/ProfileViewController.m b/Signal/src/ViewControllers/ProfileViewController.m index 5925a1472..6b2a3cf5a 100644 --- a/Signal/src/ViewControllers/ProfileViewController.m +++ b/Signal/src/ViewControllers/ProfileViewController.m @@ -287,7 +287,8 @@ NSString *const kProfileView_LastPresentedDate = @"kProfileView_LastPresentedDat [self profileCompletedOrSkipped]; return; } - + + __weak ProfileViewController *weakSelf = self; UIAlertController *controller = [UIAlertController alertControllerWithTitle: NSLocalizedString(@"NEW_GROUP_VIEW_UNSAVED_CHANGES_TITLE", @@ -301,7 +302,7 @@ NSString *const kProfileView_LastPresentedDate = @"kProfileView_LastPresentedDat @"The label for the 'discard' button in alerts and action sheets.") style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) { - [self profileCompletedOrSkipped]; + [weakSelf profileCompletedOrSkipped]; }]]; [controller addAction:[OWSAlerts cancelAction]]; [self presentViewController:controller animated:YES completion:nil]; @@ -383,35 +384,30 @@ NSString *const kProfileView_LastPresentedDate = @"kProfileView_LastPresentedDat } // Show an activity indicator to block the UI during the profile upload. - UIAlertController *alertController = [UIAlertController - alertControllerWithTitle:NSLocalizedString(@"PROFILE_VIEW_SAVING", - @"Alert title that indicates the user's profile view is being saved.") - message:nil - preferredStyle:UIAlertControllerStyleAlert]; - - [self presentViewController:alertController - animated:YES - completion:^{ - [OWSProfileManager.sharedManager updateLocalProfileName:normalizedProfileName - avatarImage:self.avatar - success:^{ - [alertController dismissViewControllerAnimated:NO - completion:^{ - [weakSelf updateProfileCompleted]; - }]; - } - failure:^{ - [alertController - dismissViewControllerAnimated:NO - completion:^{ - [OWSAlerts showErrorAlertWithMessage: - NSLocalizedString( + [ModalActivityIndicatorViewController + presentFromViewController:self + canCancel:NO + backgroundBlock:^(ModalActivityIndicatorViewController *modalActivityIndicator) { + [OWSProfileManager.sharedManager updateLocalProfileName:normalizedProfileName + avatarImage:weakSelf.avatar + success:^{ + dispatch_async(dispatch_get_main_queue(), ^{ + [modalActivityIndicator dismissWithCompletion:^{ + [weakSelf updateProfileCompleted]; + }]; + }); + } + failure:^{ + dispatch_async(dispatch_get_main_queue(), ^{ + [modalActivityIndicator dismissWithCompletion:^{ + [OWSAlerts showErrorAlertWithMessage:NSLocalizedString( @"PROFILE_VIEW_ERROR_UPDATE_FAILED", @"Error message shown when a " @"profile update fails.")]; - }]; - }]; - }]; + }]; + }); + }]; + }]; } - (NSString *)normalizedProfileName @@ -421,17 +417,25 @@ NSString *const kProfileView_LastPresentedDate = @"kProfileView_LastPresentedDat - (void)updateProfileCompleted { + OWSLogVerbose(@""); + [self profileCompletedOrSkipped]; } - (void)profileCompletedOrSkipped { + OWSLogVerbose(@""); + // Dismiss this view. switch (self.profileViewMode) { case ProfileViewMode_AppSettings: [self.navigationController popViewControllerAnimated:YES]; break; case ProfileViewMode_Registration: + if (![TSAccountManager sharedInstance].isReregistering) { + [self checkCanImportBackup]; + return; + } [self showHomeView]; break; case ProfileViewMode_UpgradeOrNag: @@ -442,12 +446,70 @@ NSString *const kProfileView_LastPresentedDate = @"kProfileView_LastPresentedDat - (void)showHomeView { - HomeViewController *homeView = [HomeViewController new]; - SignalsNavigationController *navigationController = - [[SignalsNavigationController alloc] initWithRootViewController:homeView]; - AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate; - appDelegate.window.rootViewController = navigationController; - OWSAssertDebug([navigationController.topViewController isKindOfClass:[HomeViewController class]]); + OWSAssertIsOnMainThread(); + OWSLogVerbose(@""); + + [SignalApp.sharedApp showHomeView]; +} + +- (void)showBackupRestoreView +{ + OWSAssertIsOnMainThread(); + OWSLogVerbose(@""); + + BackupRestoreViewController *restoreView = [BackupRestoreViewController new]; + [self.navigationController setViewControllers:@[ + restoreView, + ] + animated:YES]; +} + +- (void)checkCanImportBackup +{ + OWSLogVerbose(@""); + + __weak ProfileViewController *weakSelf = self; + [OWSBackup.sharedManager + checkCanImportBackup:^(BOOL value) { + OWSLogInfo(@"has backup available for import? %d", value); + + if (value) { + [OWSBackup.sharedManager setHasPendingRestoreDecision:YES]; + + [weakSelf showBackupRestoreView]; + } else { + [weakSelf showHomeView]; + } + } + failure:^(NSError *error) { + [weakSelf showBackupCheckFailedAlert]; + }]; +} + +- (void)showBackupCheckFailedAlert +{ + OWSLogVerbose(@""); + + __weak ProfileViewController *weakSelf = self; + UIAlertController *controller = [UIAlertController + alertControllerWithTitle:NSLocalizedString(@"CHECK_FOR_BACKUP_FAILED_TITLE", + @"Title for alert shown when the app failed to check for an existing backup.") + message:NSLocalizedString(@"CHECK_FOR_BACKUP_FAILED_MESSAGE", + @"Message for alert shown when the app failed to check for an existing " + @"backup.") + preferredStyle:UIAlertControllerStyleAlert]; + [controller addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"REGISTER_FAILED_TRY_AGAIN", nil) + style:UIAlertActionStyleDefault + handler:^(UIAlertAction *action) { + [weakSelf checkCanImportBackup]; + }]]; + [controller addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"CHECK_FOR_BACKUP_DO_NOT_RESTORE", + @"The label for the 'do not restore backup' button.") + style:UIAlertActionStyleDestructive + handler:^(UIAlertAction *action) { + [weakSelf showHomeView]; + }]]; + [self presentViewController:controller animated:YES completion:nil]; } #pragma mark - UITextFieldDelegate diff --git a/Signal/src/ViewControllers/Registration/BackupRestoreViewController.swift b/Signal/src/ViewControllers/Registration/BackupRestoreViewController.swift new file mode 100644 index 000000000..bdc393a29 --- /dev/null +++ b/Signal/src/ViewControllers/Registration/BackupRestoreViewController.swift @@ -0,0 +1,165 @@ +// +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// + +import UIKit + +@objc +public class BackupRestoreViewController: OWSTableViewController { + + private var hasBegunImport = false + + private var backup: OWSBackup { + return AppEnvironment.shared.backup + } + + override public func loadView() { + super.loadView() + + navigationItem.title = NSLocalizedString("SETTINGS_BACKUP", comment: "Label for the backup view in app settings.") + + navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(didPressCancelButton)) + } + + override public func viewDidLoad() { + super.viewDidLoad() + + NotificationCenter.default.addObserver(self, + selector: #selector(backupStateDidChange), + name: NSNotification.Name(NSNotificationNameBackupStateDidChange), + object: nil) + + updateTableContents() + } + + private func updateTableContents() { + if hasBegunImport { + updateProgressContents() + } else { + updateDecisionContents() + } + } + + private func updateDecisionContents() { + let contents = OWSTableContents() + + let section = OWSTableSection() + + section.headerTitle = NSLocalizedString("BACKUP_RESTORE_DECISION_TITLE", comment: "Label for the backup restore decision section.") + + section.add(OWSTableItem.actionItem(withText: NSLocalizedString("CHECK_FOR_BACKUP_DO_NOT_RESTORE", + comment: "The label for the 'do not restore backup' button."), actionBlock: { [weak self] in + guard let strongSelf = self else { + return + } + strongSelf.cancelAndDismiss() + })) + section.add(OWSTableItem.actionItem(withText: NSLocalizedString("CHECK_FOR_BACKUP_RESTORE", + comment: "The label for the 'restore backup' button."), actionBlock: { [weak self] in + guard let strongSelf = self else { + return + } + strongSelf.startImport() + })) + + contents.addSection(section) + self.contents = contents + } + + private var progressFormatter: NumberFormatter = { + let numberFormatter = NumberFormatter() + numberFormatter.numberStyle = .percent + numberFormatter.maximumFractionDigits = 0 + numberFormatter.multiplier = 1 + return numberFormatter + }() + + private func updateProgressContents() { + let contents = OWSTableContents() + + let section = OWSTableSection() + + section.add(OWSTableItem.label(withText: NSLocalizedString("BACKUP_RESTORE_STATUS", comment: "Label for the backup restore status."), accessoryText: NSStringForBackupImportState(backup.backupImportState))) + + if backup.backupImportState == .inProgress { + if let backupImportDescription = backup.backupImportDescription { + section.add(OWSTableItem.label(withText: NSLocalizedString("BACKUP_RESTORE_DESCRIPTION", comment: "Label for the backup restore description."), accessoryText: backupImportDescription)) + } + + if let backupImportProgress = backup.backupImportProgress { + let progressInt = backupImportProgress.floatValue * 100 + if let progressString = progressFormatter.string(from: NSNumber(value: progressInt)) { + section.add(OWSTableItem.label(withText: NSLocalizedString("BACKUP_RESTORE_PROGRESS", comment: "Label for the backup restore progress."), accessoryText: progressString)) + } else { + owsFailDebug("Could not format progress: \(progressInt)") + } + } + } + + contents.addSection(section) + self.contents = contents + + // TODO: Add cancel button. + } + + // MARK: Helpers + + @objc + private func didPressCancelButton(sender: UIButton) { + Logger.info("") + + // TODO: Cancel import. + + cancelAndDismiss() + } + + @objc + private func cancelAndDismiss() { + Logger.info("") + + backup.setHasPendingRestoreDecision(false) + + dismiss(animated: true) + } + + @objc + private func startImport() { + Logger.info("") + + hasBegunImport = true + + backup.tryToImport() + } + + private func showHomeView() { + // In production, this view will never be presented in a modal. + // During testing (debug UI, etc.), it may be a modal. + let isModal = navigationController?.presentingViewController != nil + if isModal { + dismiss(animated: true, completion: { + SignalApp.shared().showHomeView() + }) + } else { + SignalApp.shared().showHomeView() + } + + NotificationCenter.default.removeObserver(self) + } + + // MARK: - Notifications + + @objc func backupStateDidChange() { + AssertIsOnMainThread() + + Logger.verbose("backup.backupImportState: \(NSStringForBackupImportState(backup.backupImportState))") + Logger.flush() + + if backup.backupImportState == .succeeded { + backup.setHasPendingRestoreDecision(false) + + showHomeView() + } else { + updateTableContents() + } + } +} diff --git a/Signal/src/ViewControllers/Registration/CodeVerificationViewController.m b/Signal/src/ViewControllers/Registration/CodeVerificationViewController.m index 35c9aa5e5..ff3810d5d 100644 --- a/Signal/src/ViewControllers/Registration/CodeVerificationViewController.m +++ b/Signal/src/ViewControllers/Registration/CodeVerificationViewController.m @@ -38,6 +38,17 @@ NS_ASSUME_NONNULL_BEGIN @implementation CodeVerificationViewController +#pragma mark - Dependencies + +- (TSAccountManager *)tsAccountManager +{ + OWSAssertDebug(SSKEnvironment.shared.tsAccountManager); + + return SSKEnvironment.shared.tsAccountManager; +} + +#pragma mark - + - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; @@ -352,7 +363,7 @@ NS_ASSUME_NONNULL_BEGIN [_requestCodeAgainSpinner startAnimating]; __weak CodeVerificationViewController *weakSelf = self; - [TSAccountManager + [self.tsAccountManager rerequestSMSWithSuccess:^{ OWSLogInfo(@"Successfully requested SMS code"); [weakSelf enableServerActions:YES]; @@ -375,7 +386,7 @@ NS_ASSUME_NONNULL_BEGIN [_requestCallSpinner startAnimating]; __weak CodeVerificationViewController *weakSelf = self; - [TSAccountManager + [self.tsAccountManager rerequestVoiceWithSuccess:^{ OWSLogInfo(@"Successfully requested voice code"); diff --git a/Signal/src/ViewControllers/Registration/RegistrationViewController.m b/Signal/src/ViewControllers/Registration/RegistrationViewController.m index fcab414aa..a10e0117d 100644 --- a/Signal/src/ViewControllers/Registration/RegistrationViewController.m +++ b/Signal/src/ViewControllers/Registration/RegistrationViewController.m @@ -43,6 +43,17 @@ NSString *const kKeychainKey_LastRegisteredPhoneNumber = @"kKeychainKey_LastRegi @implementation RegistrationViewController +#pragma mark - Dependencies + +- (TSAccountManager *)tsAccountManager +{ + OWSAssertDebug(SSKEnvironment.shared.tsAccountManager); + + return SSKEnvironment.shared.tsAccountManager; +} + +#pragma mark - + - (void)loadView { [super loadView]; @@ -287,10 +298,10 @@ NSString *const kKeychainKey_LastRegisteredPhoneNumber = @"kKeychainKey_LastRegi [self.spinnerView stopAnimating]; [self.phoneNumberTextField becomeFirstResponder]; - if ([TSAccountManager sharedInstance].isReregistering) { + if (self.tsAccountManager.isReregistering) { // If re-registering, pre-populate the country (country code, calling code, country name) // and phone number state. - NSString *_Nullable phoneNumberE164 = [TSAccountManager sharedInstance].reregisterationPhoneNumber; + NSString *_Nullable phoneNumberE164 = self.tsAccountManager.reregisterationPhoneNumber; if (!phoneNumberE164) { OWSFailDebug(@"Could not resume re-registration; missing phone number."); } else if ([self tryToApplyPhoneNumberE164:phoneNumberE164]) { @@ -441,7 +452,7 @@ NSString *const kKeychainKey_LastRegisteredPhoneNumber = @"kKeychainKey_LastRegi [self.phoneNumberTextField resignFirstResponder]; __weak RegistrationViewController *weakSelf = self; - [TSAccountManager registerWithPhoneNumber:parsedPhoneNumber + [self.tsAccountManager registerWithPhoneNumber:parsedPhoneNumber success:^{ OWSProdInfo([OWSAnalyticsEvents registrationRegisteredPhoneNumber]); @@ -472,7 +483,7 @@ NSString *const kKeychainKey_LastRegisteredPhoneNumber = @"kKeychainKey_LastRegi - (void)countryCodeRowWasTapped:(UIGestureRecognizer *)sender { - if (TSAccountManager.sharedInstance.isReregistering) { + if (self.tsAccountManager.isReregistering) { // Don't let user edit their phone number while re-registering. return; } diff --git a/Signal/src/environment/SignalApp.h b/Signal/src/environment/SignalApp.h index b25dce838..ce8d4aec9 100644 --- a/Signal/src/environment/SignalApp.h +++ b/Signal/src/environment/SignalApp.h @@ -53,6 +53,8 @@ NS_ASSUME_NONNULL_BEGIN + (void)clearAllNotifications; +- (void)showHomeView; + @end NS_ASSUME_NONNULL_END diff --git a/Signal/src/environment/SignalApp.m b/Signal/src/environment/SignalApp.m index 27159cfb0..90e86046d 100644 --- a/Signal/src/environment/SignalApp.m +++ b/Signal/src/environment/SignalApp.m @@ -3,9 +3,11 @@ // #import "SignalApp.h" +#import "AppDelegate.h" #import "ConversationViewController.h" #import "HomeViewController.h" #import "Signal-Swift.h" +#import "SignalsNavigationController.h" #import #import #import @@ -156,6 +158,16 @@ NS_ASSUME_NONNULL_BEGIN [UIApplication sharedApplication].applicationIconBadgeNumber = 0; } +- (void)showHomeView +{ + HomeViewController *homeView = [HomeViewController new]; + SignalsNavigationController *navigationController = + [[SignalsNavigationController alloc] initWithRootViewController:homeView]; + AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate; + appDelegate.window.rootViewController = navigationController; + OWSAssertDebug([navigationController.topViewController isKindOfClass:[HomeViewController class]]); +} + @end NS_ASSUME_NONNULL_END diff --git a/Signal/src/util/Backup/OWSBackup.h b/Signal/src/util/Backup/OWSBackup.h index 0f0823b0f..058e9a355 100644 --- a/Signal/src/util/Backup/OWSBackup.h +++ b/Signal/src/util/Backup/OWSBackup.h @@ -20,6 +20,9 @@ typedef NS_ENUM(NSUInteger, OWSBackupState) { OWSBackupState_Succeeded, }; +NSString *NSStringForBackupExportState(OWSBackupState state); +NSString *NSStringForBackupImportState(OWSBackupState state); + @class OWSBackupIO; @class TSAttachmentPointer; @class TSThread; @@ -45,6 +48,9 @@ typedef NS_ENUM(NSUInteger, OWSBackupState) { - (BOOL)isBackupEnabled; - (void)setIsBackupEnabled:(BOOL)value; +- (BOOL)hasPendingRestoreDecision; +- (void)setHasPendingRestoreDecision:(BOOL)value; + - (void)tryToExportBackup; - (void)cancelExportBackup; diff --git a/Signal/src/util/Backup/OWSBackup.m b/Signal/src/util/Backup/OWSBackup.m index 8e3ea7a93..9d43e6156 100644 --- a/Signal/src/util/Backup/OWSBackup.m +++ b/Signal/src/util/Backup/OWSBackup.m @@ -10,6 +10,8 @@ #import #import +NS_ASSUME_NONNULL_BEGIN + NSString *const NSNotificationNameBackupStateDidChange = @"NSNotificationNameBackupStateDidChange"; NSString *const OWSPrimaryStorage_OWSBackupCollection = @"OWSPrimaryStorage_OWSBackupCollection"; @@ -17,7 +19,36 @@ NSString *const OWSBackup_IsBackupEnabledKey = @"OWSBackup_IsBackupEnabledKey"; NSString *const OWSBackup_LastExportSuccessDateKey = @"OWSBackup_LastExportSuccessDateKey"; NSString *const OWSBackup_LastExportFailureDateKey = @"OWSBackup_LastExportFailureDateKey"; -NS_ASSUME_NONNULL_BEGIN +NSString *NSStringForBackupExportState(OWSBackupState state) +{ + switch (state) { + case OWSBackupState_Idle: + return NSLocalizedString(@"SETTINGS_BACKUP_STATUS_IDLE", @"Indicates that app is not backing up."); + case OWSBackupState_InProgress: + return NSLocalizedString(@"SETTINGS_BACKUP_STATUS_IN_PROGRESS", @"Indicates that app is backing up."); + case OWSBackupState_Failed: + return NSLocalizedString(@"SETTINGS_BACKUP_STATUS_FAILED", @"Indicates that the last backup failed."); + case OWSBackupState_Succeeded: + return NSLocalizedString(@"SETTINGS_BACKUP_STATUS_SUCCEEDED", @"Indicates that the last backup succeeded."); + } +} + +NSString *NSStringForBackupImportState(OWSBackupState state) +{ + switch (state) { + case OWSBackupState_Idle: + return NSLocalizedString(@"SETTINGS_BACKUP_IMPORT_STATUS_IDLE", @"Indicates that app is not restoring up."); + case OWSBackupState_InProgress: + return NSLocalizedString( + @"SETTINGS_BACKUP_IMPORT_STATUS_IN_PROGRESS", @"Indicates that app is restoring up."); + case OWSBackupState_Failed: + return NSLocalizedString( + @"SETTINGS_BACKUP_IMPORT_STATUS_FAILED", @"Indicates that the last backup restore failed."); + case OWSBackupState_Succeeded: + return NSLocalizedString( + @"SETTINGS_BACKUP_IMPORT_STATUS_SUCCEEDED", @"Indicates that the last backup restore succeeded."); + } +} // TODO: Observe Reachability. @interface OWSBackup () @@ -116,6 +147,13 @@ NS_ASSUME_NONNULL_BEGIN return SSKEnvironment.shared.primaryStorage; } +- (TSAccountManager *)tsAccountManager +{ + OWSAssertDebug(SSKEnvironment.shared.tsAccountManager); + + return SSKEnvironment.shared.tsAccountManager; +} + #pragma mark - Backup Export - (void)tryToExportBackup @@ -206,6 +244,16 @@ NS_ASSUME_NONNULL_BEGIN [self ensureBackupExportState]; } +- (BOOL)hasPendingRestoreDecision +{ + return [self.tsAccountManager hasPendingBackupRestoreDecision]; +} + +- (void)setHasPendingRestoreDecision:(BOOL)value +{ + [self.tsAccountManager setHasPendingBackupRestoreDecision:value]; +} + - (BOOL)canBackupExport { if (!self.isBackupEnabled) { @@ -215,7 +263,7 @@ NS_ASSUME_NONNULL_BEGIN // Don't start backups when app is in the background. return NO; } - if (![TSAccountManager isRegistered]) { + if (![self.tsAccountManager isRegisteredAndReady]) { return NO; } return YES; @@ -364,6 +412,8 @@ NS_ASSUME_NONNULL_BEGIN OWSAssertIsOnMainThread(); [self ensureBackupExportState]; + + [self postDidChangeNotification]; } #pragma mark - OWSBackupJobDelegate diff --git a/Signal/src/util/Pastelog.m b/Signal/src/util/Pastelog.m index d67fed6e3..a70559829 100644 --- a/Signal/src/util/Pastelog.m +++ b/Signal/src/util/Pastelog.m @@ -290,6 +290,13 @@ typedef void (^DebugLogUploadFailure)(DebugLogUploader *uploader, NSError *error return SSKEnvironment.shared.primaryStorage.dbReadWriteConnection; } +- (TSAccountManager *)tsAccountManager +{ + OWSAssertDebug(SSKEnvironment.shared.tsAccountManager); + + return SSKEnvironment.shared.tsAccountManager; +} + #pragma mark - + (void)submitLogs @@ -570,7 +577,7 @@ typedef void (^DebugLogUploadFailure)(DebugLogUploader *uploader, NSError *error - (void)sendToSelf:(NSURL *)url { - if (![TSAccountManager isRegistered]) { + if (![self.tsAccountManager isRegistered]) { return; } NSString *recipientId = [TSAccountManager localNumber]; @@ -594,7 +601,7 @@ typedef void (^DebugLogUploadFailure)(DebugLogUploader *uploader, NSError *error - (void)sendToMostRecentThread:(NSURL *)url { - if (![TSAccountManager isRegistered]) { + if (![self.tsAccountManager isRegistered]) { return; } diff --git a/Signal/src/util/RegistrationUtils.m b/Signal/src/util/RegistrationUtils.m index de2feea72..2789b6108 100644 --- a/Signal/src/util/RegistrationUtils.m +++ b/Signal/src/util/RegistrationUtils.m @@ -14,6 +14,17 @@ NS_ASSUME_NONNULL_BEGIN @implementation RegistrationUtils +#pragma mark - Dependencies + ++ (TSAccountManager *)tsAccountManager +{ + OWSAssertDebug(SSKEnvironment.shared.tsAccountManager); + + return SSKEnvironment.shared.tsAccountManager; +} + +#pragma mark - + + (void)showReregistrationUIFromViewController:(UIViewController *)fromViewController { UIAlertController *actionSheetController = @@ -37,7 +48,7 @@ NS_ASSUME_NONNULL_BEGIN { OWSLogInfo(@"reregisterWithSamePhoneNumber."); - if (![[TSAccountManager sharedInstance] resetForReregistration]) { + if (![self.tsAccountManager resetForReregistration]) { OWSFailDebug(@"could not reset for re-registration."); return; } @@ -48,8 +59,8 @@ NS_ASSUME_NONNULL_BEGIN presentFromViewController:fromViewController canCancel:NO backgroundBlock:^(ModalActivityIndicatorViewController *modalActivityIndicator) { - [TSAccountManager - registerWithPhoneNumber:[TSAccountManager sharedInstance].reregisterationPhoneNumber + [self.tsAccountManager + registerWithPhoneNumber:self.tsAccountManager.reregisterationPhoneNumber success:^{ OWSLogInfo(@"re-registering: send verification code succeeded."); diff --git a/Signal/translations/en.lproj/Localizable.strings b/Signal/translations/en.lproj/Localizable.strings index 7c0197027..5bae7843b 100644 --- a/Signal/translations/en.lproj/Localizable.strings +++ b/Signal/translations/en.lproj/Localizable.strings @@ -230,6 +230,18 @@ /* Indicates that the backup import data is being restored. */ "BACKUP_IMPORT_PHASE_RESTORING_FILES" = "Restoring Files"; +/* Label for the backup restore decision section. */ +"BACKUP_RESTORE_DECISION_TITLE" = "Backup Available"; + +/* Label for the backup restore description. */ +"BACKUP_RESTORE_DESCRIPTION" = "Restoring Backup"; + +/* Label for the backup restore progress. */ +"BACKUP_RESTORE_PROGRESS" = "Progress"; + +/* Label for the backup restore status. */ +"BACKUP_RESTORE_STATUS" = "Status"; + /* An explanation of the consequences of blocking a group. */ "BLOCK_GROUP_BEHAVIOR_EXPLANATION" = "You will no longer receive messages or updates from this group."; @@ -383,6 +395,18 @@ /* Title for the 'censorship circumvention country' view. */ "CENSORSHIP_CIRCUMVENTION_COUNTRY_VIEW_TITLE" = "Select Country"; +/* The label for the 'do not restore backup' button. */ +"CHECK_FOR_BACKUP_DO_NOT_RESTORE" = "Do Not Restore"; + +/* Message for alert shown when the app failed to check for an existing backup. */ +"CHECK_FOR_BACKUP_FAILED_MESSAGE" = "Could not determine whether there is a backup that can be restored."; + +/* Title for alert shown when the app failed to check for an existing backup. */ +"CHECK_FOR_BACKUP_FAILED_TITLE" = "Error"; + +/* The label for the 'restore backup' button. */ +"CHECK_FOR_BACKUP_RESTORE" = "Restore"; + /* Error indicating that the app could not determine that user's CloudKit account status */ "CLOUDKIT_STATUS_COULD_NOT_DETERMINE" = "There was an error communicating with iCloud for backups."; @@ -1511,8 +1535,8 @@ /* Label for 'Work FAX' phone numbers. */ "PHONE_NUMBER_TYPE_WORK_FAX" = "Work Fax"; -/* navbar title when viewing the default photo album, which includes all photos */ -"PHOTO_PICKER_DEFAULT_ALBUM" = "All Photos"; +/* label for system photo collections which have no name. */ +"PHOTO_PICKER_UNNAMED_COLLECTION" = "PHOTO_PICKER_UNNAMED_COLLECTION"; /* Accessibility label for button to start media playback */ "PLAY_BUTTON_ACCESSABILITY_LABEL" = "Play Media"; @@ -1604,9 +1628,6 @@ /* Button to save the profile view in the profile view. */ "PROFILE_VIEW_SAVE_BUTTON" = "Save"; -/* Alert title that indicates the user's profile view is being saved. */ -"PROFILE_VIEW_SAVING" = "Saving…"; - /* Title for the profile view. */ "PROFILE_VIEW_TITLE" = "Profile"; @@ -1940,6 +1961,18 @@ /* Label for switch in settings that controls whether or not backup is enabled. */ "SETTINGS_BACKUP_ENABLING_SWITCH" = "Backup Enabled"; +/* Indicates that the last backup restore failed. */ +"SETTINGS_BACKUP_IMPORT_STATUS_FAILED" = "Backup Restore Failed"; + +/* Indicates that app is not restoring up. */ +"SETTINGS_BACKUP_IMPORT_STATUS_IDLE" = "Backup Restore Idle"; + +/* Indicates that app is restoring up. */ +"SETTINGS_BACKUP_IMPORT_STATUS_IN_PROGRESS" = "Backup Restore In Progress"; + +/* Indicates that the last backup restore succeeded. */ +"SETTINGS_BACKUP_IMPORT_STATUS_SUCCEEDED" = "Backup Restore Succeeded"; + /* Label for phase row in the in the backup settings view. */ "SETTINGS_BACKUP_PHASE" = "Phase"; diff --git a/SignalMessaging/contacts/OWSSyncManager.m b/SignalMessaging/contacts/OWSSyncManager.m index 6d05c22cf..3dd8d2821 100644 --- a/SignalMessaging/contacts/OWSSyncManager.m +++ b/SignalMessaging/contacts/OWSSyncManager.m @@ -208,14 +208,14 @@ NSString *const kSyncManagerLastContactSyncKey = @"kTSStorageManagerOWSSyncManag return; } - if ([TSAccountManager sharedInstance].isRegistered) { + if ([TSAccountManager sharedInstance].isRegisteredAndReady) { [self sendSyncContactsMessageIfNecessary]; } } - (void)sendConfigurationSyncMessage { [AppReadiness runNowOrWhenAppDidBecomeReady:^{ - if (!TSAccountManager.isRegistered) { + if (!self.tsAccountManager.isRegisteredAndReady) { return; } @@ -226,7 +226,7 @@ NSString *const kSyncManagerLastContactSyncKey = @"kTSStorageManagerOWSSyncManag - (void)sendConfigurationSyncMessage_AppReady { DDLogInfo(@""); - if (![TSAccountManager sharedInstance].isRegistered) { + if (![TSAccountManager sharedInstance].isRegisteredAndReady) { return; } diff --git a/SignalMessaging/environment/VersionMigrations.m b/SignalMessaging/environment/VersionMigrations.m index 47f117922..acecb8177 100644 --- a/SignalMessaging/environment/VersionMigrations.m +++ b/SignalMessaging/environment/VersionMigrations.m @@ -30,7 +30,16 @@ NS_ASSUME_NONNULL_BEGIN @implementation VersionMigrations -#pragma mark Utility methods +#pragma mark - Dependencies + ++ (TSAccountManager *)tsAccountManager +{ + OWSAssertDebug(SSKEnvironment.shared.tsAccountManager); + + return SSKEnvironment.shared.tsAccountManager; +} + +#pragma mark - Utility methods + (void)performUpdateCheckWithCompletion:(VersionMigrationCompletion)completion { @@ -76,12 +85,12 @@ NS_ASSUME_NONNULL_BEGIN [CurrentAppContext().frontmostViewController presentViewController:alertController animated:YES completion:nil]; } - if ([self isVersion:previousVersion atLeast:@"2.0.0" andLessThan:@"2.1.70"] && [TSAccountManager isRegistered]) { + if ([self isVersion:previousVersion atLeast:@"2.0.0" andLessThan:@"2.1.70"] && [self.tsAccountManager isRegistered]) { [self clearVideoCache]; [self blockingAttributesUpdate]; } - if ([self isVersion:previousVersion atLeast:@"2.0.0" andLessThan:@"2.3.0"] && [TSAccountManager isRegistered]) { + if ([self isVersion:previousVersion atLeast:@"2.0.0" andLessThan:@"2.3.0"] && [self.tsAccountManager isRegistered]) { [self clearBloomFilterCache]; } diff --git a/SignalMessaging/environment/migrations/OWS103EnableVideoCalling.m b/SignalMessaging/environment/migrations/OWS103EnableVideoCalling.m index fcd19cefb..3b7451e7f 100644 --- a/SignalMessaging/environment/migrations/OWS103EnableVideoCalling.m +++ b/SignalMessaging/environment/migrations/OWS103EnableVideoCalling.m @@ -4,6 +4,7 @@ #import "OWS103EnableVideoCalling.h" #import +#import #import #import @@ -12,6 +13,17 @@ static NSString *const OWS103EnableVideoCallingMigrationId = @"103"; @implementation OWS103EnableVideoCalling +#pragma mark - Dependencies + +- (TSAccountManager *)tsAccountManager +{ + OWSAssertDebug(SSKEnvironment.shared.tsAccountManager); + + return SSKEnvironment.shared.tsAccountManager; +} + +#pragma mark - + + (NSString *)migrationId { return OWS103EnableVideoCallingMigrationId; @@ -23,7 +35,7 @@ static NSString *const OWS103EnableVideoCallingMigrationId = @"103"; OWSAssertDebug(completion); OWSLogWarn(@"running migration..."); - if ([TSAccountManager isRegistered]) { + if ([self.tsAccountManager isRegistered]) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ TSRequest *request = [OWSRequestFactory updateAttributesRequest]; [[TSNetworkManager sharedManager] makeRequest:request diff --git a/SignalMessaging/environment/migrations/OWS106EnsureProfileComplete.swift b/SignalMessaging/environment/migrations/OWS106EnsureProfileComplete.swift index 76327589e..686137426 100644 --- a/SignalMessaging/environment/migrations/OWS106EnsureProfileComplete.swift +++ b/SignalMessaging/environment/migrations/OWS106EnsureProfileComplete.swift @@ -44,6 +44,14 @@ public class OWS106EnsureProfileComplete: OWSDatabaseMigration { */ private class CompleteRegistrationFixerJob: NSObject { + // MARK: - Dependencies + + private var tsAccountManager: TSAccountManager { + return TSAccountManager.sharedInstance() + } + + // MARK: - + // Duration between retries if update fails. let kRetryInterval: TimeInterval = 5 @@ -54,7 +62,7 @@ public class OWS106EnsureProfileComplete: OWSDatabaseMigration { } func start() { - guard TSAccountManager.isRegistered() else { + guard tsAccountManager.isRegistered() else { self.completionHandler(true) return } diff --git a/SignalMessaging/profiles/OWSUserProfile.m b/SignalMessaging/profiles/OWSUserProfile.m index 0a2ff90af..3a798481d 100644 --- a/SignalMessaging/profiles/OWSUserProfile.m +++ b/SignalMessaging/profiles/OWSUserProfile.m @@ -105,6 +105,13 @@ NSString *const kLocalProfileUniqueId = @"kLocalProfileUniqueId"; return SSKEnvironment.shared.syncManager; } +- (TSAccountManager *)tsAccountManager +{ + OWSAssertDebug(SSKEnvironment.shared.tsAccountManager); + + return SSKEnvironment.shared.tsAccountManager; +} + #pragma mark - - (nullable NSString *)avatarUrlPath @@ -219,7 +226,7 @@ NSString *const kLocalProfileUniqueId = @"kLocalProfileUniqueId"; // We populate an initial (empty) profile on launch of a new install, but until // we have a registered account, syncing will fail (and there could not be any // linked device to sync to at this point anyway). - if ([TSAccountManager isRegistered] && CurrentAppContext().isMainApp) { + if ([self.tsAccountManager isRegistered] && CurrentAppContext().isMainApp) { [self.syncManager syncLocalContact]; } diff --git a/SignalServiceKit/src/Account/TSAccountManager.h b/SignalServiceKit/src/Account/TSAccountManager.h index f2c3dd821..d6205a5b0 100644 --- a/SignalServiceKit/src/Account/TSAccountManager.h +++ b/SignalServiceKit/src/Account/TSAccountManager.h @@ -9,7 +9,6 @@ NS_ASSUME_NONNULL_BEGIN extern NSString *const TSRegistrationErrorDomain; extern NSString *const TSRegistrationErrorUserInfoHTTPStatus; extern NSString *const RegistrationStateDidChangeNotification; -extern NSString *const DeregistrationStateDidChangeNotification; extern NSString *const kNSNotificationName_LocalNumberDidChange; @class AnyPromise; @@ -17,6 +16,14 @@ extern NSString *const kNSNotificationName_LocalNumberDidChange; @class TSNetworkManager; @class YapDatabaseReadWriteTransaction; +typedef NS_ENUM(NSUInteger, OWSRegistrationState) { + OWSRegistrationState_Unregistered, + OWSRegistrationState_PendingBackupRestore, + OWSRegistrationState_Registered, + OWSRegistrationState_Deregistered, + OWSRegistrationState_Reregistering, +}; + @interface TSAccountManager : NSObject // This property is exposed for testing purposes only. @@ -32,13 +39,15 @@ extern NSString *const kNSNotificationName_LocalNumberDidChange; + (instancetype)sharedInstance; +- (OWSRegistrationState)registrationState; + /** * Returns if a user is registered or not * * @return registered or not */ -+ (BOOL)isRegistered; - (BOOL)isRegistered; +- (BOOL)isRegisteredAndReady; /** * Returns current phone number for this device, which may not yet have been registered. @@ -76,14 +85,14 @@ extern NSString *const kNSNotificationName_LocalNumberDidChange; #pragma mark - Register with phone number -+ (void)registerWithPhoneNumber:(NSString *)phoneNumber +- (void)registerWithPhoneNumber:(NSString *)phoneNumber success:(void (^)(void))successBlock failure:(void (^)(NSError *error))failureBlock smsVerification:(BOOL)isSMS; -+ (void)rerequestSMSWithSuccess:(void (^)(void))successBlock failure:(void (^)(NSError *error))failureBlock; +- (void)rerequestSMSWithSuccess:(void (^)(void))successBlock failure:(void (^)(NSError *error))failureBlock; -+ (void)rerequestVoiceWithSuccess:(void (^)(void))successBlock failure:(void (^)(NSError *error))failureBlock; +- (void)rerequestVoiceWithSuccess:(void (^)(void))successBlock failure:(void (^)(NSError *error))failureBlock; - (void)verifyAccountWithCode:(NSString *)verificationCode pin:(nullable NSString *)pin @@ -124,6 +133,9 @@ extern NSString *const kNSNotificationName_LocalNumberDidChange; - (BOOL)isDeregistered; - (void)setIsDeregistered:(BOOL)isDeregistered; +- (BOOL)hasPendingBackupRestoreDecision; +- (void)setHasPendingBackupRestoreDecision:(BOOL)value; + #pragma mark - Re-registration // Re-registration is the process of re-registering _with the same phone number_. diff --git a/SignalServiceKit/src/Account/TSAccountManager.m b/SignalServiceKit/src/Account/TSAccountManager.m index ef5d9da2a..100b481d7 100644 --- a/SignalServiceKit/src/Account/TSAccountManager.m +++ b/SignalServiceKit/src/Account/TSAccountManager.m @@ -28,13 +28,13 @@ NS_ASSUME_NONNULL_BEGIN NSString *const TSRegistrationErrorDomain = @"TSRegistrationErrorDomain"; NSString *const TSRegistrationErrorUserInfoHTTPStatus = @"TSHTTPStatus"; NSString *const RegistrationStateDidChangeNotification = @"RegistrationStateDidChangeNotification"; -NSString *const DeregistrationStateDidChangeNotification = @"DeregistrationStateDidChangeNotification"; NSString *const kNSNotificationName_LocalNumberDidChange = @"kNSNotificationName_LocalNumberDidChange"; NSString *const TSAccountManager_RegisteredNumberKey = @"TSStorageRegisteredNumberKey"; NSString *const TSAccountManager_IsDeregisteredKey = @"TSAccountManager_IsDeregisteredKey"; NSString *const TSAccountManager_ReregisteringPhoneNumberKey = @"TSAccountManager_ReregisteringPhoneNumberKey"; NSString *const TSAccountManager_LocalRegistrationIdKey = @"TSStorageLocalRegistrationId"; +NSString *const TSAccountManager_HasPendingRestoreDecisionKey = @"TSAccountManager_HasPendingRestoreDecisionKey"; NSString *const TSAccountManager_UserAccountCollection = @"TSStorageUserAccountCollection"; NSString *const TSAccountManager_ServerAuthToken = @"TSStorageServerAuthToken"; @@ -135,9 +135,21 @@ NSString *const TSAccountManager_NeedsAccountAttributesUpdateKey = @"TSAccountMa userInfo:nil]; } -+ (BOOL)isRegistered +- (OWSRegistrationState)registrationState { - return [[self sharedInstance] isRegistered]; + if (!self.isRegistered) { + return OWSRegistrationState_Unregistered; + } else if (self.isDeregistered) { + if (self.isReregistering) { + return OWSRegistrationState_Reregistering; + } else { + return OWSRegistrationState_Deregistered; + } + } else if (self.isDeregistered) { + return OWSRegistrationState_PendingBackupRestore; + } else { + return OWSRegistrationState_Registered; + } } - (BOOL)isRegistered @@ -153,6 +165,11 @@ NSString *const TSAccountManager_NeedsAccountAttributesUpdateKey = @"TSAccountMa } } +- (BOOL)isRegisteredAndReady +{ + return self.registrationState == OWSRegistrationState_Registered; +} + - (void)didRegister { OWSLogInfo(@"didRegister"); @@ -164,14 +181,12 @@ NSString *const TSAccountManager_NeedsAccountAttributesUpdateKey = @"TSAccountMa [self storeLocalNumber:phoneNumber]; - [[NSNotificationCenter defaultCenter] postNotificationNameAsync:RegistrationStateDidChangeNotification - object:nil - userInfo:nil]; - // Warm these cached values. [self isRegistered]; [self localNumber]; [self isDeregistered]; + + [self postRegistrationStateDidChangeNotification]; } + (nullable NSString *)localNumber @@ -294,7 +309,7 @@ NSString *const TSAccountManager_NeedsAccountAttributesUpdateKey = @"TSAccountMa }]; } -+ (void)registerWithPhoneNumber:(NSString *)phoneNumber +- (void)registerWithPhoneNumber:(NSString *)phoneNumber success:(void (^)(void))successBlock failure:(void (^)(NSError *error))failureBlock smsVerification:(BOOL)isSMS @@ -308,8 +323,7 @@ NSString *const TSAccountManager_NeedsAccountAttributesUpdateKey = @"TSAccountMa // The country code of TSAccountManager.phoneNumberAwaitingVerification is used to // determine whether or not to use domain fronting, so it needs to be set _before_ // we make our verification code request. - TSAccountManager *manager = [self sharedInstance]; - manager.phoneNumberAwaitingVerification = phoneNumber; + self.phoneNumberAwaitingVerification = phoneNumber; TSRequest *request = [OWSRequestFactory requestVerificationCodeRequestWithPhoneNumber:phoneNumber @@ -331,21 +345,17 @@ NSString *const TSAccountManager_NeedsAccountAttributesUpdateKey = @"TSAccountMa }]; } -+ (void)rerequestSMSWithSuccess:(void (^)(void))successBlock failure:(void (^)(NSError *error))failureBlock +- (void)rerequestSMSWithSuccess:(void (^)(void))successBlock failure:(void (^)(NSError *error))failureBlock { - TSAccountManager *manager = [self sharedInstance]; - NSString *number = manager.phoneNumberAwaitingVerification; - + NSString *number = self.phoneNumberAwaitingVerification; OWSAssertDebug(number); [self registerWithPhoneNumber:number success:successBlock failure:failureBlock smsVerification:YES]; } -+ (void)rerequestVoiceWithSuccess:(void (^)(void))successBlock failure:(void (^)(NSError *error))failureBlock +- (void)rerequestVoiceWithSuccess:(void (^)(void))successBlock failure:(void (^)(NSError *error))failureBlock { - TSAccountManager *manager = [self sharedInstance]; - NSString *number = manager.phoneNumberAwaitingVerification; - + NSString *number = self.phoneNumberAwaitingVerification; OWSAssertDebug(number); [self registerWithPhoneNumber:number success:successBlock failure:failureBlock smsVerification:NO]; @@ -501,9 +511,7 @@ NSString *const TSAccountManager_NeedsAccountAttributesUpdateKey = @"TSAccountMa // `RegistrationStateDidChangeNotification` which is only safe to fire after // the data store is reset. - [[NSNotificationCenter defaultCenter] postNotificationNameAsync:RegistrationStateDidChangeNotification - object:nil - userInfo:nil]; + [self.sharedInstance postRegistrationStateDidChangeNotification]; } failure:^(NSURLSessionDataTask *task, NSError *error) { if (!IsNSErrorNetworkFailure(error)) { @@ -564,9 +572,7 @@ NSString *const TSAccountManager_NeedsAccountAttributesUpdateKey = @"TSAccountMa inCollection:TSAccountManager_UserAccountCollection]; }]; - [[NSNotificationCenter defaultCenter] postNotificationNameAsync:DeregistrationStateDidChangeNotification - object:nil - userInfo:nil]; + [self postRegistrationStateDidChangeNotification]; } #pragma mark - Re-registration @@ -593,6 +599,9 @@ NSString *const TSAccountManager_NeedsAccountAttributesUpdateKey = @"TSAccountMa forKey:TSAccountManager_ReregisteringPhoneNumberKey inCollection:TSAccountManager_UserAccountCollection]; }]; + + [self postRegistrationStateDidChangeNotification]; + return YES; } } @@ -614,6 +623,24 @@ NSString *const TSAccountManager_NeedsAccountAttributesUpdateKey = @"TSAccountMa inCollection:TSAccountManager_UserAccountCollection]; } +- (BOOL)hasPendingBackupRestoreDecision +{ + return [self.dbConnection boolForKey:TSAccountManager_HasPendingRestoreDecisionKey + inCollection:TSAccountManager_UserAccountCollection + defaultValue:NO]; +} + +- (void)setHasPendingBackupRestoreDecision:(BOOL)value +{ + OWSLogInfo(@"%d", value); + + [self.dbConnection setBool:value + forKey:TSAccountManager_HasPendingRestoreDecisionKey + inCollection:TSAccountManager_UserAccountCollection]; + + [self postRegistrationStateDidChangeNotification]; +} + - (BOOL)isManualMessageFetchEnabled { return [self.dbConnection boolForKey:TSAccountManager_ManualMessageFetchKey @@ -698,6 +725,17 @@ NSString *const TSAccountManager_NeedsAccountAttributesUpdateKey = @"TSAccountMa }]; } +#pragma mark - Notifications + +- (void)postRegistrationStateDidChangeNotification +{ + OWSAssertIsOnMainThread(); + + [[NSNotificationCenter defaultCenter] postNotificationNameAsync:RegistrationStateDidChangeNotification + object:nil + userInfo:nil]; +} + @end NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Account/TSPreKeyManager.m b/SignalServiceKit/src/Account/TSPreKeyManager.m index e24f57936..c90a4b6af 100644 --- a/SignalServiceKit/src/Account/TSPreKeyManager.m +++ b/SignalServiceKit/src/Account/TSPreKeyManager.m @@ -7,6 +7,7 @@ #import "NSURLSessionDataTask+StatusCode.h" #import "OWSIdentityManager.h" #import "OWSPrimaryStorage+SignedPreKeyStore.h" +#import "SSKEnvironment.h" #import "TSNetworkManager.h" #import "TSStorageHeaders.h" #import @@ -36,6 +37,15 @@ static const NSUInteger kMaxPrekeyUpdateFailureCount = 5; @implementation TSPreKeyManager +#pragma mark - Dependencies + ++ (TSAccountManager *)tsAccountManager +{ + OWSAssertDebug(SSKEnvironment.shared.tsAccountManager); + + return SSKEnvironment.shared.tsAccountManager; +} + #pragma mark - State Tracking + (BOOL)isAppLockedDueToPreKeyUpdateFailures @@ -102,7 +112,7 @@ static const NSUInteger kMaxPrekeyUpdateFailureCount = 5; } OWSAssertDebug(CurrentAppContext().isMainAppAndActive); - if (!TSAccountManager.isRegistered) { + if (!self.tsAccountManager.isRegistered) { return; } diff --git a/SignalServiceKit/src/Messages/OWSBatchMessageProcessor.m b/SignalServiceKit/src/Messages/OWSBatchMessageProcessor.m index 1ac05f937..8d6007c03 100644 --- a/SignalServiceKit/src/Messages/OWSBatchMessageProcessor.m +++ b/SignalServiceKit/src/Messages/OWSBatchMessageProcessor.m @@ -14,6 +14,7 @@ #import "OWSQueues.h" #import "OWSStorage.h" #import "SSKEnvironment.h" +#import "TSAccountManager.h" #import "TSDatabaseView.h" #import "TSErrorMessage.h" #import "TSYapDatabaseObject.h" @@ -267,6 +268,10 @@ NSString *const OWSMessageContentJobFinderExtensionGroup = @"OWSMessageContentJo selector:@selector(applicationDidEnterBackground:) name:OWSApplicationDidEnterBackgroundNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(registrationStateDidChange:) + name:RegistrationStateDidChangeNotification + object:nil]; // Start processing. [AppReadiness runNowOrWhenAppDidBecomeReady:^{ @@ -292,6 +297,13 @@ NSString *const OWSMessageContentJobFinderExtensionGroup = @"OWSMessageContentJo return SSKEnvironment.shared.messageManager; } +- (TSAccountManager *)tsAccountManager +{ + OWSAssertDebug(SSKEnvironment.shared.tsAccountManager); + + return SSKEnvironment.shared.tsAccountManager; +} + #pragma mark - Notifications - (void)applicationWillEnterForeground:(NSNotification *)notification @@ -304,6 +316,17 @@ NSString *const OWSMessageContentJobFinderExtensionGroup = @"OWSMessageContentJo self.isAppInBackground = YES; } +- (void)registrationStateDidChange:(NSNotification *)notification +{ + OWSAssertIsOnMainThread(); + + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ + if (CurrentAppContext().isMainApp) { + [self drainQueue]; + } + }]; +} + #pragma mark - instance methods - (dispatch_queue_t)serialQueue @@ -335,6 +358,9 @@ NSString *const OWSMessageContentJobFinderExtensionGroup = @"OWSMessageContentJo if (!CurrentAppContext().isMainApp) { return; } + if (!self.tsAccountManager.isRegisteredAndReady) { + return; + } dispatch_async(self.serialQueue, ^{ if (self.isDrainingQueue) { diff --git a/SignalServiceKit/src/Messages/OWSMessageDecrypter.m b/SignalServiceKit/src/Messages/OWSMessageDecrypter.m index ab75808e4..d3c6d69da 100644 --- a/SignalServiceKit/src/Messages/OWSMessageDecrypter.m +++ b/SignalServiceKit/src/Messages/OWSMessageDecrypter.m @@ -131,6 +131,13 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes return SSKEnvironment.shared.udManager; } +- (TSAccountManager *)tsAccountManager +{ + OWSAssertDebug(SSKEnvironment.shared.tsAccountManager); + + return SSKEnvironment.shared.tsAccountManager; +} + #pragma mark - Blocking - (BOOL)isEnvelopeSenderBlocked:(SSKProtoEnvelope *)envelope @@ -140,11 +147,6 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes return [self.blockingManager.blockedPhoneNumbers containsObject:envelope.source]; } -- (TSAccountManager *)tsAccountManager -{ - return TSAccountManager.sharedInstance; -} - #pragma mark - Decryption - (void)decryptEnvelope:(SSKProtoEnvelope *)envelope @@ -156,7 +158,7 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes OWSAssertDebug(envelopeData); OWSAssertDebug(successBlockParameter); OWSAssertDebug(failureBlockParameter); - OWSAssertDebug([TSAccountManager isRegistered]); + OWSAssertDebug([self.tsAccountManager isRegistered]); // successBlock is called synchronously so that we can avail ourselves of // the transaction. diff --git a/SignalServiceKit/src/Messages/OWSMessageManager.m b/SignalServiceKit/src/Messages/OWSMessageManager.m index 79b4a1e04..65ac98d68 100644 --- a/SignalServiceKit/src/Messages/OWSMessageManager.m +++ b/SignalServiceKit/src/Messages/OWSMessageManager.m @@ -236,7 +236,7 @@ NS_ASSUME_NONNULL_BEGIN OWSFail(@"Missing transaction."); return; } - if (!TSAccountManager.isRegistered) { + if (!self.tsAccountManager.isRegistered) { OWSFailDebug(@"Not registered."); return; } diff --git a/SignalServiceKit/src/Messages/OWSMessageReceiver.m b/SignalServiceKit/src/Messages/OWSMessageReceiver.m index 4b484414d..8859ca8e4 100644 --- a/SignalServiceKit/src/Messages/OWSMessageReceiver.m +++ b/SignalServiceKit/src/Messages/OWSMessageReceiver.m @@ -14,6 +14,7 @@ #import "OWSQueues.h" #import "OWSStorage.h" #import "SSKEnvironment.h" +#import "TSAccountManager.h" #import "TSDatabaseView.h" #import "TSErrorMessage.h" #import "TSYapDatabaseObject.h" @@ -254,6 +255,11 @@ NSString *const OWSMessageDecryptJobFinderExtensionGroup = @"OWSMessageProcessin } }]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(registrationStateDidChange:) + name:RegistrationStateDidChangeNotification + object:nil]; + return self; } @@ -273,6 +279,26 @@ NSString *const OWSMessageDecryptJobFinderExtensionGroup = @"OWSMessageProcessin return SSKEnvironment.shared.batchMessageProcessor; } +- (TSAccountManager *)tsAccountManager +{ + OWSAssertDebug(SSKEnvironment.shared.tsAccountManager); + + return SSKEnvironment.shared.tsAccountManager; +} + +#pragma mark - Notifications + +- (void)registrationStateDidChange:(NSNotification *)notification +{ + OWSAssertIsOnMainThread(); + + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ + if (CurrentAppContext().isMainApp) { + [self drainQueue]; + } + }]; +} + #pragma mark - Instance methods - (dispatch_queue_t)serialQueue @@ -298,6 +324,9 @@ NSString *const OWSMessageDecryptJobFinderExtensionGroup = @"OWSMessageProcessin if (!CurrentAppContext().isMainApp) { return; } + if (!self.tsAccountManager.isRegisteredAndReady) { + return; + } dispatch_async(self.serialQueue, ^{ if (self.isDrainingQueue) { diff --git a/SignalServiceKit/src/Messages/UD/OWSUDManager.swift b/SignalServiceKit/src/Messages/UD/OWSUDManager.swift index fbe0b3aa5..201d3e0cb 100644 --- a/SignalServiceKit/src/Messages/UD/OWSUDManager.swift +++ b/SignalServiceKit/src/Messages/UD/OWSUDManager.swift @@ -123,7 +123,7 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager { @objc public func setup() { AppReadiness.runNowOrWhenAppDidBecomeReady { - guard TSAccountManager.isRegistered() else { + guard self.tsAccountManager.isRegistered() else { return } diff --git a/SignalServiceKit/src/Network/WebSockets/OWSWebSocket.m b/SignalServiceKit/src/Network/WebSockets/OWSWebSocket.m index ea06c5272..60470630e 100644 --- a/SignalServiceKit/src/Network/WebSockets/OWSWebSocket.m +++ b/SignalServiceKit/src/Network/WebSockets/OWSWebSocket.m @@ -912,7 +912,7 @@ NSString *const kNSNotification_OWSWebSocketStateDidChange = @"kNSNotification_O return NO; } - if (![TSAccountManager isRegistered]) { + if (![self.tsAccountManager isRegistered]) { return NO; } diff --git a/SignalShareExtension/ShareViewController.swift b/SignalShareExtension/ShareViewController.swift index c39e7c810..db8035f63 100644 --- a/SignalShareExtension/ShareViewController.swift +++ b/SignalShareExtension/ShareViewController.swift @@ -12,6 +12,14 @@ import PromiseKit @objc public class ShareViewController: UIViewController, ShareViewDelegate, SAEFailedViewDelegate { + // MARK: - Dependencies + + private var tsAccountManager: TSAccountManager { + return TSAccountManager.sharedInstance() + } + + // MARK: - + enum ShareViewControllerError: Error { case assertionError(description: String) case unsupportedMedia @@ -171,7 +179,7 @@ public class ShareViewController: UIViewController, ShareViewDelegate, SAEFailed // We don't need to use RTCInitializeSSL() in the SAE. - if TSAccountManager.isRegistered() { + if tsAccountManager.isRegistered() { // 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 DispatchQueue.global().async { [weak self] in @@ -192,7 +200,7 @@ public class ShareViewController: UIViewController, ShareViewDelegate, SAEFailed // We don't need to prod the TSSocketManager in the SAE. } - if TSAccountManager.isRegistered() { + if tsAccountManager.isRegistered() { DispatchQueue.main.async { [weak self] in guard let _ = self else { return } Logger.info("running post launch block for registered user: \(TSAccountManager.localNumber)") @@ -253,7 +261,7 @@ public class ShareViewController: UIViewController, ShareViewDelegate, SAEFailed // it will also run all deferred blocks. AppReadiness.setAppIsReady() - if TSAccountManager.isRegistered() { + if tsAccountManager.isRegistered() { Logger.info("localNumber: \(TSAccountManager.localNumber)") // We don't need to use messageFetcherJob in the SAE. @@ -285,7 +293,7 @@ public class ShareViewController: UIViewController, ShareViewDelegate, SAEFailed Logger.debug("") - if TSAccountManager.isRegistered() { + if tsAccountManager.isRegistered() { Logger.info("localNumber: \(TSAccountManager.localNumber)") // We don't need to use ExperienceUpgradeFinder in the SAE. @@ -325,7 +333,7 @@ public class ShareViewController: UIViewController, ShareViewDelegate, SAEFailed Logger.info("Presenting content view") - if !TSAccountManager.isRegistered() { + if !tsAccountManager.isRegistered() { showNotRegisteredView() } else if !OWSProfileManager.shared().localProfileExists() { // This is a rare edge case, but we want to ensure that the user @@ -451,7 +459,7 @@ public class ShareViewController: UIViewController, ShareViewDelegate, SAEFailed // If a user unregisters in the main app, the SAE should shut down // immediately. - guard !TSAccountManager.isRegistered() else { + guard !tsAccountManager.isRegistered() else { // If user is registered, do nothing. return }