From d7e52367ff20a827fc00d4f1f8b34454a8b74005 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Mon, 15 Oct 2018 14:34:41 -0400 Subject: [PATCH] Create AppEnvironment. --- Signal.xcodeproj/project.pbxproj | 4 + Signal/src/AppDelegate.m | 4 +- Signal/src/Jobs/MessageFetcherJob.swift | 23 ++-- Signal/src/Models/AccountManager.swift | 4 +- .../DebugUI/DebugUINotifications.swift | 5 +- Signal/src/call/CallService.swift | 122 +++++++++++------- Signal/src/call/OutboundCallInitiator.swift | 25 +++- .../src/call/WebRTCCallMessageHandler.swift | 38 ++++-- Signal/src/environment/AppEnvironment.swift | 89 +++++++++++++ Signal/src/environment/SignalApp.h | 2 +- Signal/src/environment/SignalApp.m | 71 ++-------- Signal/test/Models/AccountManagerTest.swift | 10 +- 12 files changed, 246 insertions(+), 151 deletions(-) create mode 100644 Signal/src/environment/AppEnvironment.swift diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index 1edd42b87..1861510d1 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -265,6 +265,7 @@ 34D8C02B1ED3685800188D7C /* DebugUIContacts.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D8C02A1ED3685800188D7C /* DebugUIContacts.m */; }; 34D920E720E179C200D51158 /* OWSMessageFooterView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D920E620E179C200D51158 /* OWSMessageFooterView.m */; }; 34D99C931F2937CC00D284D6 /* OWSAnalytics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D99C911F2937CC00D284D6 /* OWSAnalytics.swift */; }; + 34D99CE4217509C2000AFB39 /* AppEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D99CE3217509C1000AFB39 /* AppEnvironment.swift */; }; 34DB0BED2011548B007B313F /* OWSDatabaseConverterTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 34DB0BEC2011548B007B313F /* OWSDatabaseConverterTest.m */; }; 34DBF003206BD5A500025978 /* OWSMessageTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34DBEFFF206BD5A400025978 /* OWSMessageTextView.m */; }; 34DBF004206BD5A500025978 /* OWSBubbleView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34DBF001206BD5A500025978 /* OWSBubbleView.m */; }; @@ -942,6 +943,7 @@ 34D920E520E179C100D51158 /* OWSMessageFooterView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSMessageFooterView.h; sourceTree = ""; }; 34D920E620E179C200D51158 /* OWSMessageFooterView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSMessageFooterView.m; sourceTree = ""; }; 34D99C911F2937CC00D284D6 /* OWSAnalytics.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSAnalytics.swift; sourceTree = ""; }; + 34D99CE3217509C1000AFB39 /* AppEnvironment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppEnvironment.swift; sourceTree = ""; }; 34DB0BEB2011548A007B313F /* OWSDatabaseConverterTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSDatabaseConverterTest.h; sourceTree = ""; }; 34DB0BEC2011548B007B313F /* OWSDatabaseConverterTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSDatabaseConverterTest.m; sourceTree = ""; }; 34DBEFFF206BD5A400025978 /* OWSMessageTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSMessageTextView.m; sourceTree = ""; }; @@ -2160,6 +2162,7 @@ 76EB041118170B33006006FC /* environment */ = { isa = PBXGroup; children = ( + 34D99CE3217509C1000AFB39 /* AppEnvironment.swift */, 4505C2BD1E648E6E00CEBF41 /* ExperienceUpgrades */, 3461299A1FD1EA9E00532771 /* NotificationsManager.h */, 3461299B1FD1EA9E00532771 /* NotificationsManager.m */, @@ -3295,6 +3298,7 @@ 340FC8B4204DAC8D007AEB0F /* OWSBackupSettingsViewController.m in Sources */, 34D1F0871F8678AA0066283D /* ConversationViewItem.m in Sources */, 451A13B11E13DED2000A50FD /* CallNotificationsAdapter.swift in Sources */, + 34D99CE4217509C2000AFB39 /* AppEnvironment.swift in Sources */, 348570A820F67575004FF32B /* OWSMessageHeaderView.m in Sources */, 450DF2091E0DD2C6003D14BE /* UserNotificationsAdaptee.swift in Sources */, 34D1F0AB1F867BFC0066283D /* OWSContactOffersCell.m in Sources */, diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index 6a4135142..6612bb3a3 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -158,7 +158,9 @@ static NSTimeInterval launchStartedAt; [AppSetup setupEnvironmentWithAppSpecificSingletonBlock:^{ - [SignalApp.sharedApp createSingletons]; + // Create AppEnvironment. + [AppEnvironment shared]; + [SignalApp.sharedApp setup]; } migrationCompletion:^{ OWSAssertIsOnMainThread(); diff --git a/Signal/src/Jobs/MessageFetcherJob.swift b/Signal/src/Jobs/MessageFetcherJob.swift index 3eb548cda..b4fbd63ab 100644 --- a/Signal/src/Jobs/MessageFetcherJob.swift +++ b/Signal/src/Jobs/MessageFetcherJob.swift @@ -9,17 +9,16 @@ import SignalServiceKit @objc(OWSMessageFetcherJob) public class MessageFetcherJob: NSObject { - private var timer: Timer? +private + var timer : Timer ? - // MARK: injected dependencies - private let signalService: OWSSignalService + @objc public override + init() + { + super + .init() - @objc public init(signalService: OWSSignalService) { - self.signalService = signalService - - super.init() - - SwiftSingletons.register(self) + SwiftSingletons.register(self) } // MARK: Singletons @@ -32,6 +31,12 @@ public class MessageFetcherJob: NSObject { return SSKEnvironment.shared.messageReceiver } +private + var signalService : OWSSignalService + { + return OWSSignalService.sharedInstance() + } + // MARK: @discardableResult diff --git a/Signal/src/Models/AccountManager.swift b/Signal/src/Models/AccountManager.swift index 8477f404a..99c6a7a72 100644 --- a/Signal/src/Models/AccountManager.swift +++ b/Signal/src/Models/AccountManager.swift @@ -18,8 +18,8 @@ public class AccountManager: NSObject { return PushManager.shared() } - @objc - public required override init() { + @objc public override init() + { super.init() SwiftSingletons.register(self) diff --git a/Signal/src/ViewControllers/DebugUI/DebugUINotifications.swift b/Signal/src/ViewControllers/DebugUI/DebugUINotifications.swift index e0e858c9b..336f97516 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUINotifications.swift +++ b/Signal/src/ViewControllers/DebugUI/DebugUINotifications.swift @@ -14,7 +14,7 @@ class DebugUINotifications: DebugUIPage { return SignalApp.shared().notificationsManager } var notificationsAdapter: CallNotificationsAdapter { - return SignalApp.shared().callService.notificationsAdapter + return AppEnvironment.shared.callNotificationsAdapter } var messageSender: MessageSender { return SSKEnvironment.shared.messageSender @@ -29,7 +29,8 @@ class DebugUINotifications: DebugUIPage { return "Notifications" } - override func section(thread aThread: TSThread?) -> OWSTableSection? { + override func section(thread aThread: TSThread?) -> OWSTableSection? + { guard let thread = aThread else { owsFailDebug("Notifications must specify thread.") return nil diff --git a/Signal/src/call/CallService.swift b/Signal/src/call/CallService.swift index c6ee1aba5..1a022d2ff 100644 --- a/Signal/src/call/CallService.swift +++ b/Signal/src/call/CallService.swift @@ -147,25 +147,28 @@ private class SignalCallData: NSObject { } } - required init(call: SignalCall) { - self.call = call + required init(call + : SignalCall) { self.call = call - let (callConnectedPromise, callConnectedResolver) = Promise.pending() - self.callConnectedPromise = callConnectedPromise - self.callConnectedResolver = callConnectedResolver + let(callConnectedPromise, callConnectedResolver) + = Promise.pending() self.callConnectedPromise = callConnectedPromise self.callConnectedResolver + = callConnectedResolver - let (peerConnectionClientPromise, peerConnectionClientResolver) = Promise.pending() - self.peerConnectionClientPromise = peerConnectionClientPromise - self.peerConnectionClientResolver = peerConnectionClientResolver + let(peerConnectionClientPromise, peerConnectionClientResolver) + = Promise.pending() self.peerConnectionClientPromise + = peerConnectionClientPromise self.peerConnectionClientResolver = peerConnectionClientResolver - let (readyToSendIceUpdatesPromise, readyToSendIceUpdatesResolver) = Promise.pending() - self.readyToSendIceUpdatesPromise = readyToSendIceUpdatesPromise - self.readyToSendIceUpdatesResolver = readyToSendIceUpdatesResolver + let(readyToSendIceUpdatesPromise, readyToSendIceUpdatesResolver) + = Promise.pending() self.readyToSendIceUpdatesPromise + = readyToSendIceUpdatesPromise self.readyToSendIceUpdatesResolver = readyToSendIceUpdatesResolver - super.init() - } + super + .init() - deinit { + SwiftSingletons.register(self) } + + deinit + { Logger.debug("[SignalCallData] deinit") } @@ -202,24 +205,23 @@ private class SignalCallData: NSObject { var observers = [Weak]() - // MARK: Dependencies + // MARK: Dependencies - private let accountManager: AccountManager - private let messageSender: MessageSender - private let contactsManager: OWSContactsManager - private let primaryStorage: OWSPrimaryStorage + // Exposed by environment.m - // Exposed by environment.m - internal let notificationsAdapter: CallNotificationsAdapter - @objc public var callUIAdapter: CallUIAdapter! + @objc public var callUIAdapter : CallUIAdapter ! - // MARK: Class + // MARK: Class - static let fallbackIceServer = RTCIceServer(urlStrings: ["stun:stun1.l.google.com:19302"]) + static let fallbackIceServer + = RTCIceServer(urlStrings + : ["stun:stun1.l.google.com:19302"]) - // MARK: Ivars + // MARK: Ivars - fileprivate var callData: SignalCallData? { + fileprivate var callData : SignalCallData + ? + { didSet { AssertIsOnMainThread() @@ -291,33 +293,59 @@ private class SignalCallData: NSObject { } } - @objc public required init(accountManager: AccountManager, contactsManager: OWSContactsManager, messageSender: MessageSender, notificationsAdapter: CallNotificationsAdapter) { - self.accountManager = accountManager - self.contactsManager = contactsManager - self.messageSender = messageSender - self.notificationsAdapter = notificationsAdapter - self.primaryStorage = OWSPrimaryStorage.shared() + @objc public override init() { super + .init() - super.init() + SwiftSingletons + .register(self) - SwiftSingletons.register(self) + self + .createCallUIAdapter() - self.createCallUIAdapter() + NotificationCenter.default + .addObserver(self, selector + : #selector(didEnterBackground), name + : NSNotification.Name.OWSApplicationDidEnterBackground, object + : nil) + NotificationCenter.default.addObserver( + self, selector + : #selector(didBecomeActive), name + : NSNotification.Name.OWSApplicationDidBecomeActive, object + : nil) } - NotificationCenter.default.addObserver(self, - selector: #selector(didEnterBackground), - name: NSNotification.Name.OWSApplicationDidEnterBackground, - object: nil) - NotificationCenter.default.addObserver(self, - selector: #selector(didBecomeActive), - name: NSNotification.Name.OWSApplicationDidBecomeActive, - object: nil) - } - - deinit { + deinit + { NotificationCenter.default.removeObserver(self) } + // MARK: - Dependencies + +private + var contactsManager : OWSContactsManager + { + return Environment.shared.contactsManager + } + +private + var messageSender : MessageSender + { + return SSKEnvironment.shared.messageSender + } + +private + var accountManager : AccountManager + { + return AppEnvironment.shared.accountManager + } + +private + var notificationsAdapter : CallNotificationsAdapter + { + return AppEnvironment.shared.callNotificationsAdapter + } + + // MARK: - Notifications + @objc func didEnterBackground() { AssertIsOnMainThread() self.updateIsVideoEnabled() @@ -328,6 +356,8 @@ private class SignalCallData: NSObject { self.updateIsVideoEnabled() } + // MARK: - + /** * Choose whether to use CallKit or a Notification backed interface for calling. */ diff --git a/Signal/src/call/OutboundCallInitiator.swift b/Signal/src/call/OutboundCallInitiator.swift index 3e84a69b3..2a694c2a2 100644 --- a/Signal/src/call/OutboundCallInitiator.swift +++ b/Signal/src/call/OutboundCallInitiator.swift @@ -11,18 +11,29 @@ import SignalMessaging */ @objc public class OutboundCallInitiator: NSObject { - let contactsManager: OWSContactsManager - let contactsUpdater: ContactsUpdater - - @objc public init(contactsManager: OWSContactsManager, contactsUpdater: ContactsUpdater) { - self.contactsManager = contactsManager - self.contactsUpdater = contactsUpdater - + @objc public override init() + { super.init() SwiftSingletons.register(self) } + // MARK: - Dependencies + +private + var contactsManager : OWSContactsManager + { + return Environment.shared.contactsManager + } + +private + var contactsUpdater : ContactsUpdater + { + return SSKEnvironment.shared.contactsUpdater + } + + // MARK: - + /** * |handle| is a user formatted phone number, e.g. from a system contacts entry */ diff --git a/Signal/src/call/WebRTCCallMessageHandler.swift b/Signal/src/call/WebRTCCallMessageHandler.swift index 8bc10932d..3c350ed60 100644 --- a/Signal/src/call/WebRTCCallMessageHandler.swift +++ b/Signal/src/call/WebRTCCallMessageHandler.swift @@ -9,24 +9,34 @@ import SignalMessaging @objc(OWSWebRTCCallMessageHandler) public class WebRTCCallMessageHandler: NSObject, OWSCallMessageHandler { - // MARK: - Properties - - // MARK: Dependencies - - let accountManager: AccountManager - let callService: CallService - let messageSender: MessageSender - // MARK: Initializers - @objc public required init(accountManager: AccountManager, callService: CallService, messageSender: MessageSender) { - self.accountManager = accountManager - self.callService = callService - self.messageSender = messageSender + @objc public override init() + { + super + .init() - super.init() + SwiftSingletons.register(self) + } - SwiftSingletons.register(self) + // MARK: - Dependencies + +private + var messageSender : MessageSender + { + return SSKEnvironment.shared.messageSender + } + +private + var accountManager : AccountManager + { + return AppEnvironment.shared.accountManager + } + +private + var callService : CallService + { + return AppEnvironment.shared.callService } // MARK: - Call Handlers diff --git a/Signal/src/environment/AppEnvironment.swift b/Signal/src/environment/AppEnvironment.swift new file mode 100644 index 000000000..c0f49b7b5 --- /dev/null +++ b/Signal/src/environment/AppEnvironment.swift @@ -0,0 +1,89 @@ +// +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// + +import Foundation + //import PromiseKit + //import PushKit + import SignalServiceKit import SignalMessaging + + @objc public class AppEnvironment : NSObject { + +private + static var _shared : AppEnvironment = AppEnvironment() + + @objc public class var shared : AppEnvironment { + get { return _shared } set + { + _shared = newValue + } + } + + @objc public var callMessageHandler : WebRTCCallMessageHandler + + @objc public var callService : CallService + + @objc public var outboundCallInitiator + : OutboundCallInitiator + + @objc public var messageFetcherJob : MessageFetcherJob + + @objc public var notificationsManager : NotificationsManager + + @objc public var accountManager + : AccountManager + + @objc public var callNotificationsAdapter : CallNotificationsAdapter + + @objc public init(callMessageHandler + : WebRTCCallMessageHandler, callService + : CallService, outboundCallInitiator + : OutboundCallInitiator, messageFetcherJob + : MessageFetcherJob, notificationsManager + : NotificationsManager, accountManager + : AccountManager, callNotificationsAdapter + : CallNotificationsAdapter) + { + self.callMessageHandler = callMessageHandler self.callService = callService self.outboundCallInitiator + = outboundCallInitiator self.messageFetcherJob = messageFetcherJob self.notificationsManager + = notificationsManager self.accountManager = accountManager self.callNotificationsAdapter + = callNotificationsAdapter + + super + .init() + + SwiftSingletons.register(self) + + setup() + } + +private + override init() + { + let accountManager = AccountManager() let notificationsManager + = NotificationsManager() let callNotificationsAdapter = CallNotificationsAdapter() let callService + = CallService() let callMessageHandler = WebRTCCallMessageHandler() let outboundCallInitiator + = OutboundCallInitiator() let messageFetcherJob = MessageFetcherJob() + + self.callMessageHandler + = callMessageHandler self.callService = callService self.outboundCallInitiator + = outboundCallInitiator self.messageFetcherJob = messageFetcherJob self.notificationsManager + = notificationsManager self.accountManager = accountManager self.callNotificationsAdapter + = callNotificationsAdapter + + super + .init() + + SwiftSingletons.register(self) + + setup() + } + +private + func setup() + { + // Hang certain singletons on SSKEnvironment too. + SSKEnvironment.shared.notificationsManager = notificationsManager SSKEnvironment.shared.callMessageHandler + = callMessageHandler + } +} diff --git a/Signal/src/environment/SignalApp.h b/Signal/src/environment/SignalApp.h index e19bc8e9b..d84ac11c2 100644 --- a/Signal/src/environment/SignalApp.h +++ b/Signal/src/environment/SignalApp.h @@ -36,7 +36,7 @@ NS_ASSUME_NONNULL_BEGIN + (instancetype)sharedApp; -- (void)createSingletons; +- (void)setup; #pragma mark - Conversation Presentation diff --git a/Signal/src/environment/SignalApp.m b/Signal/src/environment/SignalApp.m index 7bea1e48d..7c67ff63a 100644 --- a/Signal/src/environment/SignalApp.m +++ b/Signal/src/environment/SignalApp.m @@ -15,19 +15,6 @@ NS_ASSUME_NONNULL_BEGIN -@interface SignalApp () - -@property (nonatomic) OWSWebRTCCallMessageHandler *callMessageHandler; -@property (nonatomic) CallService *callService; -@property (nonatomic) OutboundCallInitiator *outboundCallInitiator; -@property (nonatomic) OWSMessageFetcherJob *messageFetcherJob; -@property (nonatomic) NotificationsManager *notificationsManager; -@property (nonatomic) AccountManager *accountManager; - -@end - -#pragma mark - - @implementation SignalApp + (instancetype)sharedApp @@ -55,88 +42,46 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark - Singletons -- (void)createSingletons -{ - OWSAssertDebug(SSKEnvironment.shared.messageSender); - OWSAssertDebug(Environment.shared.contactsManager); - OWSAssertDebug(Environment.shared.preferences); - OWSAssertDebug(SSKEnvironment.shared.networkManager); - OWSAssertDebug(SSKEnvironment.shared.contactsUpdater); - - _accountManager = [[AccountManager alloc] init]; - - _notificationsManager = [NotificationsManager new]; - SSKEnvironment.shared.notificationsManager = self.notificationsManager; - +- (void)setup { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didChangeCallLoggingPreference:) name:OWSPreferencesCallLoggingDidChangeNotification object:nil]; - _callService = [[CallService alloc] initWithAccountManager:self.accountManager - contactsManager:Environment.shared.contactsManager - messageSender:SSKEnvironment.shared.messageSender - notificationsAdapter:[OWSCallNotificationsAdapter new]]; - - _callMessageHandler = - [[OWSWebRTCCallMessageHandler alloc] initWithAccountManager:self.accountManager - callService:self.callService - messageSender:SSKEnvironment.shared.messageSender]; - SSKEnvironment.shared.callMessageHandler = self.callMessageHandler; - - _outboundCallInitiator = - [[OutboundCallInitiator alloc] initWithContactsManager:Environment.shared.contactsManager - contactsUpdater:SSKEnvironment.shared.contactsUpdater]; - - _messageFetcherJob = [[OWSMessageFetcherJob alloc] initWithSignalService:[OWSSignalService sharedInstance]]; } - (OWSWebRTCCallMessageHandler *)callMessageHandler { - OWSAssertDebug(_callMessageHandler); - - return _callMessageHandler; + return AppEnvironment.shared.callMessageHandler; } - (CallService *)callService { - OWSAssertDebug(_callService); - - return _callService; + return AppEnvironment.shared.callService; } - (CallUIAdapter *)callUIAdapter { - OWSAssertDebug(self.callService.callUIAdapter); - - return self.callService.callUIAdapter; + return AppEnvironment.shared.callService.callUIAdapter; } - (OutboundCallInitiator *)outboundCallInitiator { - OWSAssertDebug(_outboundCallInitiator); - - return _outboundCallInitiator; + return AppEnvironment.shared.outboundCallInitiator; } - (OWSMessageFetcherJob *)messageFetcherJob { - OWSAssertDebug(_messageFetcherJob); - - return _messageFetcherJob; + return AppEnvironment.shared.messageFetcherJob; } - (NotificationsManager *)notificationsManager { - OWSAssertDebug(_notificationsManager); - - return _notificationsManager; + return AppEnvironment.shared.notificationsManager; } - (AccountManager *)accountManager { - OWSAssertDebug(_accountManager); - - return _accountManager; + return AppEnvironment.shared.accountManager; } #pragma mark - View Convenience Methods diff --git a/Signal/test/Models/AccountManagerTest.swift b/Signal/test/Models/AccountManagerTest.swift index 2aedf780b..6c19e398b 100644 --- a/Signal/test/Models/AccountManagerTest.swift +++ b/Signal/test/Models/AccountManagerTest.swift @@ -42,11 +42,10 @@ class FailingTSAccountManager: TSAccountManager { } class VerifyingTSAccountManager: FailingTSAccountManager { - override func verifyAccount(withCode: String, - pin: String?, - success: @escaping () -> Void, failure: @escaping (Error) -> Void) { - success() - } + override func verifyAccount(withCode + : String, pin + : String ?, success : @escaping()->Void, failure + : @escaping(Error)->Void) { success() } s } class TokenObtainingTSAccountManager: VerifyingTSAccountManager { @@ -142,5 +141,4 @@ class AccountManagerTest: SignalBaseTest { self.waitForExpectations(timeout: 1.0, handler: nil) } - }