Merge branch 'charlesmchen/backupRestoreView'

pull/1/head
Matthew Chen 6 years ago
commit 018fe6cb42

@ -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 = "<group>"; };
343D3D991E9283F100165CA4 /* BlockListUIUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlockListUIUtils.h; sourceTree = "<group>"; };
343D3D9A1E9283F100165CA4 /* BlockListUIUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BlockListUIUtils.m; sourceTree = "<group>"; };
3441FD9E21A3604F00BB9542 /* BackupRestoreViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BackupRestoreViewController.swift; sourceTree = "<group>"; };
34480B341FD0929200BC14EF /* ShareAppExtensionContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShareAppExtensionContext.h; sourceTree = "<group>"; };
34480B351FD0929200BC14EF /* ShareAppExtensionContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ShareAppExtensionContext.m; sourceTree = "<group>"; };
34480B371FD092A900BC14EF /* SignalShareExtension-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SignalShareExtension-Bridging-Header.h"; sourceTree = "<group>"; };
@ -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 */,

@ -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];
}

@ -25,7 +25,7 @@ public class AccountManager: NSObject {
SwiftSingletons.register(self)
}
// MARK: - Singletons
// MARK: - Dependencies
private var networkManager: TSNetworkManager {
return SSKEnvironment.shared.networkManager

@ -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]];

@ -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];

@ -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();

@ -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

@ -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()
}
}
}

@ -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");

@ -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;
}

@ -53,6 +53,8 @@ NS_ASSUME_NONNULL_BEGIN
+ (void)clearAllNotifications;
- (void)showHomeView;
@end
NS_ASSUME_NONNULL_END

@ -3,9 +3,11 @@
//
#import "SignalApp.h"
#import "AppDelegate.h"
#import "ConversationViewController.h"
#import "HomeViewController.h"
#import "Signal-Swift.h"
#import "SignalsNavigationController.h"
#import <SignalCoreKit/Threading.h>
#import <SignalMessaging/DebugLogger.h>
#import <SignalMessaging/Environment.h>
@ -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

@ -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;

@ -10,6 +10,8 @@
#import <SignalCoreKit/Randomness.h>
#import <SignalServiceKit/YapDatabaseConnection+OWS.h>
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 () <OWSBackupJobDelegate>
@ -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

@ -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;
}

@ -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.");

@ -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";

@ -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;
}

@ -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];
}

@ -4,6 +4,7 @@
#import "OWS103EnableVideoCalling.h"
#import <SignalServiceKit/OWSRequestFactory.h>
#import <SignalServiceKit/SSKEnvironment.h>
#import <SignalServiceKit/TSAccountManager.h>
#import <SignalServiceKit/TSNetworkManager.h>
@ -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

@ -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
}

@ -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];
}

@ -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_.

@ -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

@ -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 <SignalCoreKit/NSDate+OWS.h>
@ -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;
}

@ -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) {

@ -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.

@ -236,7 +236,7 @@ NS_ASSUME_NONNULL_BEGIN
OWSFail(@"Missing transaction.");
return;
}
if (!TSAccountManager.isRegistered) {
if (!self.tsAccountManager.isRegistered) {
OWSFailDebug(@"Not registered.");
return;
}

@ -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) {

@ -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
}

@ -912,7 +912,7 @@ NSString *const kNSNotification_OWSWebSocketStateDidChange = @"kNSNotification_O
return NO;
}
if (![TSAccountManager isRegistered]) {
if (![self.tsAccountManager isRegistered]) {
return NO;
}

@ -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
}

Loading…
Cancel
Save