diff --git a/Signal/src/call/Speakerbox/CallKitCallUIAdaptee.swift b/Signal/src/call/Speakerbox/CallKitCallUIAdaptee.swift index 910ba07ff..6dae7486f 100644 --- a/Signal/src/call/Speakerbox/CallKitCallUIAdaptee.swift +++ b/Signal/src/call/Speakerbox/CallKitCallUIAdaptee.swift @@ -21,6 +21,7 @@ final class CallKitCallUIAdaptee: NSObject, CallUIAdaptee, CXProviderDelegate { private let callManager: CallKitCallManager internal let callService: CallService internal let notificationsAdapter: CallNotificationsAdapter + internal let contactsManager: OWSContactsManager private let provider: CXProvider // CallKit handles incoming ringer stop/start for us. Yay! @@ -48,13 +49,14 @@ final class CallKitCallUIAdaptee: NSObject, CallUIAdaptee, CXProviderDelegate { return providerConfiguration } - init(callService: CallService, notificationsAdapter: CallNotificationsAdapter) { + init(callService: CallService, contactsManager: OWSContactsManager, notificationsAdapter: CallNotificationsAdapter) { AssertIsOnMainThread() Logger.debug("\(self.TAG) \(#function)") self.callManager = CallKitCallManager() self.callService = callService + self.contactsManager = contactsManager self.notificationsAdapter = notificationsAdapter self.provider = CXProvider(configuration: type(of: self).providerConfiguration) @@ -104,13 +106,14 @@ final class CallKitCallUIAdaptee: NSObject, CallUIAdaptee, CXProviderDelegate { let callKitId = CallKitCallManager.kAnonymousCallHandlePrefix + call.localId.uuidString update.remoteHandle = CXHandle(type: .generic, value: callKitId) TSStorageManager.shared().setPhoneNumber(call.remotePhoneNumber, forCallKitId:callKitId) + update.localizedCallerName = NSLocalizedString("CALLKIT_ANONYMOUS_CONTACT_NAME", comment: "The generic name used for calls if CallKit privacy is enabled") } else { + update.localizedCallerName = self.contactsManager.stringForConversationTitle(withPhoneIdentifier: call.remotePhoneNumber) 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") + disableUnsupportedFeatures(callUpdate: update) // Report the incoming call to the system diff --git a/Signal/src/call/UserInterface/CallUIAdapter.swift b/Signal/src/call/UserInterface/CallUIAdapter.swift index c458c5b60..3f27bfe4b 100644 --- a/Signal/src/call/UserInterface/CallUIAdapter.swift +++ b/Signal/src/call/UserInterface/CallUIAdapter.swift @@ -91,7 +91,7 @@ extension CallUIAdaptee { adaptee = NonCallKitCallUIAdaptee(callService: callService, notificationsAdapter: notificationsAdapter) } else if #available(iOS 10.0, *), Environment.getCurrent().preferences.isCallKitEnabled() { Logger.info("\(TAG) choosing callkit adaptee for iOS10+") - adaptee = CallKitCallUIAdaptee(callService: callService, notificationsAdapter: notificationsAdapter) + adaptee = CallKitCallUIAdaptee(callService: callService, contactsManager: contactsManager, notificationsAdapter: notificationsAdapter) } else { Logger.info("\(TAG) choosing non-callkit adaptee") adaptee = NonCallKitCallUIAdaptee(callService: callService, notificationsAdapter: notificationsAdapter) diff --git a/Signal/src/contact/OWSContactsManager.h b/Signal/src/contact/OWSContactsManager.h index 8d8e09a7c..644e44de9 100644 --- a/Signal/src/contact/OWSContactsManager.h +++ b/Signal/src/contact/OWSContactsManager.h @@ -68,6 +68,7 @@ extern NSString *const OWSContactsManagerSignalAccountsDidChangeNotification; - (nullable NSString *)formattedProfileNameForRecipientId:(NSString *)recipientId; - (nullable NSString *)profileNameForRecipientId:(NSString *)recipientId; - (nullable NSString *)nameFromSystemContactsForRecipientId:(NSString *)recipientId; +- (NSString *)stringForConversationTitleWithPhoneIdentifier:(NSString *)recipientId; - (nullable UIImage *)imageForPhoneIdentifier:(nullable NSString *)identifier; - (NSAttributedString *)formattedDisplayNameForSignalAccount:(SignalAccount *)signalAccount font:(UIFont *_Nonnull)font; diff --git a/Signal/src/contact/OWSContactsManager.m b/Signal/src/contact/OWSContactsManager.m index fa09b075e..89ce0c20c 100644 --- a/Signal/src/contact/OWSContactsManager.m +++ b/Signal/src/contact/OWSContactsManager.m @@ -610,6 +610,34 @@ NSString *const kTSStorageManager_AccountLastNames = @"kTSStorageManager_Account return [[NSAttributedString alloc] initWithString:recipientId]; } +// TODO refactor attributed counterparts to use this as a helper method? +- (NSString *)stringForConversationTitleWithPhoneIdentifier:(NSString *)recipientId +{ + // Prefer a saved name from system contacts, if available + NSString *_Nullable savedContactName = [self cachedDisplayNameForRecipientId:recipientId]; + if (savedContactName.length > 0) { + return savedContactName; + } + + NSString *formattedPhoneNumber = + [PhoneNumber bestEffortFormatPartialUserSpecifiedTextToLookLikeAPhoneNumber:recipientId]; + NSString *_Nullable profileName = [self.profileManager profileNameForRecipientId:recipientId]; + if (profileName.length > 0) { + NSString *numberAndProfileNameFormat = NSLocalizedString(@"PROFILE_NAME_AND_PHONE_NUMBER_LABEL_FORMAT", + @"Label text combining the phone number and profile name separated by a simple demarcation character. " + @"Phone number should be most prominent. '%1$@' is replaced with {{phone number}} and '%2$@' is replaced " + @"with {{profile name}}"); + + NSString *numberAndProfileName = + [NSString stringWithFormat:numberAndProfileNameFormat, formattedPhoneNumber, profileName]; + + return numberAndProfileName; + } + + // else fall back phone number + return formattedPhoneNumber; +} + - (nullable SignalAccount *)signalAccountForRecipientId:(NSString *)recipientId { OWSAssert(recipientId.length > 0);