diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index 060ba313a..45a3b0904 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -18,6 +18,7 @@ #import "Signal-Swift.h" #import "TSMessagesManager.h" #import "TSSocketManager.h" +#import "TSStorageManager+Calling.h" #import "TextSecureKitEnv.h" #import "VersionMigrations.h" #import @@ -377,6 +378,15 @@ static NSString *const kURLHostVerifyPrefix = @"verify"; return NO; } + NSString *_Nullable phoneNumber = handle; + if ([handle hasPrefix:CallKitCallManager.kAnonymousCallHandlePrefix]) { + phoneNumber = [[TSStorageManager sharedManager] phoneNumberForCallKitId:handle]; + if (phoneNumber.length < 1) { + DDLogWarn(@"%@ ignoring attempt to initiate video call to unknown anonymous signal user.", self.tag); + return NO; + } + } + // This intent can be received from more than one user interaction. // // * It can be received if the user taps the "video" button in the CallKit UI for an @@ -386,7 +396,7 @@ static NSString *const kURLHostVerifyPrefix = @"verify"; // contacts app. If so, the correct response is to try to initiate a new call // to that user - unless there already is another call in progress. if ([Environment getCurrent].callService.call != nil) { - if ([handle isEqualToString:[Environment getCurrent].callService.call.remotePhoneNumber]) { + if ([phoneNumber isEqualToString:[Environment getCurrent].callService.call.remotePhoneNumber]) { DDLogWarn(@"%@ trying to upgrade ongoing call to video.", self.tag); [[Environment getCurrent].callService handleCallKitStartVideo]; return YES; @@ -399,7 +409,7 @@ static NSString *const kURLHostVerifyPrefix = @"verify"; OutboundCallInitiator *outboundCallInitiator = [Environment getCurrent].outboundCallInitiator; OWSAssert(outboundCallInitiator); - return [outboundCallInitiator initiateCallWithHandle:handle]; + return [outboundCallInitiator initiateCallWithHandle:phoneNumber]; } else if ([userActivity.activityType isEqualToString:@"INStartAudioCallIntent"]) { if (!SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(10, 0)) { @@ -423,6 +433,15 @@ static NSString *const kURLHostVerifyPrefix = @"verify"; return NO; } + NSString *_Nullable phoneNumber = handle; + if ([handle hasPrefix:CallKitCallManager.kAnonymousCallHandlePrefix]) { + phoneNumber = [[TSStorageManager sharedManager] phoneNumberForCallKitId:handle]; + if (phoneNumber.length < 1) { + DDLogWarn(@"%@ ignoring attempt to initiate audio call to unknown anonymous signal user.", self.tag); + return NO; + } + } + if ([Environment getCurrent].phoneManager.hasOngoingRedphoneCall) { DDLogWarn(@"%@ ignoring INStartAudioCallIntent due to ongoing RedPhone call.", self.tag); return NO; @@ -434,7 +453,7 @@ static NSString *const kURLHostVerifyPrefix = @"verify"; OutboundCallInitiator *outboundCallInitiator = [Environment getCurrent].outboundCallInitiator; OWSAssert(outboundCallInitiator); - return [outboundCallInitiator initiateCallWithHandle:handle]; + return [outboundCallInitiator initiateCallWithHandle:phoneNumber]; } else { DDLogWarn(@"%@ called %s with userActivity: %@, but not yet supported.", self.tag, diff --git a/Signal/src/Signal-Bridging-Header.h b/Signal/src/Signal-Bridging-Header.h index 55fadea30..fac87a093 100644 --- a/Signal/src/Signal-Bridging-Header.h +++ b/Signal/src/Signal-Bridging-Header.h @@ -21,6 +21,7 @@ #import "PushManager.h" #import "RPAccountManager.h" #import "TSSocketManager.h" +#import "TSStorageManager+Calling.h" #import "UIColor+OWS.h" #import "UIFont+OWS.h" #import "UIUtil.h" diff --git a/Signal/src/call/Speakerbox/CallKitCallManager.swift b/Signal/src/call/Speakerbox/CallKitCallManager.swift index 898383018..251b5bc66 100644 --- a/Signal/src/call/Speakerbox/CallKitCallManager.swift +++ b/Signal/src/call/Speakerbox/CallKitCallManager.swift @@ -23,9 +23,15 @@ final class CallKitCallManager: NSObject { // MARK: Actions func startCall(_ call: SignalCall) { - let handle = (Environment.getCurrent().preferences.isCallKitPrivacyEnabled() - ? CXHandle(type: .generic, value: CallKitCallManager.kAnonymousCallHandlePrefix + call.localId.uuidString) - : CXHandle(type: .phoneNumber, value: call.remotePhoneNumber)) + var handle: CXHandle + if Environment.getCurrent().preferences.isCallKitPrivacyEnabled() { + let callKitId = CallKitCallManager.kAnonymousCallHandlePrefix + call.localId.uuidString + handle = CXHandle(type: .generic, value: callKitId) + TSStorageManager.shared().setPhoneNumber(call.remotePhoneNumber, forCallKitId:callKitId) + } else { + handle = CXHandle(type: .phoneNumber, value: call.remotePhoneNumber) + } + let startCallAction = CXStartCallAction(call: call.localId, handle: handle) startCallAction.isVideo = call.hasLocalVideo diff --git a/Signal/src/call/Speakerbox/CallKitCallUIAdaptee.swift b/Signal/src/call/Speakerbox/CallKitCallUIAdaptee.swift index c445eebb1..03c74a8ff 100644 --- a/Signal/src/call/Speakerbox/CallKitCallUIAdaptee.swift +++ b/Signal/src/call/Speakerbox/CallKitCallUIAdaptee.swift @@ -100,9 +100,14 @@ final class CallKitCallUIAdaptee: NSObject, CallUIAdaptee, CXProviderDelegate { // Construct a CXCallUpdate describing the incoming call, including the caller. let update = CXCallUpdate() - update.remoteHandle = (Environment.getCurrent().preferences.isCallKitPrivacyEnabled() - ? CXHandle(type: .generic, value: CallKitCallManager.kAnonymousCallHandlePrefix + call.localId.uuidString) - : CXHandle(type: .phoneNumber, value: call.remotePhoneNumber)) + if Environment.getCurrent().preferences.isCallKitPrivacyEnabled() { + let callKitId = CallKitCallManager.kAnonymousCallHandlePrefix + call.localId.uuidString + update.remoteHandle = CXHandle(type: .generic, value: callKitId) + TSStorageManager.shared().setPhoneNumber(call.remotePhoneNumber, forCallKitId:callKitId) + } else { + update.remoteHandle = CXHandle(type: .phoneNumber, value: call.remotePhoneNumber) + } + update.hasVideo = call.hasLocalVideo // Update the name used in the CallKit UI for incoming calls. update.localizedCallerName = NSLocalizedString("CALLKIT_ANONYMOUS_CONTACT_NAME", comment: "The generic name used for calls if CallKit privacy is enabled") @@ -237,15 +242,15 @@ final class CallKitCallUIAdaptee: NSObject, CallUIAdaptee, CXProviderDelegate { _ = self.callService.handleOutgoingCall(call) action.fulfill() self.provider.reportOutgoingCall(with: call.localId, startedConnectingAt: nil) - + ensureCallName(call:call) } - func ensureCallName(call : SignalCall) { + func ensureCallName(call: SignalCall) { guard Environment.getCurrent().preferences.isCallKitPrivacyEnabled() else { - return; + return } - + // Update the name used in the CallKit UI for outgoing calls. let update = CXCallUpdate() update.localizedCallerName = NSLocalizedString("CALLKIT_ANONYMOUS_CONTACT_NAME", comment: "The generic name used for calls if CallKit privacy is enabled")