|
|
|
//
|
|
|
|
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
import UIKit
|
|
|
|
|
|
|
|
import SignalMessaging
|
|
|
|
import PureLayout
|
|
|
|
import SignalServiceKit
|
|
|
|
|
|
|
|
@objc
|
|
|
|
public class ShareViewController: UINavigationController, SAELoadViewDelegate {
|
|
|
|
|
|
|
|
private var contactsSyncing: OWSContactsSyncing?
|
|
|
|
|
|
|
|
private var hasInitialRootViewController = false
|
|
|
|
private var isReadyForAppExtensions = false
|
|
|
|
|
|
|
|
override open func loadView() {
|
|
|
|
super.loadView()
|
|
|
|
|
|
|
|
Logger.debug("\(self.logTag()) \(#function)")
|
|
|
|
|
|
|
|
// This should be the first thing we do.
|
|
|
|
SetCurrentAppContext(ShareAppExtensionContext(rootViewController:self))
|
|
|
|
|
|
|
|
DebugLogger.shared().enableTTYLogging()
|
|
|
|
if _isDebugAssertConfiguration() {
|
|
|
|
DebugLogger.shared().enableFileLogging()
|
|
|
|
} else if (OWSPreferences.isLoggingEnabled()) {
|
|
|
|
// TODO: Consult OWSPreferences.isLoggingEnabled.
|
|
|
|
DebugLogger.shared().enableFileLogging()
|
|
|
|
}
|
|
|
|
|
|
|
|
_ = AppVersion()
|
|
|
|
|
|
|
|
startupLogging()
|
|
|
|
|
|
|
|
SetRandFunctionSeed()
|
|
|
|
|
|
|
|
// We don't need to use DeviceSleepManager in the SAE.
|
|
|
|
|
|
|
|
setupEnvironment()
|
|
|
|
|
|
|
|
// TODO:
|
|
|
|
// [UIUtil applySignalAppearence];
|
|
|
|
|
|
|
|
if CurrentAppContext().isRunningTests() {
|
|
|
|
// TODO: Do we need to implement isRunningTests in the SAE context?
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
isReadyForAppExtensions = OWSPreferences.isReadyForAppExtensions()
|
|
|
|
if !isReadyForAppExtensions {
|
|
|
|
// TODO: Show the "You need to launch main app" view.
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// performUpdateCheck must be invoked after Environment has been initialized because
|
|
|
|
// upgrade process may depend on Environment.
|
|
|
|
VersionMigrations.performUpdateCheck()
|
|
|
|
|
|
|
|
let loadViewController = SAELoadViewController(delegate:self)
|
|
|
|
self.pushViewController(loadViewController, animated: false)
|
|
|
|
self.isNavigationBarHidden = false
|
|
|
|
|
|
|
|
// We don't need to use "screen protection" in the SAE.
|
|
|
|
|
|
|
|
contactsSyncing = OWSContactsSyncing(contactsManager:Environment.current().contactsManager,
|
|
|
|
identityManager:OWSIdentityManager.shared(),
|
|
|
|
messageSender:Environment.current().messageSender,
|
|
|
|
profileManager:OWSProfileManager.shared())
|
|
|
|
|
|
|
|
NotificationCenter.default.addObserver(self,
|
|
|
|
selector: #selector(databaseViewRegistrationComplete),
|
|
|
|
name: .DatabaseViewRegistrationComplete,
|
|
|
|
object: nil)
|
|
|
|
NotificationCenter.default.addObserver(self,
|
|
|
|
selector: #selector(registrationStateDidChange),
|
|
|
|
name: .RegistrationStateDidChange,
|
|
|
|
object: nil)
|
|
|
|
|
|
|
|
Logger.info("\(self.logTag) application: didFinishLaunchingWithOptions completed.")
|
|
|
|
|
|
|
|
OWSAnalytics.appLaunchDidBegin()
|
|
|
|
}
|
|
|
|
|
|
|
|
deinit {
|
|
|
|
NotificationCenter.default.removeObserver(self)
|
|
|
|
}
|
|
|
|
|
|
|
|
private func activate() {
|
|
|
|
Logger.debug("\(self.logTag()) \(#function)")
|
|
|
|
|
|
|
|
// We don't need to use "screen protection" in the SAE.
|
|
|
|
|
|
|
|
ensureRootViewController()
|
|
|
|
|
|
|
|
// Always check prekeys after app launches, and sometimes check on app activation.
|
|
|
|
TSPreKeyManager.checkPreKeysIfNecessary()
|
|
|
|
|
|
|
|
// We don't need to use RTCInitializeSSL() in the SAE.
|
|
|
|
|
|
|
|
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
|
|
|
|
guard let strongSelf = self else { return }
|
|
|
|
Logger.info("\(strongSelf.logTag) running post launch block for registered user: \(TSAccountManager.localNumber)")
|
|
|
|
|
|
|
|
// We don't need to use OWSDisappearingMessagesJob in the SAE.
|
|
|
|
|
|
|
|
// TODO remove this once we're sure our app boot process is coherent.
|
|
|
|
// Currently this happens *before* db registration is complete when
|
|
|
|
// launching the app directly, but *after* db registration is complete when
|
|
|
|
// the app is launched in the background, e.g. from a voip notification.
|
|
|
|
OWSProfileManager.shared().ensureLocalProfileCached()
|
|
|
|
|
|
|
|
// We don't need to use OWSFailedMessagesJob in the SAE.
|
|
|
|
|
|
|
|
// We don't need to use OWSFailedAttachmentDownloadsJob in the SAE.
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
Logger.info("\(self.logTag) running post launch block for unregistered user.")
|
|
|
|
|
|
|
|
// We don't need to update the app icon badge number in the SAE.
|
|
|
|
|
|
|
|
// We don't need to prod the TSSocketManager in the SAE.
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: Move this logic into the notification handler for "SAE will appear".
|
|
|
|
if TSAccountManager.isRegistered() {
|
|
|
|
DispatchQueue.main.async { [weak self] in
|
|
|
|
guard let strongSelf = self else { return }
|
|
|
|
Logger.info("\(strongSelf.logTag) running post launch block for registered user: \(TSAccountManager.localNumber)")
|
|
|
|
|
|
|
|
// We don't need to use the TSSocketManager in the SAE.
|
|
|
|
|
|
|
|
Environment.current().contactsManager.fetchSystemContactsOnceIfAlreadyAuthorized()
|
|
|
|
|
|
|
|
// We don't need to fetch messages in the SAE.
|
|
|
|
|
|
|
|
// We don't need to use OWSSyncPushTokensJob in the SAE.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@objc
|
|
|
|
func databaseViewRegistrationComplete() {
|
|
|
|
AssertIsOnMainThread()
|
|
|
|
|
|
|
|
Logger.debug("\(self.logTag()) \(#function)")
|
|
|
|
|
|
|
|
if TSAccountManager.isRegistered() {
|
|
|
|
Logger.info("\(self.logTag) localNumber: \(TSAccountManager.localNumber)")
|
|
|
|
|
|
|
|
// We don't need to use messageFetcherJob in the SAE.
|
|
|
|
|
|
|
|
// We don't need to use SyncPushTokensJob in the SAE.
|
|
|
|
}
|
|
|
|
|
|
|
|
// We don't need to use DeviceSleepManager in the SAE.
|
|
|
|
|
|
|
|
// TODO: Should we distinguish main app and SAE "completion"?
|
|
|
|
AppVersion.instance().appLaunchDidComplete()
|
|
|
|
|
|
|
|
ensureRootViewController()
|
|
|
|
|
|
|
|
// We don't need to use OWSMessageReceiver in the SAE.
|
|
|
|
// We don't need to use OWSBatchMessageProcessor in the SAE.
|
|
|
|
|
|
|
|
OWSProfileManager.shared().ensureLocalProfileCached()
|
|
|
|
|
|
|
|
// TODO:
|
|
|
|
// self.isEnvironmentSetup = YES;
|
|
|
|
|
|
|
|
// We don't need to use OWSOrphanedDataCleaner in the SAE.
|
|
|
|
|
|
|
|
//[OWSProfileManager.sharedManager fetchLocalUsersProfile];
|
|
|
|
//[[OWSReadReceiptManager sharedManager] prepareCachedValues];
|
|
|
|
//[[Environment current].contactsManager loadLastKnownContactRecipientIds];
|
|
|
|
}
|
|
|
|
|
|
|
|
@objc
|
|
|
|
func registrationStateDidChange() {
|
|
|
|
AssertIsOnMainThread()
|
|
|
|
|
|
|
|
Logger.debug("\(self.logTag()) \(#function)")
|
|
|
|
|
|
|
|
if TSAccountManager.isRegistered() {
|
|
|
|
Logger.info("\(self.logTag) localNumber: \(TSAccountManager.localNumber)")
|
|
|
|
|
|
|
|
// We don't need to use ExperienceUpgradeFinder in the SAE.
|
|
|
|
|
|
|
|
// We don't need to use OWSDisappearingMessagesJob in the SAE.
|
|
|
|
|
|
|
|
OWSProfileManager.shared().ensureLocalProfileCached()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private func ensureRootViewController() {
|
|
|
|
Logger.debug("\(self.logTag()) \(#function)")
|
|
|
|
|
|
|
|
guard !TSDatabaseView.hasPendingViewRegistrations() else {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
guard !hasInitialRootViewController else {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
hasInitialRootViewController = true
|
|
|
|
|
|
|
|
Logger.info("Presenting initial root view controller")
|
|
|
|
|
|
|
|
if TSAccountManager.isRegistered() {
|
|
|
|
// HomeViewController *homeView = [HomeViewController new];
|
|
|
|
// SignalsNavigationController *navigationController =
|
|
|
|
// [[SignalsNavigationController alloc] initWithRootViewController:homeView];
|
|
|
|
// self.window.rootViewController = navigationController;
|
|
|
|
} else {
|
|
|
|
// RegistrationViewController *viewController = [RegistrationViewController new];
|
|
|
|
// OWSNavigationController *navigationController =
|
|
|
|
// [[OWSNavigationController alloc] initWithRootViewController:viewController];
|
|
|
|
// navigationController.navigationBarHidden = YES;
|
|
|
|
// self.window.rootViewController = navigationController;
|
|
|
|
}
|
|
|
|
|
|
|
|
// We don't use the AppUpdateNag in the SAE.
|
|
|
|
}
|
|
|
|
|
|
|
|
func startupLogging() {
|
|
|
|
Logger.info("iOS Version: \(UIDevice.current.systemVersion)}")
|
|
|
|
|
|
|
|
let locale = NSLocale.current as NSLocale
|
|
|
|
if let localeIdentifier = locale.object(forKey:NSLocale.Key.identifier) as? String,
|
|
|
|
localeIdentifier.count > 0 {
|
|
|
|
Logger.info("Locale Identifier: \(localeIdentifier)")
|
|
|
|
} else {
|
|
|
|
owsFail("Locale Identifier: Unknown")
|
|
|
|
}
|
|
|
|
if let countryCode = locale.object(forKey:NSLocale.Key.countryCode) as? String,
|
|
|
|
countryCode.count > 0 {
|
|
|
|
Logger.info("Country Code: \(countryCode)")
|
|
|
|
} else {
|
|
|
|
owsFail("Country Code: Unknown")
|
|
|
|
}
|
|
|
|
if let languageCode = locale.object(forKey:NSLocale.Key.languageCode) as? String,
|
|
|
|
languageCode.count > 0 {
|
|
|
|
Logger.info("Language Code: \(languageCode)")
|
|
|
|
} else {
|
|
|
|
owsFail("Language Code: Unknown")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func setupEnvironment() {
|
|
|
|
let environment = Release.releaseEnvironment()
|
|
|
|
Environment.setCurrent(environment)
|
|
|
|
|
|
|
|
// Encryption/Decryption mutates session state and must be synchronized on a serial queue.
|
|
|
|
SessionCipher.setSessionCipherDispatchQueue(OWSDispatch.sessionStoreQueue())
|
|
|
|
|
|
|
|
let sharedEnv = TextSecureKitEnv(callMessageHandler:SAECallMessageHandler(),
|
|
|
|
contactsManager:Environment.current().contactsManager,
|
|
|
|
messageSender:Environment.current().messageSender,
|
|
|
|
notificationsManager:SAENotificationsManager(),
|
|
|
|
profileManager:OWSProfileManager.shared())
|
|
|
|
TextSecureKitEnv.setShared(sharedEnv)
|
|
|
|
|
|
|
|
TSStorageManager.shared().setupDatabase(safeBlockingMigrations: {
|
|
|
|
VersionMigrations.runSafeBlockingMigrations()
|
|
|
|
})
|
|
|
|
|
|
|
|
Environment.current().contactsManager.startObserving()
|
|
|
|
}
|
|
|
|
|
|
|
|
// MARK: View Lifecycle
|
|
|
|
|
|
|
|
override open func viewDidLoad() {
|
|
|
|
super.viewDidLoad()
|
|
|
|
|
|
|
|
Logger.debug("\(self.logTag()) \(#function)")
|
|
|
|
|
|
|
|
if isReadyForAppExtensions {
|
|
|
|
activate()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
override open func viewWillAppear(_ animated: Bool) {
|
|
|
|
Logger.debug("\(self.logTag()) \(#function)")
|
|
|
|
|
|
|
|
super.viewWillAppear(animated)
|
|
|
|
}
|
|
|
|
|
|
|
|
override open func viewDidAppear(_ animated: Bool) {
|
|
|
|
Logger.debug("\(self.logTag()) \(#function)")
|
|
|
|
|
|
|
|
super.viewDidAppear(animated)
|
|
|
|
}
|
|
|
|
|
|
|
|
override open func viewWillDisappear(_ animated: Bool) {
|
|
|
|
Logger.debug("\(self.logTag()) \(#function)")
|
|
|
|
|
|
|
|
super.viewWillDisappear(animated)
|
|
|
|
|
|
|
|
Logger.flush()
|
|
|
|
}
|
|
|
|
|
|
|
|
override open func viewDidDisappear(_ animated: Bool) {
|
|
|
|
Logger.debug("\(self.logTag()) \(#function)")
|
|
|
|
|
|
|
|
super.viewDidDisappear(animated)
|
|
|
|
|
|
|
|
Logger.flush()
|
|
|
|
}
|
|
|
|
|
|
|
|
// MARK: SAELoadViewDelegate
|
|
|
|
|
|
|
|
public func shareExtensionWasCancelled() {
|
|
|
|
self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
|
|
|
|
}
|
|
|
|
}
|