diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index 358020517..3ca909583 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -342,7 +342,6 @@ static NSString *const kURLHostVerifyPrefix = @"verify"; DDLogInfo(@"%@ got start audio call intent", self.tag); - // hoooooooooooly moly. INInteraction *interaction = [userActivity interaction]; INIntent *intent = interaction.intent; @@ -357,23 +356,8 @@ static NSString *const kURLHostVerifyPrefix = @"verify"; return NO; } - CallUIAdapter *callUIAdapter = [Environment getCurrent].callService.callUIAdapter; - OWSAssert(callUIAdapter); - - ContactsUpdater *contactsUpdater = [Environment getCurrent].contactsUpdater; - OWSAssert(contactsUpdater); - - OWSContactsManager *contactsManager = [Environment getCurrent].contactsManager; - OWSAssert(contactsManager); - - PhoneManager *phoneManager = [Environment getCurrent].phoneManager; - OWSAssert(phoneManager); - - OutboundCallInitiator *outboundCallInitiator = - [[OutboundCallInitiator alloc] initWithRedphoneManager:phoneManager - callUIAdapter:callUIAdapter - contactsManager:contactsManager - contactsUpdater:contactsUpdater]; + OutboundCallInitiator *outboundCallInitiator = [Environment getCurrent].outboundCallInitiator; + OWSAssert(outboundCallInitiator); return [outboundCallInitiator initiateCallWithHandle:handle]; } else { DDLogWarn(@"%@ called %s with userActivity: %@, but not yet supported.", diff --git a/Signal/src/environment/Environment.h b/Signal/src/environment/Environment.h index e5af9498a..a2ccde09f 100644 --- a/Signal/src/environment/Environment.h +++ b/Signal/src/environment/Environment.h @@ -31,6 +31,7 @@ static NSString *const kRedphoneCallSegue = @"2.0_6.0_Call_Segue"; @class UINavigationController; @class RecentCallManager; @class OWSContactsManager; +@class OutboundCallInitiator; @class PhoneManager; @class SignalsViewController; @class TSGroupThread; @@ -38,6 +39,7 @@ static NSString *const kRedphoneCallSegue = @"2.0_6.0_Call_Segue"; @class TSNetworkManager; @class AccountManager; @class OWSWebRTCCallMessageHandler; +@class CallUIAdapter; @class CallService; @class OWSMessageSender; @class NotificationsManager; @@ -78,8 +80,10 @@ static NSString *const kRedphoneCallSegue = @"2.0_6.0_Call_Segue"; @property (nonatomic, readonly) NSData *zrtpVersionId; @property (nonatomic, readonly) AccountManager *accountManager; @property (nonatomic, readonly) OWSWebRTCCallMessageHandler *callMessageHandler; +@property (nonatomic, readonly) CallUIAdapter *callUIAdapter; @property (nonatomic, readonly) CallService *callService; @property (nonatomic, readonly) OWSContactsManager *contactsManager; +@property (nonatomic, readonly) OutboundCallInitiator *outboundCallInitiator; @property (nonatomic, readonly) ContactsUpdater *contactsUpdater; @property (nonatomic, readonly) TSNetworkManager *networkManager; @property (nonatomic, readonly) NotificationsManager *notificationsManager; diff --git a/Signal/src/environment/Environment.m b/Signal/src/environment/Environment.m index d659e0378..9bda05e69 100644 --- a/Signal/src/environment/Environment.m +++ b/Signal/src/environment/Environment.m @@ -23,11 +23,12 @@ static Environment *environment = nil; @implementation Environment -@synthesize accountManager = _accountManager; -@synthesize callMessageHandler = _callMessageHandler; -@synthesize callService = _callService; -@synthesize notificationsManager = _notificationsManager; -@synthesize preferences = _preferences; +@synthesize accountManager = _accountManager, + callMessageHandler = _callMessageHandler, + callService = _callService, + notificationsManager = _notificationsManager, + preferences = _preferences, + outboundCallInitiator = _outboundCallInitiator; + (Environment *)getCurrent { NSAssert((environment != nil), @"Environment is not defined."); @@ -159,6 +160,9 @@ static Environment *environment = nil; { @synchronized (self) { if (!_callService) { + OWSAssert(self.accountManager); + OWSAssert(self.contactsManager); + OWSAssert(self.messageSender); _callService = [[CallService alloc] initWithAccountManager:self.accountManager contactsManager:self.contactsManager messageSender:self.messageSender @@ -169,6 +173,29 @@ static Environment *environment = nil; return _callService; } +- (CallUIAdapter *)callUIAdapter +{ + return self.callService.callUIAdapter; +} + +- (OutboundCallInitiator *)outboundCallInitiator +{ + @synchronized (self) { + if (!_outboundCallInitiator) { + OWSAssert(self.phoneManager); + OWSAssert(self.callUIAdapter); + OWSAssert(self.contactsManager); + OWSAssert(self.contactsUpdater); + _outboundCallInitiator = [[OutboundCallInitiator alloc] initWithRedphoneManager:self.phoneManager + callUIAdapter:self.callUIAdapter + contactsManager:self.contactsManager + contactsUpdater:self.contactsUpdater]; + } + } + + return _outboundCallInitiator; +} + + (PhoneManager *)phoneManager { return Environment.getCurrent.phoneManager; } diff --git a/Signal/src/view controllers/CallViewController.swift b/Signal/src/view controllers/CallViewController.swift index 601334cec..9e92cfd6a 100644 --- a/Signal/src/view controllers/CallViewController.swift +++ b/Signal/src/view controllers/CallViewController.swift @@ -83,15 +83,13 @@ class CallViewController: UIViewController, CallObserver, CallServiceObserver, R required init?(coder aDecoder: NSCoder) { contactsManager = Environment.getCurrent().contactsManager - let callService = Environment.getCurrent().callService! - callUIAdapter = callService.callUIAdapter + callUIAdapter = Environment.getCurrent().callUIAdapter super.init(coder: aDecoder) } required init() { contactsManager = Environment.getCurrent().contactsManager - let callService = Environment.getCurrent().callService! - callUIAdapter = callService.callUIAdapter + callUIAdapter = Environment.getCurrent().callUIAdapter super.init(nibName: nil, bundle: nil) } diff --git a/Signal/src/view controllers/MessagesViewController.m b/Signal/src/view controllers/MessagesViewController.m index a9fbb38a1..f8152ba7a 100644 --- a/Signal/src/view controllers/MessagesViewController.m +++ b/Signal/src/view controllers/MessagesViewController.m @@ -125,6 +125,7 @@ typedef enum : NSUInteger { @property (nonatomic, readonly) OWSDisappearingMessagesJob *disappearingMessagesJob; @property (nonatomic, readonly) TSMessagesManager *messagesManager; @property (nonatomic, readonly) TSNetworkManager *networkManager; +@property (nonatomic, readonly) OutboundCallInitiator *outboundCallInitiator; @property NSCache *messageAdapterCache; @@ -166,6 +167,7 @@ typedef enum : NSUInteger { _contactsManager = [Environment getCurrent].contactsManager; _contactsUpdater = [Environment getCurrent].contactsUpdater; _messageSender = [Environment getCurrent].messageSender; + _outboundCallInitiator = [Environment getCurrent].outboundCallInitiator; _storageManager = [TSStorageManager sharedManager]; _disappearingMessagesJob = [[OWSDisappearingMessagesJob alloc] initWithStorageManager:_storageManager]; _messagesManager = [TSMessagesManager sharedManager]; @@ -631,54 +633,7 @@ typedef enum : NSUInteger { return; } - // Since users can toggle this setting, which is only communicated during contact sync, it's easy to imagine the - // preference getting stale. Especially as users are toggling the feature to test calls. So here, we opt for a - // blocking network request *every* time we place a call to make sure we've got up to date preferences. - // - // e.g. The following would suffice if we weren't worried about stale preferences. - // SignalRecipient *recipient = [SignalRecipient recipientWithTextSecureIdentifier:self.thread.contactIdentifier]; - BOOL localWantsWebRTC = [Environment preferences].isWebRTCEnabled; - - if (!localWantsWebRTC) { - [self placeRedphoneCall]; - return; - } - - [self.contactsUpdater lookupIdentifier:self.thread.contactIdentifier - success:^(SignalRecipient *_Nonnull recipient) { - BOOL remoteWantsWebRTC = recipient.supportsWebRTC; - DDLogDebug(@"%@ localWantsWebRTC?: %@, remoteWantsWebRTC?: %@", - self.tag, - (localWantsWebRTC ? @"YES" : @"NO"), - (remoteWantsWebRTC ? @"YES" : @"NO")); - if (localWantsWebRTC && remoteWantsWebRTC) { - [self placeWebRTCCall]; - } else { - [self placeRedphoneCall]; - } - } - failure:^(NSError *_Nonnull error) { - DDLogWarn(@"%@ looking up call recipient: %@ failed with error: %@", self.tag, self.thread, error); - SignalAlertView(NSLocalizedString(@"UNABLE_TO_PLACE_CALL", @"Alert Title"), error.localizedDescription); - }]; -} - -- (void)placeRedphoneCall -{ - DDLogInfo(@"%@ Placing redphone call to: %@", self.tag, self.thread); - PhoneNumber *number = [PhoneNumber tryParsePhoneNumberFromUserSpecifiedText:self.thread.contactIdentifier]; - Contact *contact = [self.contactsManager latestContactForPhoneNumber:number]; - - OWSAssert(number != nil); - OWSAssert(contact != nil); - - [Environment.phoneManager initiateOutgoingCallToContact:contact atRemoteNumber:number]; -} - -- (void)placeWebRTCCall -{ - DDLogInfo(@"%@ Placing WebRTC call to: %@", self.tag, self.thread); - [self performSegueWithIdentifier:OWSMessagesViewControllerSegueInitiateCall sender:self]; + [self.outboundCallInitiator initiateCallWithRecipientId:self.thread.contactIdentifier]; } - (BOOL)canCall {