diff --git a/Pods b/Pods index 7fcaa35aac..3d393009e3 160000 --- a/Pods +++ b/Pods @@ -1 +1 @@ -Subproject commit 7fcaa35aac69aa47443b920ef4c6553bd1f8d9d3 +Subproject commit 3d393009e3fded14568792745f55eb8faccf44a0 diff --git a/Signal/src/Jobs/SessionResetJob.swift b/Signal/src/Jobs/SessionResetJob.swift index b67d1a378e..ab6be470ae 100644 --- a/Signal/src/Jobs/SessionResetJob.swift +++ b/Signal/src/Jobs/SessionResetJob.swift @@ -79,7 +79,7 @@ public class SessionResetOperation: OWSOperation, DurableOperation { let contactThread: TSContactThread var recipientId: String { - return contactThread.contactIdentifier() + return contactThread.contactAddress.transitional_phoneNumber } @objc public required init(contactThread: TSContactThread, jobRecord: OWSSessionResetJobRecord) { diff --git a/Signal/src/UserInterface/Notifications/AppNotifications.swift b/Signal/src/UserInterface/Notifications/AppNotifications.swift index 5472fb0a25..bbb9b3f3e5 100644 --- a/Signal/src/UserInterface/Notifications/AppNotifications.swift +++ b/Signal/src/UserInterface/Notifications/AppNotifications.swift @@ -212,7 +212,7 @@ public class NotificationPresenter: NSObject, NotificationsProtocol { func presentIncomingCall(_ call: SignalCall, callerName: String) { let remotePhoneNumber = call.remotePhoneNumber - let thread = TSContactThread.getOrCreateThread(contactId: remotePhoneNumber) + let thread = TSContactThread.getOrCreateThread(contactAddress: remotePhoneNumber.transitional_signalServiceAddress) let notificationTitle: String? let threadIdentifier: String? @@ -250,7 +250,7 @@ public class NotificationPresenter: NSObject, NotificationsProtocol { func presentMissedCall(_ call: SignalCall, callerName: String) { let remotePhoneNumber = call.remotePhoneNumber - let thread = TSContactThread.getOrCreateThread(contactId: remotePhoneNumber) + let thread = TSContactThread.getOrCreateThread(contactAddress: remotePhoneNumber.transitional_signalServiceAddress) let notificationTitle: String? let threadIdentifier: String? @@ -289,7 +289,7 @@ public class NotificationPresenter: NSObject, NotificationsProtocol { public func presentMissedCallBecauseOfNoLongerVerifiedIdentity(call: SignalCall, callerName: String) { let remotePhoneNumber = call.remotePhoneNumber - let thread = TSContactThread.getOrCreateThread(contactId: remotePhoneNumber) + let thread = TSContactThread.getOrCreateThread(contactAddress: remotePhoneNumber.transitional_signalServiceAddress) let notificationTitle: String? let threadIdentifier: String? @@ -327,7 +327,7 @@ public class NotificationPresenter: NSObject, NotificationsProtocol { public func presentMissedCallBecauseOfNewIdentity(call: SignalCall, callerName: String) { let remotePhoneNumber = call.remotePhoneNumber - let thread = TSContactThread.getOrCreateThread(contactId: remotePhoneNumber) + let thread = TSContactThread.getOrCreateThread(contactAddress: remotePhoneNumber.transitional_signalServiceAddress) let notificationTitle: String? let threadIdentifier: String? diff --git a/Signal/src/ViewControllers/Call/CallViewController.swift b/Signal/src/ViewControllers/Call/CallViewController.swift index 70d942084b..b587c7cf05 100644 --- a/Signal/src/ViewControllers/Call/CallViewController.swift +++ b/Signal/src/ViewControllers/Call/CallViewController.swift @@ -143,7 +143,7 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, required init(call: SignalCall) { contactsManager = Environment.shared.contactsManager self.call = call - self.thread = TSContactThread.getOrCreateThread(contactId: call.remotePhoneNumber) + self.thread = TSContactThread.getOrCreateThread(contactAddress: call.remotePhoneNumber.transitional_signalServiceAddress) super.init(nibName: nil, bundle: nil) allAudioSources = Set(callUIAdapter.audioService.availableInputs) diff --git a/Signal/src/ViewControllers/ConversationView/Cells/ConversationViewCell.h b/Signal/src/ViewControllers/ConversationView/Cells/ConversationViewCell.h index 9836dc38eb..479fb7974d 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/ConversationViewCell.h +++ b/Signal/src/ViewControllers/ConversationView/Cells/ConversationViewCell.h @@ -51,10 +51,6 @@ NS_ASSUME_NONNULL_BEGIN - (void)tappedAddToContactsOfferMessage:(OWSContactOffersInteraction *)interaction; - (void)tappedAddToProfileWhitelistOfferMessage:(OWSContactOffersInteraction *)interaction; -#pragma mark - Formatting - -- (NSAttributedString *)attributedContactOrProfileNameForPhoneIdentifier:(NSString *)recipientId; - #pragma mark - Caching - (NSCache *)cellMediaCache; diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m index e2f4c4aea2..9a7276e747 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m @@ -1720,8 +1720,12 @@ typedef enum : NSUInteger { - (BOOL)canCall { - return !(self.isGroupConversation || - [((TSContactThread *)self.thread).contactIdentifier isEqualToString:self.tsAccountManager.localNumber]); + TSContactThread *_Nullable contactThread; + if ([self.thread isKindOfClass:[TSContactThread class]]) { + contactThread = (TSContactThread *)self.thread; + } + + return !(self.isGroupConversation || contactThread.contactAddress.isLocalAddress); } #pragma mark - Dynamic Text @@ -1900,9 +1904,10 @@ typedef enum : NSUInteger { return; } else { + TSContactThread *thread = (TSContactThread *)self.thread; OWSLogInfo(@"Assuming tap on legacy nonblocking identity change corresponds to current contact thread: %@", - self.thread.contactIdentifier); - signalIdParam = self.thread.contactIdentifier; + thread.contactAddress); + signalIdParam = thread.contactAddress.transitional_phoneNumber; } } @@ -2271,15 +2276,6 @@ typedef enum : NSUInteger { [[OWSWindowManager sharedManager] showMenuActionsWindow:menuActionsViewController]; } -- (NSAttributedString *)attributedContactOrProfileNameForPhoneIdentifier:(NSString *)recipientId -{ - OWSAssertIsOnMainThread(); - OWSAssertDebug(recipientId.length > 0); - - return - [self.contactsManager attributedContactOrProfileNameForAddress:recipientId.transitional_signalServiceAddress]; -} - - (void)tappedUnknownContactBlockOfferMessage:(OWSContactOffersInteraction *)interaction { if (![self.thread isKindOfClass:[TSContactThread class]]) { @@ -2334,9 +2330,10 @@ typedef enum : NSUInteger { return; } TSContactThread *contactThread = (TSContactThread *)self.thread; - [self.contactsViewHelper presentContactViewControllerForRecipientId:contactThread.contactIdentifier - fromViewController:self - editImmediately:YES]; + [self.contactsViewHelper + presentContactViewControllerForRecipientId:contactThread.contactAddress.transitional_phoneNumber + fromViewController:self + editImmediately:YES]; // Delete the offers. [self.editingDatabaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewItem.m b/Signal/src/ViewControllers/ConversationView/ConversationViewItem.m index ed97421555..ebb28ef18c 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewItem.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewItem.m @@ -193,15 +193,16 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType) switch (self.interaction.interactionType) { case OWSInteractionType_TypingIndicator: { OWSTypingIndicatorInteraction *typingIndicator = (OWSTypingIndicatorInteraction *)self.interaction; - _authorConversationColorName = - [TSContactThread conversationColorNameForRecipientId:typingIndicator.recipientId - transaction:transaction]; + _authorConversationColorName = [TSContactThread + conversationColorNameForContactAddress:typingIndicator.recipientId.transitional_signalServiceAddress + transaction:transaction]; break; } case OWSInteractionType_IncomingMessage: { TSIncomingMessage *incomingMessage = (TSIncomingMessage *)self.interaction; - _authorConversationColorName = - [TSContactThread conversationColorNameForRecipientId:incomingMessage.authorId transaction:transaction]; + _authorConversationColorName = [TSContactThread + conversationColorNameForContactAddress:incomingMessage.authorId.transitional_signalServiceAddress + transaction:transaction]; break; } default: diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewModel.m b/Signal/src/ViewControllers/ConversationView/ConversationViewModel.m index 5cff43c1a6..50411afdb3 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewModel.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewModel.m @@ -1205,7 +1205,7 @@ static const int kYapDatabaseRangeMaxLength = 25000; BOOL shouldHaveAddToContactsOffer = YES; BOOL shouldHaveAddToProfileWhitelistOffer = YES; - SignalServiceAddress *recipientAddress = ((TSContactThread *)thread).contactAddress; + SignalServiceAddress *recipientAddress = contactThread.contactAddress; if (recipientAddress.isLocalAddress) { // Don't add self to contacts. diff --git a/Signal/src/ViewControllers/DebugUI/DebugUICalling.swift b/Signal/src/ViewControllers/DebugUI/DebugUICalling.swift index de8e514f57..29d7cb49f7 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUICalling.swift +++ b/Signal/src/ViewControllers/DebugUI/DebugUICalling.swift @@ -1,5 +1,5 @@ // -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // import Foundation @@ -42,9 +42,9 @@ class DebugUICalling: DebugUIPage { let callMessage = OWSOutgoingCallMessage(thread: thread, hangupMessage: hangupMessage) strongSelf.messageSender.sendPromise(message: callMessage).done { - Logger.debug("Successfully sent hangup call message to \(thread.contactIdentifier())") + Logger.debug("Successfully sent hangup call message to \(thread.contactAddress)") }.catch { error in - Logger.error("failed to send hangup call message to \(thread.contactIdentifier()) with error: \(error)") + Logger.error("failed to send hangup call message to \(thread.contactAddress) with error: \(error)") }.retainUntilComplete() }, OWSTableItem(title: "Send 'busy' for old call") { [weak self] in @@ -63,9 +63,9 @@ class DebugUICalling: DebugUIPage { let callMessage = OWSOutgoingCallMessage(thread: thread, busyMessage: busyMessage) strongSelf.messageSender.sendPromise(message: callMessage).done { - Logger.debug("Successfully sent busy call message to \(thread.contactIdentifier())") + Logger.debug("Successfully sent busy call message to \(thread.contactAddress)") }.catch { error in - Logger.error("failed to send busy call message to \(thread.contactIdentifier()) with error: \(error)") + Logger.error("failed to send busy call message to \(thread.contactAddress) with error: \(error)") }.retainUntilComplete() } ] diff --git a/Signal/src/ViewControllers/DebugUI/DebugUIContacts.m b/Signal/src/ViewControllers/DebugUI/DebugUIContacts.m index bff8a49681..a21b5bd320 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUIContacts.m +++ b/Signal/src/ViewControllers/DebugUI/DebugUIContacts.m @@ -107,7 +107,8 @@ NS_ASSUME_NONNULL_BEGIN + (void)createUnregisteredContactThread { NSString *recipientId = [self unregisteredRecipientId]; - TSContactThread *thread = [TSContactThread getOrCreateThreadWithContactId:recipientId]; + TSContactThread *thread = + [TSContactThread getOrCreateThreadWithContactAddress:recipientId.transitional_signalServiceAddress]; [SignalApp.sharedApp presentConversationForThread:thread animated:YES]; } diff --git a/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m b/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m index c510347048..036b9411bc 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m +++ b/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m @@ -305,7 +305,7 @@ NS_ASSUME_NONNULL_BEGIN if ([thread isKindOfClass:[TSContactThread class]]) { TSContactThread *contactThread = (TSContactThread *)thread; - NSString *recipientId = contactThread.contactIdentifier; + NSString *recipientId = contactThread.contactAddress.transitional_phoneNumber; [items addObject:[OWSTableItem itemWithTitle:@"Create 10 new groups" actionBlock:^{ [DebugUIMessages createNewGroups:10 recipientId:recipientId]; @@ -381,7 +381,8 @@ NS_ASSUME_NONNULL_BEGIN + (void)sendMessages:(NSUInteger)count toAllMembersOfGroup:(TSGroupThread *)groupThread { for (NSString *recipientId in groupThread.groupModel.groupMemberIds) { - TSContactThread *contactThread = [TSContactThread getOrCreateThreadWithContactId:recipientId]; + TSContactThread *contactThread = + [TSContactThread getOrCreateThreadWithContactAddress:recipientId.transitional_signalServiceAddress]; [[self sendTextMessagesActionInThread:contactThread] prepareAndPerformNTimes:count]; } } @@ -3457,7 +3458,7 @@ typedef OWSContact * (^OWSContactBlock)(SDSAnyWriteTransaction *transaction); return gThread.groupModel.groupMemberIds[0]; } else if ([thread isKindOfClass:[TSContactThread class]]) { TSContactThread *contactThread = (TSContactThread *)thread; - return contactThread.contactIdentifier; + return contactThread.contactAddress.transitional_phoneNumber; } else { OWSFailDebug(@"failure: unknown thread type"); return @"unknown-source-id"; @@ -3760,7 +3761,8 @@ typedef OWSContact * (^OWSContactBlock)(SDSAnyWriteTransaction *transaction); OWSAssertDebug(phoneNumber); OWSAssertDebug(phoneNumber.toE164); - TSContactThread *contactThread = [TSContactThread getOrCreateThreadWithContactId:phoneNumber.toE164]; + TSContactThread *contactThread = [TSContactThread + getOrCreateThreadWithContactAddress:phoneNumber.toE164.transitional_signalServiceAddress]; [self sendFakeMessages:messageCount thread:contactThread]; [self.databaseStorage readWithBlock:^(SDSAnyReadTransaction *transaction) { NSUInteger interactionCount = [contactThread numberOfInteractionsWithTransaction:transaction]; diff --git a/Signal/src/ViewControllers/DebugUI/DebugUINotifications.swift b/Signal/src/ViewControllers/DebugUI/DebugUINotifications.swift index 76e756cd66..572f660b32 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUINotifications.swift +++ b/Signal/src/ViewControllers/DebugUI/DebugUINotifications.swift @@ -108,7 +108,7 @@ class DebugUINotifications: DebugUIPage { } func delayedNotificationDispatchWithFakeCall(thread: TSContactThread, callBlock: @escaping (SignalCall) -> Void) -> Guarantee { - let call = SignalCall.incomingCall(localId: UUID(), remotePhoneNumber: thread.contactIdentifier(), signalingId: 0) + let call = SignalCall.incomingCall(localId: UUID(), remotePhoneNumber: thread.contactAddress.transitional_phoneNumber, signalingId: 0) return delayedNotificationDispatch { callBlock(call) diff --git a/Signal/src/ViewControllers/DebugUI/DebugUISessionState.m b/Signal/src/ViewControllers/DebugUI/DebugUISessionState.m index 88424db3dc..4080385153 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUISessionState.m +++ b/Signal/src/ViewControllers/DebugUI/DebugUISessionState.m @@ -59,7 +59,7 @@ NS_ASSUME_NONNULL_BEGIN OWSLogError(@"Flipping identity Key. Flip again to return."); OWSIdentityManager *identityManager = [OWSIdentityManager sharedManager]; - NSString *recipientId = [thread contactIdentifier]; + NSString *recipientId = thread.contactAddress.transitional_phoneNumber; NSData *currentKey = [identityManager identityKeyForRecipientId:recipientId]; NSMutableData *flippedKey = [NSMutableData new]; diff --git a/Signal/src/ViewControllers/HomeView/HomeViewCell.m b/Signal/src/ViewControllers/HomeView/HomeViewCell.m index cdf3627547..47182adb9f 100644 --- a/Signal/src/ViewControllers/HomeView/HomeViewCell.m +++ b/Signal/src/ViewControllers/HomeView/HomeViewCell.m @@ -479,7 +479,7 @@ NS_ASSUME_NONNULL_BEGIN return; } - if (![self.thread.contactIdentifier isEqualToString:recipientId]) { + if (![self.thread.contactAddress.transitional_phoneNumber isEqualToString:recipientId]) { return; } diff --git a/Signal/src/ViewControllers/HomeView/HomeViewController.m b/Signal/src/ViewControllers/HomeView/HomeViewController.m index 4f0a70923c..30aac077a3 100644 --- a/Signal/src/ViewControllers/HomeView/HomeViewController.m +++ b/Signal/src/ViewControllers/HomeView/HomeViewController.m @@ -1078,7 +1078,7 @@ NSString *const kArchiveButtonPseudoGroup = @"kArchiveButtonPseudoGroup"; cellName = [NSString stringWithFormat:@"cell-group-%@", groupThread.groupModel.groupName]; } else { TSContactThread *contactThread = (TSContactThread *)thread.threadRecord; - cellName = [NSString stringWithFormat:@"cell-contact-%@", contactThread.contactIdentifier]; + cellName = [NSString stringWithFormat:@"cell-contact-%@", contactThread.contactAddress.stringForDisplay]; } cell.accessibilityIdentifier = ACCESSIBILITY_IDENTIFIER_WITH_NAME(self, cellName); diff --git a/Signal/src/ViewControllers/NewContactThreadViewController.m b/Signal/src/ViewControllers/NewContactThreadViewController.m index 6c7cc99c65..a5c4ecc21b 100644 --- a/Signal/src/ViewControllers/NewContactThreadViewController.m +++ b/Signal/src/ViewControllers/NewContactThreadViewController.m @@ -875,7 +875,8 @@ NS_ASSUME_NONNULL_BEGIN - (void)newConversationWithRecipientId:(NSString *)recipientId { OWSAssertDebug(recipientId.length > 0); - TSContactThread *thread = [TSContactThread getOrCreateThreadWithContactId:recipientId]; + TSContactThread *thread = + [TSContactThread getOrCreateThreadWithContactAddress:recipientId.transitional_signalServiceAddress]; [self newConversationWithThread:thread]; } diff --git a/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m b/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m index f482645279..4bf0cba14c 100644 --- a/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m +++ b/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m @@ -177,10 +177,15 @@ const CGFloat kIconViewLength = 24; - (NSString *)threadName { NSString *threadName = self.thread.name; - if (self.thread.contactIdentifier && - [threadName isEqualToString:self.thread.contactIdentifier]) { - threadName = - [PhoneNumber bestEffortFormatPartialUserSpecifiedTextToLookLikeAPhoneNumber:self.thread.contactIdentifier]; + + TSContactThread *_Nullable contactThread; + if ([self.thread isKindOfClass:[TSContactThread class]]) { + contactThread = (TSContactThread *)self.thread; + } + + if (contactThread && [threadName isEqualToString:contactThread.contactAddress.phoneNumber]) { + threadName = [PhoneNumber + bestEffortFormatPartialUserSpecifiedTextToLookLikeAPhoneNumber:contactThread.contactAddress.phoneNumber]; } else if (threadName.length == 0 && [self isGroupThread]) { threadName = [MessageStrings newGroupDefaultTitle]; } @@ -367,7 +372,7 @@ const CGFloat kIconViewLength = 24; OWSConversationSettingsViewController *strongSelf = weakSelf; OWSCAssertDebug(strongSelf); TSContactThread *contactThread = (TSContactThread *)strongSelf.thread; - NSString *recipientId = contactThread.contactIdentifier; + NSString *recipientId = contactThread.contactAddress.transitional_phoneNumber; [strongSelf presentAddToContactViewControllerWithRecipientId:recipientId]; }]]; } @@ -1108,7 +1113,9 @@ const CGFloat kIconViewLength = 24; - (void)showVerificationView { - NSString *recipientId = self.thread.contactIdentifier; + OWSAssertDebug([self.thread isKindOfClass:[TSContactThread class]]); + TSContactThread *contactThread = (TSContactThread *)self.thread; + NSString *recipientId = contactThread.contactAddress.transitional_phoneNumber; OWSAssertDebug(recipientId.length > 0); [FingerprintViewController presentFromViewController:self recipientId:recipientId]; @@ -1144,9 +1151,10 @@ const CGFloat kIconViewLength = 24; } TSContactThread *contactThread = (TSContactThread *)self.thread; - [self.contactsViewHelper presentContactViewControllerForRecipientId:contactThread.contactIdentifier - fromViewController:self - editImmediately:YES]; + [self.contactsViewHelper + presentContactViewControllerForRecipientId:contactThread.contactAddress.transitional_phoneNumber + fromViewController:self + editImmediately:YES]; } - (void)presentAddToContactViewControllerWithRecipientId:(NSString *)recipientId @@ -1469,8 +1477,13 @@ const CGFloat kIconViewLength = 24; NSString *recipientId = notification.userInfo[kNSNotificationKey_ProfileRecipientId]; OWSAssertDebug(recipientId.length > 0); - if (recipientId.length > 0 && [self.thread isKindOfClass:[TSContactThread class]] && - [self.thread.contactIdentifier isEqualToString:recipientId]) { + TSContactThread *_Nullable contactThread; + if ([self.thread isKindOfClass:[TSContactThread class]]) { + contactThread = (TSContactThread *)self.thread; + } + + if (recipientId.length > 0 && contactThread && + [contactThread.contactAddress.transitional_phoneNumber isEqualToString:recipientId]) { [self updateTableContents]; } } diff --git a/Signal/src/call/CallService.swift b/Signal/src/call/CallService.swift index b9d8936ee7..33c3c7568d 100644 --- a/Signal/src/call/CallService.swift +++ b/Signal/src/call/CallService.swift @@ -569,7 +569,7 @@ private class SignalCallData: NSObject { */ public func handleReceivedAnswer(thread: TSContactThread, callId: UInt64, sessionDescription: String) { AssertIsOnMainThread() - Logger.info("received call answer for call: \(callId) thread: \(thread.contactIdentifier())") + Logger.info("received call answer for call: \(callId) thread: \(thread.contactAddress)") guard let call = self.call else { Logger.warn("ignoring obsolete call: \(callId)") @@ -613,7 +613,7 @@ private class SignalCallData: NSObject { if call.callRecord == nil { // MJK TODO remove this timestamp param call.callRecord = TSCall(timestamp: NSDate.ows_millisecondTimeStamp(), - withCallNumber: call.thread.contactIdentifier(), + withCallNumber: call.thread.contactAddress.transitional_phoneNumber, callType: .incomingMissed, in: call.thread) } @@ -646,7 +646,7 @@ private class SignalCallData: NSObject { */ private func handleLocalBusyCall(_ call: SignalCall) { AssertIsOnMainThread() - Logger.info("for call: \(call.identifiersForLogs) thread: \(call.thread.contactIdentifier())") + Logger.info("for call: \(call.identifiersForLogs) thread: \(call.thread.contactAddress)") do { let busyBuilder = SSKProtoCallMessageBusy.builder(id: call.signalingId) @@ -665,7 +665,7 @@ private class SignalCallData: NSObject { */ public func handleRemoteBusy(thread: TSContactThread, callId: UInt64) { AssertIsOnMainThread() - Logger.info("for thread: \(thread.contactIdentifier())") + Logger.info("for thread: \(thread.contactAddress)") guard let call = self.call else { Logger.warn("ignoring obsolete call: \(callId)") @@ -677,7 +677,7 @@ private class SignalCallData: NSObject { return } - guard thread.contactIdentifier() == call.remotePhoneNumber else { + guard thread.contactAddress.transitional_phoneNumber == call.remotePhoneNumber else { Logger.warn("ignoring obsolete call") return } @@ -699,11 +699,11 @@ private class SignalCallData: NSObject { BenchEventStart(title: "Incoming Call Connection", eventId: "call-\(callId)") - let newCall = SignalCall.incomingCall(localId: UUID(), remotePhoneNumber: thread.contactIdentifier(), signalingId: callId) + let newCall = SignalCall.incomingCall(localId: UUID(), remotePhoneNumber: thread.contactAddress.transitional_phoneNumber, signalingId: callId) Logger.info("receivedCallOffer: \(newCall.identifiersForLogs)") - let untrustedIdentity = OWSIdentityManager.shared().untrustedIdentityForSending(toRecipientId: thread.contactIdentifier()) + let untrustedIdentity = OWSIdentityManager.shared().untrustedIdentityForSending(toRecipientId: thread.contactAddress.transitional_phoneNumber) guard untrustedIdentity == nil else { Logger.warn("missed a call due to untrusted identity: \(newCall.identifiersForLogs)") @@ -722,7 +722,7 @@ private class SignalCallData: NSObject { // MJK TODO remove this timestamp param let callRecord = TSCall(timestamp: NSDate.ows_millisecondTimeStamp(), - withCallNumber: thread.contactIdentifier(), + withCallNumber: thread.contactAddress.transitional_phoneNumber, callType: .incomingMissedBecauseOfChangedIdentity, in: thread) assert(newCall.callRecord == nil) @@ -901,7 +901,7 @@ private class SignalCallData: NSObject { return } - guard thread.contactIdentifier() == call.thread.contactIdentifier() else { + guard thread.contactAddress.matchesAddress(call.thread.contactAddress) else { Logger.warn("ignoring remote ice update for thread: \(String(describing: thread.uniqueId)) due to thread mismatch. Call already ended?") return } @@ -1070,10 +1070,10 @@ private class SignalCallData: NSObject { return } - guard thread.contactIdentifier() == call.thread.contactIdentifier() else { + guard thread.contactAddress.matchesAddress(call.thread.contactAddress) else { // This can safely be ignored. // We don't want to fail the current call because an old call was slow to send us the hangup message. - Logger.warn("ignoring hangup for thread: \(thread.contactIdentifier()) which is not the current call: \(call.identifiersForLogs)") + Logger.warn("ignoring hangup for thread: \(thread.contactAddress) which is not the current call: \(call.identifiersForLogs)") return } @@ -1317,10 +1317,10 @@ private class SignalCallData: NSObject { self.messageSender.sendPromise(message: callMessage) .done { - Logger.debug("successfully sent hangup call message to \(call.thread.contactIdentifier())") + Logger.debug("successfully sent hangup call message to \(call.thread.contactAddress)") }.catch { error in OWSProdInfo(OWSAnalyticsEvents.callServiceErrorHandleLocalHungupCall(), file: #file, function: #function, line: #line) - Logger.error("failed to send hangup call message to \(call.thread.contactIdentifier()) with error: \(error)") + Logger.error("failed to send hangup call message to \(call.thread.contactAddress) with error: \(error)") }.retainUntilComplete() terminateCall() diff --git a/Signal/src/call/SignalCall.swift b/Signal/src/call/SignalCall.swift index 860c1da1f4..3749a89ceb 100644 --- a/Signal/src/call/SignalCall.swift +++ b/Signal/src/call/SignalCall.swift @@ -160,7 +160,7 @@ protocol CallObserver: class { self.signalingId = signalingId self.state = state self.remotePhoneNumber = remotePhoneNumber - self.thread = TSContactThread.getOrCreateThread(contactId: remotePhoneNumber) + self.thread = TSContactThread.getOrCreateThread(contactAddress: remotePhoneNumber.transitional_signalServiceAddress) self.audioActivity = AudioActivity(audioDescription: "[SignalCall] with \(remotePhoneNumber)", behavior: .call) } diff --git a/Signal/src/call/WebRTCCallMessageHandler.swift b/Signal/src/call/WebRTCCallMessageHandler.swift index 52a294f39a..031a7a56b8 100644 --- a/Signal/src/call/WebRTCCallMessageHandler.swift +++ b/Signal/src/call/WebRTCCallMessageHandler.swift @@ -1,5 +1,5 @@ // -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // import Foundation @@ -12,8 +12,7 @@ public class WebRTCCallMessageHandler: NSObject, OWSCallMessageHandler { // MARK: Initializers @objc - public override init() - { + public override init() { super.init() SwiftSingletons.register(self) @@ -21,18 +20,15 @@ public class WebRTCCallMessageHandler: NSObject, OWSCallMessageHandler { // MARK: - Dependencies - private var messageSender : MessageSender - { + private var messageSender: MessageSender { return SSKEnvironment.shared.messageSender } - private var accountManager : AccountManager - { + private var accountManager: AccountManager { return AppEnvironment.shared.accountManager } - private var callService : CallService - { + private var callService: CallService { return AppEnvironment.shared.callService } @@ -41,21 +37,21 @@ public class WebRTCCallMessageHandler: NSObject, OWSCallMessageHandler { public func receivedOffer(_ offer: SSKProtoCallMessageOffer, from callerId: String) { AssertIsOnMainThread() - let thread = TSContactThread.getOrCreateThread(contactId: callerId) + let thread = TSContactThread.getOrCreateThread(contactAddress: callerId.transitional_signalServiceAddress) self.callService.handleReceivedOffer(thread: thread, callId: offer.id, sessionDescription: offer.sessionDescription) } public func receivedAnswer(_ answer: SSKProtoCallMessageAnswer, from callerId: String) { AssertIsOnMainThread() - let thread = TSContactThread.getOrCreateThread(contactId: callerId) + let thread = TSContactThread.getOrCreateThread(contactAddress: callerId.transitional_signalServiceAddress) self.callService.handleReceivedAnswer(thread: thread, callId: answer.id, sessionDescription: answer.sessionDescription) } public func receivedIceUpdate(_ iceUpdate: SSKProtoCallMessageIceUpdate, from callerId: String) { AssertIsOnMainThread() - let thread = TSContactThread.getOrCreateThread(contactId: callerId) + let thread = TSContactThread.getOrCreateThread(contactAddress: callerId.transitional_signalServiceAddress) // Discrepency between our protobuf's sdpMlineIndex, which is unsigned, // while the RTC iOS API requires a signed int. @@ -67,14 +63,14 @@ public class WebRTCCallMessageHandler: NSObject, OWSCallMessageHandler { public func receivedHangup(_ hangup: SSKProtoCallMessageHangup, from callerId: String) { AssertIsOnMainThread() - let thread = TSContactThread.getOrCreateThread(contactId: callerId) + let thread = TSContactThread.getOrCreateThread(contactAddress: callerId.transitional_signalServiceAddress) self.callService.handleRemoteHangup(thread: thread, callId: hangup.id) } public func receivedBusy(_ busy: SSKProtoCallMessageBusy, from callerId: String) { AssertIsOnMainThread() - let thread = TSContactThread.getOrCreateThread(contactId: callerId) + let thread = TSContactThread.getOrCreateThread(contactAddress: callerId.transitional_signalServiceAddress) self.callService.handleRemoteBusy(thread: thread, callId: busy.id) } diff --git a/Signal/src/environment/SignalApp.m b/Signal/src/environment/SignalApp.m index f174d0fb19..f4534bd8c2 100644 --- a/Signal/src/environment/SignalApp.m +++ b/Signal/src/environment/SignalApp.m @@ -65,7 +65,8 @@ NS_ASSUME_NONNULL_BEGIN __block TSThread *thread = nil; [OWSPrimaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { - thread = [TSContactThread getOrCreateThreadWithContactId:recipientId transaction:transaction]; + thread = [TSContactThread getOrCreateThreadWithContactAddress:recipientId.transitional_signalServiceAddress + transaction:transaction.asAnyWrite]; }]; [self presentConversationForThread:thread action:action animated:(BOOL)isAnimated]; } diff --git a/Signal/src/util/Pastelog.m b/Signal/src/util/Pastelog.m index d76b0d9898..563449a9b8 100644 --- a/Signal/src/util/Pastelog.m +++ b/Signal/src/util/Pastelog.m @@ -593,12 +593,13 @@ typedef void (^DebugLogUploadFailure)(DebugLogUploader *uploader, NSError *error if (![self.tsAccountManager isRegistered]) { return; } - NSString *recipientId = [TSAccountManager localNumber]; + SignalServiceAddress *recipientAddress = TSAccountManager.sharedInstance.localAddress; DispatchMainThreadSafe(^{ __block TSThread *thread = nil; [OWSPrimaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - thread = [TSContactThread getOrCreateThreadWithContactId:recipientId transaction:transaction]; + thread = [TSContactThread getOrCreateThreadWithContactAddress:recipientAddress + transaction:transaction.asAnyWrite]; }]; [self.databaseStorage readWithBlock:^(SDSAnyReadTransaction *transaction) { [ThreadUtil enqueueMessageWithText:url.absoluteString diff --git a/Signal/test/ViewControllers/ConversationViewItemTest.m b/Signal/test/ViewControllers/ConversationViewItemTest.m index 6242f713d2..f838364fdb 100644 --- a/Signal/test/ViewControllers/ConversationViewItemTest.m +++ b/Signal/test/ViewControllers/ConversationViewItemTest.m @@ -26,7 +26,7 @@ - (void)setUp { [super setUp]; - self.thread = [TSContactThread getOrCreateThreadWithContactId:@"+15555555"]; + self.thread = [TSContactThread getOrCreateThreadWithContactAddress:@"+15555555".transitional_signalServiceAddress]; self.conversationStyle = [[ConversationStyle alloc] initWithThread:self.thread]; } diff --git a/Signal/test/util/SearcherTest.swift b/Signal/test/util/SearcherTest.swift index 7da27d0647..f46ec8886b 100644 --- a/Signal/test/util/SearcherTest.swift +++ b/Signal/test/util/SearcherTest.swift @@ -91,10 +91,10 @@ class FullTextSearcherTest: SignalBaseTest { let snackClubGroupThread = TSGroupThread.getOrCreateThread(with: snackModel, transaction: transaction) self.snackClubThread = ThreadViewModel(thread: snackClubGroupThread, transaction: transaction.asAnyWrite) - let aliceContactThread = TSContactThread.getOrCreateThread(withContactId: aliceRecipientId, transaction: transaction) + let aliceContactThread = TSContactThread.getOrCreateThread(withContactAddress: aliceRecipientId.transitional_signalServiceAddress, transaction: transaction.asAnyWrite) self.aliceThread = ThreadViewModel(thread: aliceContactThread, transaction: transaction.asAnyWrite) - let bobContactThread = TSContactThread.getOrCreateThread(withContactId: bobRecipientId, transaction: transaction) + let bobContactThread = TSContactThread.getOrCreateThread(withContactAddress: bobRecipientId.transitional_signalServiceAddress, transaction: transaction.asAnyWrite) self.bobEmptyThread = ThreadViewModel(thread: bobContactThread, transaction: transaction.asAnyWrite) let helloAlice = TSOutgoingMessage(in: aliceContactThread, messageBody: "Hello Alice", attachmentId: nil) diff --git a/SignalMessaging/ViewControllers/SelectThreadViewController.m b/SignalMessaging/ViewControllers/SelectThreadViewController.m index bcc941c100..610f794baa 100644 --- a/SignalMessaging/ViewControllers/SelectThreadViewController.m +++ b/SignalMessaging/ViewControllers/SelectThreadViewController.m @@ -328,8 +328,8 @@ NS_ASSUME_NONNULL_BEGIN __block TSThread *thread = nil; [OWSPrimaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - thread = [TSContactThread getOrCreateThreadWithContactId:signalAccount.recipientAddress.transitional_phoneNumber - transaction:transaction]; + thread = [TSContactThread getOrCreateThreadWithContactAddress:signalAccount.recipientAddress + transaction:transaction.asAnyWrite]; }]; OWSAssertDebug(thread); @@ -354,7 +354,7 @@ NS_ASSUME_NONNULL_BEGIN for (TSThread *thread in threads) { if ([thread isKindOfClass:[TSContactThread class]]) { TSContactThread *contactThread = (TSContactThread *)thread; - [contactIdsToIgnore addObject:contactThread.contactIdentifier]; + [contactIdsToIgnore addObject:contactThread.contactAddress.transitional_phoneNumber]; } } diff --git a/SignalMessaging/ViewModels/ThreadViewModel.swift b/SignalMessaging/ViewModels/ThreadViewModel.swift index 6673ea8168..ec45cfce8f 100644 --- a/SignalMessaging/ViewModels/ThreadViewModel.swift +++ b/SignalMessaging/ViewModels/ThreadViewModel.swift @@ -11,7 +11,6 @@ public class ThreadViewModel: NSObject { @objc public let isGroupThread: Bool @objc public let threadRecord: TSThread @objc public let unreadCount: UInt - @objc public let contactIdentifier: String? @objc public let contactAddress: SignalServiceAddress? @objc public let name: String @objc public let isMuted: Bool @@ -36,10 +35,8 @@ public class ThreadViewModel: NSObject { self.lastMessageDate = lastInteraction?.receivedAtDate() if let contactThread = thread as? TSContactThread { - self.contactIdentifier = contactThread.contactIdentifier() self.contactAddress = contactThread.contactAddress } else { - self.contactIdentifier = nil self.contactAddress = nil } diff --git a/SignalMessaging/Views/AvatarImageView.swift b/SignalMessaging/Views/AvatarImageView.swift index 5495bc2e8c..c18c2f39d3 100644 --- a/SignalMessaging/Views/AvatarImageView.swift +++ b/SignalMessaging/Views/AvatarImageView.swift @@ -86,7 +86,7 @@ public class ConversationAvatarImageView: AvatarImageView { switch thread { case let contactThread as TSContactThread: - self.recipientId = contactThread.contactIdentifier() + self.recipientId = contactThread.contactAddress.transitional_phoneNumber self.groupThreadId = nil case let groupThread as TSGroupThread: self.recipientId = nil diff --git a/SignalMessaging/Views/ContactCellView.m b/SignalMessaging/Views/ContactCellView.m index 01586943a7..c3a851ee68 100644 --- a/SignalMessaging/Views/ContactCellView.m +++ b/SignalMessaging/Views/ContactCellView.m @@ -137,7 +137,8 @@ const CGFloat kContactCellAvatarTextMargin = 12; self.recipientId = recipientId; [self.primaryStorage.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { - self.thread = [TSContactThread getThreadWithContactId:recipientId transaction:transaction]; + self.thread = [TSContactThread getThreadWithContactAddress:recipientId.transitional_signalServiceAddress + transaction:transaction.asAnyRead]; }]; BOOL isNoteToSelf = (IsNoteToSelfEnabled() && [recipientId isEqualToString:self.tsAccountManager.localNumber]); @@ -182,8 +183,12 @@ const CGFloat kContactCellAvatarTextMargin = 12; threadName = [MessageStrings newGroupDefaultTitle]; } - BOOL isNoteToSelf - = (!thread.isGroupThread && [thread.contactIdentifier isEqualToString:self.tsAccountManager.localNumber]); + TSContactThread *_Nullable contactThread; + if ([self.thread isKindOfClass:[TSContactThread class]]) { + contactThread = (TSContactThread *)self.thread; + } + + BOOL isNoteToSelf = contactThread && contactThread.contactAddress.isLocalAddress; if (isNoteToSelf) { threadName = NSLocalizedString(@"NOTE_TO_SELF", @"Label for 1:1 conversation with yourself."); } @@ -195,8 +200,8 @@ const CGFloat kContactCellAvatarTextMargin = 12; }]; self.nameLabel.attributedText = attributedText; - if ([thread isKindOfClass:[TSContactThread class]]) { - self.recipientId = thread.contactIdentifier; + if (contactThread != nil) { + self.recipientId = contactThread.contactAddress.transitional_phoneNumber; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(otherUsersProfileDidChange:) diff --git a/SignalMessaging/contacts/NewAccountDiscovery.swift b/SignalMessaging/contacts/NewAccountDiscovery.swift index 6ceb4a37cc..b8548d7926 100644 --- a/SignalMessaging/contacts/NewAccountDiscovery.swift +++ b/SignalMessaging/contacts/NewAccountDiscovery.swift @@ -53,13 +53,13 @@ public class NewAccountDiscovery: NSObject { // Typically we'd never want to create a "new user" notification if the thread already existed // but for testing we disabled the `forNewThreadsOnly` flag. if forNewThreadsOnly { - guard TSContactThread.getWithContactId(recipient.address.transitional_phoneNumber, anyTransaction: transaction) == nil else { + guard TSContactThread.getWithContactAddress(recipient.address, transaction: transaction) == nil else { owsFailDebug("not creating notification for 'new' user in existing thread.") continue } } - let thread = TSContactThread.getOrCreateThread(withContactId: recipient.address.transitional_phoneNumber, anyTransaction: transaction) + let thread = TSContactThread.getOrCreateThread(withContactAddress: recipient.address, transaction: transaction) let message = TSInfoMessage(timestamp: NSDate.ows_millisecondTimeStamp(), in: thread, messageType: .userJoinedSignal) diff --git a/SignalMessaging/profiles/OWSProfileManager.m b/SignalMessaging/profiles/OWSProfileManager.m index 218fb00564..a15216edc2 100644 --- a/SignalMessaging/profiles/OWSProfileManager.m +++ b/SignalMessaging/profiles/OWSProfileManager.m @@ -857,7 +857,8 @@ typedef void (^ProfileManagerFailureBlock)(NSError *error); [self addUserToProfileWhitelist:recipientId]; } } else { - NSString *recipientId = thread.contactIdentifier; + TSContactThread *contactThread = (TSContactThread *)thread; + NSString *recipientId = contactThread.contactAddress.transitional_phoneNumber; [self addUserToProfileWhitelist:recipientId]; } } @@ -890,7 +891,8 @@ typedef void (^ProfileManagerFailureBlock)(NSError *error); NSData *groupId = groupThread.groupModel.groupId; return [self isGroupIdInProfileWhitelist:groupId]; } else { - NSString *recipientId = thread.contactIdentifier; + TSContactThread *contactThread = (TSContactThread *)thread; + NSString *recipientId = contactThread.contactAddress.transitional_phoneNumber; return [self isUserInProfileWhitelist:recipientId]; } } diff --git a/SignalMessaging/utils/BlockListCache.swift b/SignalMessaging/utils/BlockListCache.swift index 77f0c02954..a96cc0319a 100644 --- a/SignalMessaging/utils/BlockListCache.swift +++ b/SignalMessaging/utils/BlockListCache.swift @@ -1,5 +1,5 @@ // -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // import Foundation @@ -86,7 +86,7 @@ public class BlockListCache: NSObject { switch thread { case let contactThread as TSContactThread: return serialQueue.sync { - blockedRecipientIds.contains(contactThread.contactIdentifier()) + blockedRecipientIds.contains(contactThread.contactAddress.transitional_phoneNumber) } case let groupThread as TSGroupThread: return serialQueue.sync { diff --git a/SignalMessaging/utils/BlockListUIUtils.m b/SignalMessaging/utils/BlockListUIUtils.m index 78810b22bd..bb48f70ee0 100644 --- a/SignalMessaging/utils/BlockListUIUtils.m +++ b/SignalMessaging/utils/BlockListUIUtils.m @@ -29,7 +29,7 @@ typedef void (^BlockAlertCompletionBlock)(UIAlertAction *action); { if ([thread isKindOfClass:[TSContactThread class]]) { TSContactThread *contactThread = (TSContactThread *)thread; - [self showBlockPhoneNumberActionSheet:contactThread.contactIdentifier + [self showBlockPhoneNumberActionSheet:contactThread.contactAddress.transitional_phoneNumber fromViewController:fromViewController blockingManager:blockingManager contactsManager:contactsManager @@ -267,7 +267,7 @@ typedef void (^BlockAlertCompletionBlock)(UIAlertAction *action); { if ([thread isKindOfClass:[TSContactThread class]]) { TSContactThread *contactThread = (TSContactThread *)thread; - [self showUnblockPhoneNumberActionSheet:contactThread.contactIdentifier + [self showUnblockPhoneNumberActionSheet:contactThread.contactAddress.transitional_phoneNumber fromViewController:fromViewController blockingManager:blockingManager contactsManager:contactsManager diff --git a/SignalMessaging/utils/FullTextSearcher.swift b/SignalMessaging/utils/FullTextSearcher.swift index 1b16689c80..106d64cafd 100644 --- a/SignalMessaging/utils/FullTextSearcher.swift +++ b/SignalMessaging/utils/FullTextSearcher.swift @@ -292,7 +292,7 @@ public class FullTextSearcher: NSObject { let searchResult = ConversationSearchResult(thread: threadViewModel, sortKey: sortKey) if let contactThread = thread as? TSContactThread { - let recipientId = contactThread.contactIdentifier() + let recipientId = contactThread.contactAddress.transitional_phoneNumber! existingConversationRecipientIds.insert(recipientId) } @@ -416,7 +416,7 @@ public class FullTextSearcher: NSObject { } private lazy var contactThreadSearcher: Searcher = Searcher { (contactThread: TSContactThread) in - let recipientId = contactThread.contactIdentifier() + let recipientId = contactThread.contactAddress.transitional_phoneNumber! return self.conversationIndexingString(recipientId: recipientId) } diff --git a/SignalMessaging/utils/OWSAvatarBuilder.m b/SignalMessaging/utils/OWSAvatarBuilder.m index bed4d510f7..5679da2913 100644 --- a/SignalMessaging/utils/OWSAvatarBuilder.m +++ b/SignalMessaging/utils/OWSAvatarBuilder.m @@ -1,5 +1,5 @@ // -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // #import "OWSAvatarBuilder.h" @@ -11,6 +11,7 @@ #import "UIColor+OWS.h" #import "UIFont+OWS.h" #import "UIView+OWS.h" +#import NS_ASSUME_NONNULL_BEGIN @@ -30,9 +31,10 @@ typedef void (^OWSAvatarDrawBlock)(CGContextRef context); if ([thread isKindOfClass:[TSContactThread class]]) { TSContactThread *contactThread = (TSContactThread *)thread; ConversationColorName colorName = thread.conversationColorName; - avatarBuilder = [[OWSContactAvatarBuilder alloc] initWithSignalId:contactThread.contactIdentifier - colorName:colorName - diameter:diameter]; + avatarBuilder = + [[OWSContactAvatarBuilder alloc] initWithSignalId:contactThread.contactAddress.transitional_phoneNumber + colorName:colorName + diameter:diameter]; } else if ([thread isKindOfClass:[TSGroupThread class]]) { avatarBuilder = [[OWSGroupAvatarBuilder alloc] initWithThread:(TSGroupThread *)thread diameter:diameter]; } else { diff --git a/SignalServiceKit/src/Contacts/AnyThreadFinder.swift b/SignalServiceKit/src/Contacts/AnyThreadFinder.swift new file mode 100644 index 0000000000..b1eff25b34 --- /dev/null +++ b/SignalServiceKit/src/Contacts/AnyThreadFinder.swift @@ -0,0 +1,48 @@ +// +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. +// + +import Foundation + +@objc +class AnyContactThreadFinder: NSObject { + let grdbAdapter = GRDBContactThreadFinder() + let yapdbAdapter = YAPDBSignalServiceAddressIndex() +} + +extension AnyContactThreadFinder { + @objc(contactThreadForAddress:transaction:) + func contactThread(for address: SignalServiceAddress, transaction: SDSAnyReadTransaction) -> TSContactThread? { + switch transaction.readTransaction { + case .grdbRead(let transaction): + return grdbAdapter.contactThread(for: address, transaction: transaction) + case .yapRead(let transaction): + return yapdbAdapter.fetchOne(for: address, transaction: transaction) + } + } +} + +@objc +class GRDBContactThreadFinder: NSObject { + func contactThread(for address: SignalServiceAddress, transaction: GRDBReadTransaction) -> TSContactThread? { + if let thread = contactThreadForUUID(address.uuid, transaction: transaction) { + return thread + } else if let thread = contactThreadForPhoneNumber(address.phoneNumber, transaction: transaction) { + return thread + } else { + return nil + } + } + + private func contactThreadForUUID(_ uuid: UUID?, transaction: GRDBReadTransaction) -> TSContactThread? { + guard let uuidString = uuid?.uuidString else { return nil } + let sql = "SELECT * FROM \(ThreadRecord.databaseTableName) WHERE \(threadColumn: .contactUUID) = ?" + return TSContactThread.grdbFetchOne(sql: sql, arguments: [uuidString], transaction: transaction) as? TSContactThread + } + + private func contactThreadForPhoneNumber(_ phoneNumber: String?, transaction: GRDBReadTransaction) -> TSContactThread? { + guard let phoneNumber = phoneNumber else { return nil } + let sql = "SELECT * FROM \(ThreadRecord.databaseTableName) WHERE \(threadColumn: .contactPhoneNumber) = ?" + return TSContactThread.grdbFetchOne(sql: sql, arguments: [phoneNumber], transaction: transaction) as? TSContactThread + } +} diff --git a/SignalServiceKit/src/Contacts/SignalAccountFinder.swift b/SignalServiceKit/src/Contacts/SignalAccountFinder.swift index b950203f57..260a89a4db 100644 --- a/SignalServiceKit/src/Contacts/SignalAccountFinder.swift +++ b/SignalServiceKit/src/Contacts/SignalAccountFinder.swift @@ -4,36 +4,26 @@ import Foundation -protocol SignalAccountFinder { - associatedtype ReadTransaction - - func signalAccount(for address: SignalServiceAddress, transaction: ReadTransaction) -> SignalAccount? -} - @objc class AnySignalAccountFinder: NSObject { - typealias ReadTransaction = SDSAnyReadTransaction - let grdbAdapter = GRDBSignalAccountFinder() - let yapdbAdapter = YAPDBSignalAccountFinder() + let yapdbAdapter = YAPDBSignalServiceAddressIndex() } -extension AnySignalAccountFinder: SignalAccountFinder { +extension AnySignalAccountFinder { @objc(signalAccountForAddress:transaction:) func signalAccount(for address: SignalServiceAddress, transaction: SDSAnyReadTransaction) -> SignalAccount? { switch transaction.readTransaction { case .grdbRead(let transaction): return grdbAdapter.signalAccount(for: address, transaction: transaction) case .yapRead(let transaction): - return yapdbAdapter.signalAccount(for: address, transaction: transaction) + return yapdbAdapter.fetchOne(for: address, transaction: transaction) } } } @objc -class GRDBSignalAccountFinder: NSObject, SignalAccountFinder { - typealias ReadTransaction = GRDBReadTransaction - +class GRDBSignalAccountFinder: NSObject { func signalAccount(for address: SignalServiceAddress, transaction: GRDBReadTransaction) -> SignalAccount? { if let account = signalAccountForUUID(address.uuid, transaction: transaction) { return account @@ -56,109 +46,3 @@ class GRDBSignalAccountFinder: NSObject, SignalAccountFinder { return SignalAccount.grdbFetchOne(sql: sql, arguments: [phoneNumber], transaction: transaction) } } - -@objc -class YAPDBSignalAccountFinder: NSObject, SignalAccountFinder { - typealias ReadTransaction = YapDatabaseReadTransaction - - private static let uuidColumn = "recipient_uuid" - private static let phoneNumberColumn = "recipient_phone_number" - private static let phoneNumberIndex = "index_signal_accounts_on_recipientPhoneNumber" - private static let uuidIndex = "index_signal_accounts_on_recipientUUID" - - func signalAccount(for address: SignalServiceAddress, transaction: YapDatabaseReadTransaction) -> SignalAccount? { - if let account = signalAccountForUUID(address.uuid, transaction: transaction) { - return account - } else if let account = signalAccountForPhoneNumber(address.phoneNumber, transaction: transaction) { - return account - } else { - return nil - } - } - - private func signalAccountForUUID(_ uuid: UUID?, transaction: YapDatabaseReadTransaction) -> SignalAccount? { - guard let uuidString = uuid?.uuidString else { return nil } - - guard let ext = transaction.ext(YAPDBSignalAccountFinder.uuidIndex) as? YapDatabaseSecondaryIndexTransaction else { - owsFailDebug("Unexpected transaction type for extension") - return nil - } - - let queryFormat = String(format: "WHERE %@ = \"%@\"", YAPDBSignalAccountFinder.uuidColumn, uuidString) - let query = YapDatabaseQuery(string: queryFormat, parameters: []) - - var matchedAccount: SignalAccount? - - ext.enumerateKeysAndObjects(matching: query) { _, _, object, stop in - guard let account = object as? SignalAccount else { - owsFailDebug("Unexpected object type \(type(of: object))") - return - } - matchedAccount = account - stop.pointee = true - } - - return matchedAccount - } - - private func signalAccountForPhoneNumber(_ phoneNumber: String?, transaction: YapDatabaseReadTransaction) -> SignalAccount? { - guard let phoneNumber = phoneNumber else { return nil } - - guard let ext = transaction.ext(YAPDBSignalAccountFinder.phoneNumberIndex) as? YapDatabaseSecondaryIndexTransaction else { - owsFailDebug("Unexpected transaction type for extension") - return nil - } - - let queryFormat = String(format: "WHERE %@ = \"%@\"", YAPDBSignalAccountFinder.phoneNumberColumn, phoneNumber) - let query = YapDatabaseQuery(string: queryFormat, parameters: []) - - var matchedAccount: SignalAccount? - - ext.enumerateKeysAndObjects(matching: query) { _, _, object, stop in - guard let account = object as? SignalAccount else { - owsFailDebug("Unexpected object type \(type(of: object))") - return - } - matchedAccount = account - stop.pointee = true - } - - return matchedAccount - } - - @objc - static func asyncRegisterDatabaseExtensions(_ storage: OWSStorage) { - storage.asyncRegister(indexUUIDExtension(), withName: uuidIndex) - storage.asyncRegister(indexPhoneNumberExtension(), withName: phoneNumberIndex) - } - - private static func indexUUIDExtension() -> YapDatabaseSecondaryIndex { - let setup = YapDatabaseSecondaryIndexSetup() - setup.addColumn(uuidColumn, with: .text) - - let handler = YapDatabaseSecondaryIndexHandler.withObjectBlock { _, dict, _, _, object in - guard let account = object as? SignalAccount else { - return - } - - dict[uuidColumn] = account.recipientUUID - } - - return YapDatabaseSecondaryIndex(setup: setup, handler: handler, versionTag: "1") - } - - private static func indexPhoneNumberExtension() -> YapDatabaseSecondaryIndex { - let setup = YapDatabaseSecondaryIndexSetup() - setup.addColumn(phoneNumberColumn, with: .text) - - let handler = YapDatabaseSecondaryIndexHandler.withObjectBlock { _, dict, _, _, object in - guard let account = object as? SignalAccount else { - return - } - - dict[phoneNumberColumn] = account.recipientPhoneNumber - } - - return YapDatabaseSecondaryIndex(setup: setup, handler: handler, versionTag: "1") - } -} diff --git a/SignalServiceKit/src/Contacts/SignalRecipientFinder.swift b/SignalServiceKit/src/Contacts/SignalRecipientFinder.swift index 111da46abc..3b56935fe8 100644 --- a/SignalServiceKit/src/Contacts/SignalRecipientFinder.swift +++ b/SignalServiceKit/src/Contacts/SignalRecipientFinder.swift @@ -4,36 +4,26 @@ import Foundation -protocol SignalRecipientFinder { - associatedtype ReadTransaction - - func signalRecipient(for address: SignalServiceAddress, transaction: ReadTransaction) -> SignalRecipient? -} - @objc -public class AnySignalRecipientFinder: NSObject { - typealias ReadTransaction = SDSAnyReadTransaction - +class AnySignalRecipientFinder: NSObject { let grdbAdapter = GRDBSignalRecipientFinder() - let yapdbAdapter = YAPDBSignalRecipientFinder() + let yapdbAdapter = YAPDBSignalServiceAddressIndex() } -extension AnySignalRecipientFinder: SignalRecipientFinder { +extension AnySignalRecipientFinder { @objc(signalRecipientForAddress:transaction:) func signalRecipient(for address: SignalServiceAddress, transaction: SDSAnyReadTransaction) -> SignalRecipient? { switch transaction.readTransaction { case .grdbRead(let transaction): return grdbAdapter.signalRecipient(for: address, transaction: transaction) case .yapRead(let transaction): - return yapdbAdapter.signalRecipient(for: address, transaction: transaction) + return yapdbAdapter.fetchOne(for: address, transaction: transaction) } } } @objc -class GRDBSignalRecipientFinder: NSObject, SignalRecipientFinder { - typealias ReadTransaction = GRDBReadTransaction - +class GRDBSignalRecipientFinder: NSObject { func signalRecipient(for address: SignalServiceAddress, transaction: GRDBReadTransaction) -> SignalRecipient? { if let recipient = signalRecipientForUUID(address.uuid, transaction: transaction) { return recipient @@ -56,109 +46,3 @@ class GRDBSignalRecipientFinder: NSObject, SignalRecipientFinder { return SignalRecipient.grdbFetchOne(sql: sql, arguments: [phoneNumber], transaction: transaction) } } - -@objc -class YAPDBSignalRecipientFinder: NSObject, SignalRecipientFinder { - typealias ReadTransaction = YapDatabaseReadTransaction - - private static let uuidColumn = "recipient_uuid" - private static let phoneNumberColumn = "recipient_phone_number" - private static let phoneNumberIndex = "index_signal_recipients_on_recipientPhoneNumber" - private static let uuidIndex = "index_signal_recipients_on_recipientUUID" - - func signalRecipient(for address: SignalServiceAddress, transaction: YapDatabaseReadTransaction) -> SignalRecipient? { - if let recipient = signalRecipientForUUID(address.uuid, transaction: transaction) { - return recipient - } else if let recipient = signalRecipientForPhoneNumber(address.phoneNumber, transaction: transaction) { - return recipient - } else { - return nil - } - } - - private func signalRecipientForUUID(_ uuid: UUID?, transaction: YapDatabaseReadTransaction) -> SignalRecipient? { - guard let uuidString = uuid?.uuidString else { return nil } - - guard let ext = transaction.ext(YAPDBSignalRecipientFinder.uuidIndex) as? YapDatabaseSecondaryIndexTransaction else { - owsFailDebug("Unexpected transaction type for extension") - return nil - } - - let queryFormat = String(format: "WHERE %@ = \"%@\"", YAPDBSignalRecipientFinder.uuidColumn, uuidString) - let query = YapDatabaseQuery(string: queryFormat, parameters: []) - - var matchedAccount: SignalRecipient? - - ext.enumerateKeysAndObjects(matching: query) { _, _, object, stop in - guard let recipient = object as? SignalRecipient else { - owsFailDebug("Unexpected object type \(type(of: object))") - return - } - matchedAccount = recipient - stop.pointee = true - } - - return matchedAccount - } - - private func signalRecipientForPhoneNumber(_ phoneNumber: String?, transaction: YapDatabaseReadTransaction) -> SignalRecipient? { - guard let phoneNumber = phoneNumber else { return nil } - - guard let ext = transaction.ext(YAPDBSignalRecipientFinder.phoneNumberIndex) as? YapDatabaseSecondaryIndexTransaction else { - owsFailDebug("Unexpected transaction type for extension") - return nil - } - - let queryFormat = String(format: "WHERE %@ = \"%@\"", YAPDBSignalRecipientFinder.phoneNumberColumn, phoneNumber) - let query = YapDatabaseQuery(string: queryFormat, parameters: []) - - var matchedAccount: SignalRecipient? - - ext.enumerateKeysAndObjects(matching: query) { _, _, object, stop in - guard let recipient = object as? SignalRecipient else { - owsFailDebug("Unexpected object type \(type(of: object))") - return - } - matchedAccount = recipient - stop.pointee = true - } - - return matchedAccount - } - - @objc - static func asyncRegisterDatabaseExtensions(_ storage: OWSStorage) { - storage.asyncRegister(indexUUIDExtension(), withName: uuidIndex) - storage.asyncRegister(indexPhoneNumberExtension(), withName: phoneNumberIndex) - } - - private static func indexUUIDExtension() -> YapDatabaseSecondaryIndex { - let setup = YapDatabaseSecondaryIndexSetup() - setup.addColumn(uuidColumn, with: .text) - - let handler = YapDatabaseSecondaryIndexHandler.withObjectBlock { _, dict, _, _, object in - guard let recipient = object as? SignalRecipient else { - return - } - - dict[uuidColumn] = recipient.recipientUUID - } - - return YapDatabaseSecondaryIndex(setup: setup, handler: handler, versionTag: "1") - } - - private static func indexPhoneNumberExtension() -> YapDatabaseSecondaryIndex { - let setup = YapDatabaseSecondaryIndexSetup() - setup.addColumn(phoneNumberColumn, with: .text) - - let handler = YapDatabaseSecondaryIndexHandler.withObjectBlock { _, dict, _, _, object in - guard let recipient = object as? SignalRecipient else { - return - } - - dict[phoneNumberColumn] = recipient.recipientPhoneNumber - } - - return YapDatabaseSecondaryIndex(setup: setup, handler: handler, versionTag: "1") - } -} diff --git a/SignalServiceKit/src/Contacts/TSThread+SDS.swift b/SignalServiceKit/src/Contacts/TSThread+SDS.swift index cc0e5440e4..7cf825b587 100644 --- a/SignalServiceKit/src/Contacts/TSThread+SDS.swift +++ b/SignalServiceKit/src/Contacts/TSThread+SDS.swift @@ -37,6 +37,9 @@ public struct ThreadRecord: SDSRecord { public let shouldThreadBeVisible: Bool // Subclass properties + public let contactPhoneNumber: String? + public let contactThreadSchemaVersion: UInt? + public let contactUUID: String? public let groupModel: Data? public let hasDismissedOffers: Bool? @@ -53,6 +56,9 @@ public struct ThreadRecord: SDSRecord { case messageDraft case mutedUntilDate case shouldThreadBeVisible + case contactPhoneNumber + case contactThreadSchemaVersion + case contactUUID case groupModel case hasDismissedOffers } @@ -99,6 +105,9 @@ extension TSThread { let messageDraft: String? = record.messageDraft let mutedUntilDate: Date? = record.mutedUntilDate let shouldThreadBeVisible: Bool = record.shouldThreadBeVisible + let contactPhoneNumber: String? = record.contactPhoneNumber + let contactThreadSchemaVersion: UInt = try SDSDeserialization.required(record.contactThreadSchemaVersion, name: "contactThreadSchemaVersion") + let contactUUID: String? = record.contactUUID let hasDismissedOffers: Bool = try SDSDeserialization.required(record.hasDismissedOffers, name: "hasDismissedOffers") return TSContactThread(uniqueId: uniqueId, @@ -111,6 +120,9 @@ extension TSThread { messageDraft: messageDraft, mutedUntilDate: mutedUntilDate, shouldThreadBeVisible: shouldThreadBeVisible, + contactPhoneNumber: contactPhoneNumber, + contactThreadSchemaVersion: contactThreadSchemaVersion, + contactUUID: contactUUID, hasDismissedOffers: hasDismissedOffers) case .groupThread: @@ -215,8 +227,11 @@ extension TSThreadSerializer { static let mutedUntilDateColumn = SDSColumnMetadata(columnName: "mutedUntilDate", columnType: .int64, isOptional: true, columnIndex: 10) static let shouldThreadBeVisibleColumn = SDSColumnMetadata(columnName: "shouldThreadBeVisible", columnType: .int, columnIndex: 11) // Subclass properties - static let groupModelColumn = SDSColumnMetadata(columnName: "groupModel", columnType: .blob, isOptional: true, columnIndex: 12) - static let hasDismissedOffersColumn = SDSColumnMetadata(columnName: "hasDismissedOffers", columnType: .int, isOptional: true, columnIndex: 13) + static let contactPhoneNumberColumn = SDSColumnMetadata(columnName: "contactPhoneNumber", columnType: .unicodeString, isOptional: true, columnIndex: 12) + static let contactThreadSchemaVersionColumn = SDSColumnMetadata(columnName: "contactThreadSchemaVersion", columnType: .int64, isOptional: true, columnIndex: 13) + static let contactUUIDColumn = SDSColumnMetadata(columnName: "contactUUID", columnType: .unicodeString, isOptional: true, columnIndex: 14) + static let groupModelColumn = SDSColumnMetadata(columnName: "groupModel", columnType: .blob, isOptional: true, columnIndex: 15) + static let hasDismissedOffersColumn = SDSColumnMetadata(columnName: "hasDismissedOffers", columnType: .int, isOptional: true, columnIndex: 16) // TODO: We should decide on a naming convention for // tables that store models. @@ -233,6 +248,9 @@ extension TSThreadSerializer { messageDraftColumn, mutedUntilDateColumn, shouldThreadBeVisibleColumn, + contactPhoneNumberColumn, + contactThreadSchemaVersionColumn, + contactUUIDColumn, groupModelColumn, hasDismissedOffersColumn ]) @@ -571,9 +589,12 @@ class TSThreadSerializer: SDSSerializer { let shouldThreadBeVisible: Bool = model.shouldThreadBeVisible // Subclass properties + let contactPhoneNumber: String? = nil + let contactThreadSchemaVersion: UInt? = nil + let contactUUID: String? = nil let groupModel: Data? = nil let hasDismissedOffers: Bool? = nil - return ThreadRecord(id: id, recordType: recordType, uniqueId: uniqueId, archivalDate: archivalDate, archivedAsOfMessageSortId: archivedAsOfMessageSortId, conversationColorName: conversationColorName, creationDate: creationDate, isArchivedByLegacyTimestampForSorting: isArchivedByLegacyTimestampForSorting, lastMessageDate: lastMessageDate, messageDraft: messageDraft, mutedUntilDate: mutedUntilDate, shouldThreadBeVisible: shouldThreadBeVisible, groupModel: groupModel, hasDismissedOffers: hasDismissedOffers) + return ThreadRecord(id: id, recordType: recordType, uniqueId: uniqueId, archivalDate: archivalDate, archivedAsOfMessageSortId: archivedAsOfMessageSortId, conversationColorName: conversationColorName, creationDate: creationDate, isArchivedByLegacyTimestampForSorting: isArchivedByLegacyTimestampForSorting, lastMessageDate: lastMessageDate, messageDraft: messageDraft, mutedUntilDate: mutedUntilDate, shouldThreadBeVisible: shouldThreadBeVisible, contactPhoneNumber: contactPhoneNumber, contactThreadSchemaVersion: contactThreadSchemaVersion, contactUUID: contactUUID, groupModel: groupModel, hasDismissedOffers: hasDismissedOffers) } } diff --git a/SignalServiceKit/src/Contacts/TSThread.h b/SignalServiceKit/src/Contacts/TSThread.h index 20f6d8b875..4fb25ce4cb 100644 --- a/SignalServiceKit/src/Contacts/TSThread.h +++ b/SignalServiceKit/src/Contacts/TSThread.h @@ -83,12 +83,6 @@ NS_SWIFT_NAME(init(uniqueId:archivalDate:archivedAsOfMessageSortId:conversationC + (ConversationColorName)stableColorNameForNewConversationWithString:(NSString *)colorSeed; @property (class, nonatomic, readonly) NSArray *conversationColorNames; -/** - * @returns - * Signal Id (e164) of the contact if it's a contact thread. - */ -- (nullable NSString *)contactIdentifier; - /** * @returns recipientId for each recipient in the thread */ diff --git a/SignalServiceKit/src/Contacts/TSThread.m b/SignalServiceKit/src/Contacts/TSThread.m index aac8291dd6..2a31c4e502 100644 --- a/SignalServiceKit/src/Contacts/TSThread.m +++ b/SignalServiceKit/src/Contacts/TSThread.m @@ -85,13 +85,10 @@ ConversationColorName const kConversationColorName_Default = ConversationColorNa _creationDate = [NSDate date]; _messageDraft = nil; - NSString *_Nullable contactId = self.contactIdentifier; - if (contactId.length > 0) { - // To be consistent with colors synced to desktop - _conversationColorName = [self.class stableColorNameForNewConversationWithString:contactId]; - } else { - _conversationColorName = [self.class stableColorNameForNewConversationWithString:self.uniqueId]; - } + // This is overriden in TSContactThread to use the phone number when available + // We can't use self.colorSeed here because the subclass hasn't done its + // initializing work yet to set it up. + _conversationColorName = [self.class stableColorNameForNewConversationWithString:uniqueId]; } return self; @@ -154,14 +151,7 @@ isArchivedByLegacyTimestampForSorting:(BOOL)isArchivedByLegacyTimestampForSortin } if (_conversationColorName.length == 0) { - NSString *_Nullable colorSeed = self.contactIdentifier; - if (colorSeed.length > 0) { - // group threads - colorSeed = self.uniqueId; - } - - // To be consistent with colors synced to desktop - ConversationColorName colorName = [self.class stableColorNameForLegacyConversationWithString:colorSeed]; + ConversationColorName colorName = [self.class stableColorNameForLegacyConversationWithString:self.colorSeed]; OWSAssertDebug(colorName); _conversationColorName = colorName; @@ -246,11 +236,12 @@ isArchivedByLegacyTimestampForSorting:(BOOL)isArchivedByLegacyTimestampForSortin - (BOOL)isNoteToSelf { - if (!IsNoteToSelfEnabled()) { - return NO; - } - return (!self.isGroupThread && self.contactIdentifier != nil && - [self.contactIdentifier isEqualToString:self.tsAccountManager.localNumber]); + return NO; +} + +- (NSString *)colorSeed +{ + return self.uniqueId; } #pragma mark - To be subclassed. @@ -261,12 +252,6 @@ isArchivedByLegacyTimestampForSorting:(BOOL)isArchivedByLegacyTimestampForSortin return NO; } -// Override in ContactThread -- (nullable NSString *)contactIdentifier -{ - return nil; -} - - (NSString *)name { OWSAbstractMethod(); diff --git a/SignalServiceKit/src/Contacts/Threads/TSContactThread+SDS.swift b/SignalServiceKit/src/Contacts/Threads/TSContactThread+SDS.swift index 3e80f08b1d..2b0ce493c5 100644 --- a/SignalServiceKit/src/Contacts/Threads/TSContactThread+SDS.swift +++ b/SignalServiceKit/src/Contacts/Threads/TSContactThread+SDS.swift @@ -43,9 +43,12 @@ class TSContactThreadSerializer: SDSSerializer { let shouldThreadBeVisible: Bool = model.shouldThreadBeVisible // Subclass properties + let contactPhoneNumber: String? = model.contactPhoneNumber + let contactThreadSchemaVersion: UInt? = model.contactThreadSchemaVersion + let contactUUID: String? = model.contactUUID let groupModel: Data? = nil let hasDismissedOffers: Bool? = model.hasDismissedOffers - return ThreadRecord(id: id, recordType: recordType, uniqueId: uniqueId, archivalDate: archivalDate, archivedAsOfMessageSortId: archivedAsOfMessageSortId, conversationColorName: conversationColorName, creationDate: creationDate, isArchivedByLegacyTimestampForSorting: isArchivedByLegacyTimestampForSorting, lastMessageDate: lastMessageDate, messageDraft: messageDraft, mutedUntilDate: mutedUntilDate, shouldThreadBeVisible: shouldThreadBeVisible, groupModel: groupModel, hasDismissedOffers: hasDismissedOffers) + return ThreadRecord(id: id, recordType: recordType, uniqueId: uniqueId, archivalDate: archivalDate, archivedAsOfMessageSortId: archivedAsOfMessageSortId, conversationColorName: conversationColorName, creationDate: creationDate, isArchivedByLegacyTimestampForSorting: isArchivedByLegacyTimestampForSorting, lastMessageDate: lastMessageDate, messageDraft: messageDraft, mutedUntilDate: mutedUntilDate, shouldThreadBeVisible: shouldThreadBeVisible, contactPhoneNumber: contactPhoneNumber, contactThreadSchemaVersion: contactThreadSchemaVersion, contactUUID: contactUUID, groupModel: groupModel, hasDismissedOffers: hasDismissedOffers) } } diff --git a/SignalServiceKit/src/Contacts/Threads/TSContactThread.h b/SignalServiceKit/src/Contacts/Threads/TSContactThread.h index 48abb94546..b59fb1f870 100644 --- a/SignalServiceKit/src/Contacts/Threads/TSContactThread.h +++ b/SignalServiceKit/src/Contacts/Threads/TSContactThread.h @@ -6,8 +6,6 @@ NS_ASSUME_NONNULL_BEGIN -extern NSString *const TSContactThreadPrefix; - @class SignalServiceAddress; @interface TSContactThread : TSThread @@ -28,48 +26,45 @@ isArchivedByLegacyTimestampForSorting:(BOOL)isArchivedByLegacyTimestampForSortin messageDraft:(nullable NSString *)messageDraft mutedUntilDate:(nullable NSDate *)mutedUntilDate shouldThreadBeVisible:(BOOL)shouldThreadBeVisible + contactPhoneNumber:(nullable NSString *)contactPhoneNumber + contactThreadSchemaVersion:(NSUInteger)contactThreadSchemaVersion + contactUUID:(nullable NSString *)contactUUID hasDismissedOffers:(BOOL)hasDismissedOffers -NS_SWIFT_NAME(init(uniqueId:archivalDate:archivedAsOfMessageSortId:conversationColorName:creationDate:isArchivedByLegacyTimestampForSorting:lastMessageDate:messageDraft:mutedUntilDate:shouldThreadBeVisible:hasDismissedOffers:)); +NS_SWIFT_NAME(init(uniqueId:archivalDate:archivedAsOfMessageSortId:conversationColorName:creationDate:isArchivedByLegacyTimestampForSorting:lastMessageDate:messageDraft:mutedUntilDate:shouldThreadBeVisible:contactPhoneNumber:contactThreadSchemaVersion:contactUUID:hasDismissedOffers:)); // clang-format on // --- CODE GENERATION MARKER // TODO: We might want to make this initializer private once we -// convert getOrCreateThreadWithContactId to take "any" transaction. -- (instancetype)initWithContactId:(NSString *)contactId; - -@property (nonatomic) BOOL hasDismissedOffers; - -+ (instancetype)getOrCreateThreadWithContactId:(NSString *)contactId NS_SWIFT_NAME(getOrCreateThread(contactId:)); - -+ (instancetype)getOrCreateThreadWithContactId:(NSString *)contactId - transaction:(YapDatabaseReadWriteTransaction *)transaction; - -+ (instancetype)getOrCreateThreadWithContactId:(NSString *)contactId - anyTransaction:(SDSAnyWriteTransaction *)transaction; - -// Unlike getOrCreateThreadWithContactId, this will _NOT_ create a thread if one does not already exist. -+ (nullable instancetype)getThreadWithContactId:(NSString *)contactId transaction:(YapDatabaseReadTransaction *)transaction; -+ (nullable instancetype)getThreadWithContactId:(NSString *)contactId - anyTransaction:(SDSAnyReadTransaction *)transaction; - -- (NSString *)contactIdentifier; +// convert getOrCreateThreadWithContactAddress to take "any" transaction. +- (instancetype)initWithContactAddress:(SignalServiceAddress *)contactAddress; @property (nonatomic, readonly) SignalServiceAddress *contactAddress; -+ (NSString *)contactIdFromThreadId:(NSString *)threadId; +@property (nonatomic) BOOL hasDismissedOffers; -// This is only exposed for tests. -#ifdef DEBUG -+ (NSString *)threadIdFromContactId:(NSString *)contactId; -#endif ++ (instancetype)getOrCreateThreadWithContactAddress:(SignalServiceAddress *)contactAddress + NS_SWIFT_NAME(getOrCreateThread(contactAddress:)); + ++ (instancetype)getOrCreateThreadWithContactAddress:(SignalServiceAddress *)contactAddress + transaction:(SDSAnyWriteTransaction *)transaction; + +// Unlike getOrCreateThreadWithContactAddress, this will _NOT_ create a thread if one does not already exist. ++ (nullable instancetype)getThreadWithContactAddress:(SignalServiceAddress *)contactAddress + transaction:(SDSAnyReadTransaction *)transaction; + ++ (nullable SignalServiceAddress *)contactAddressFromThreadId:(NSString *)threadId + transaction:(SDSAnyReadTransaction *)transaction; + +// This is only ever used from migration from a pre-UUID world to a UUID world ++ (nullable NSString *)legacyContactPhoneNumberFromThreadId:(NSString *)threadId; // This method can be used to get the conversation color for a given // recipient without using a read/write transaction to create a // contact thread. -+ (NSString *)conversationColorNameForRecipientId:(NSString *)recipientId - transaction:(SDSAnyReadTransaction *)transaction; ++ (NSString *)conversationColorNameForContactAddress:(SignalServiceAddress *)address + transaction:(SDSAnyReadTransaction *)transaction; @end diff --git a/SignalServiceKit/src/Contacts/Threads/TSContactThread.m b/SignalServiceKit/src/Contacts/Threads/TSContactThread.m index 7efa83bed9..38fca9c7fd 100644 --- a/SignalServiceKit/src/Contacts/Threads/TSContactThread.m +++ b/SignalServiceKit/src/Contacts/Threads/TSContactThread.m @@ -9,15 +9,40 @@ #import "OWSIdentityManager.h" #import "SSKEnvironment.h" #import -#import -#import NS_ASSUME_NONNULL_BEGIN -NSString *const TSContactThreadPrefix = @"c"; +NSString *const TSContactThreadLegacyPrefix = @"c"; +NSUInteger const TSContactThreadSchemaVersion = 1; + +@interface TSContactThread () + +@property (nonatomic, nullable, readonly) NSString *contactPhoneNumber; +@property (nonatomic, nullable, readonly) NSString *contactUUID; +@property (nonatomic, readonly) NSUInteger contactThreadSchemaVersion; + +// From TSThread +@property (nonatomic) NSString *conversationColorName; + +@end @implementation TSContactThread +#pragma mark - Dependencies + ++ (SDSDatabaseStorage *)databaseStorage +{ + return SDSDatabaseStorage.shared; +} + ++ (AnyContactThreadFinder *)threadFinder +{ + return [AnyContactThreadFinder new]; +} + + +#pragma mark - + // --- CODE GENERATION MARKER // This snippet is generated by /Scripts/sds_codegen/sds_generate.py. Do not manually edit it, instead run `sds_codegen.sh`. @@ -34,6 +59,9 @@ isArchivedByLegacyTimestampForSorting:(BOOL)isArchivedByLegacyTimestampForSortin messageDraft:(nullable NSString *)messageDraft mutedUntilDate:(nullable NSDate *)mutedUntilDate shouldThreadBeVisible:(BOOL)shouldThreadBeVisible + contactPhoneNumber:(nullable NSString *)contactPhoneNumber + contactThreadSchemaVersion:(NSUInteger)contactThreadSchemaVersion + contactUUID:(nullable NSString *)contactUUID hasDismissedOffers:(BOOL)hasDismissedOffers { self = [super initWithUniqueId:uniqueId @@ -51,6 +79,9 @@ isArchivedByLegacyTimestampForSorting:isArchivedByLegacyTimestampForSorting return self; } + _contactPhoneNumber = contactPhoneNumber; + _contactThreadSchemaVersion = contactThreadSchemaVersion; + _contactUUID = contactUUID; _hasDismissedOffers = hasDismissedOffers; return self; @@ -60,93 +91,108 @@ isArchivedByLegacyTimestampForSorting:isArchivedByLegacyTimestampForSorting // --- CODE GENERATION MARKER -- (instancetype)initWithContactId:(NSString *)contactId { - NSString *uniqueIdentifier = [[self class] threadIdFromContactId:contactId]; +- (nullable instancetype)initWithCoder:(NSCoder *)coder +{ + self = [super initWithCoder:coder]; + if (self) { + // Migrate legacy threads to store phone number and UUID + if (_contactThreadSchemaVersion < 1) { + _contactPhoneNumber = [[self class] legacyContactPhoneNumberFromThreadId:self.uniqueId]; + } - OWSAssertDebug(contactId.length > 0); + _contactThreadSchemaVersion = TSContactThreadSchemaVersion; + } + return self; +} - self = [super initWithUniqueId:uniqueIdentifier]; +- (instancetype)initWithContactAddress:(SignalServiceAddress *)contactAddress +{ + OWSAssertDebug(contactAddress.isValid); + + if (self = [super init]) { + _contactUUID = contactAddress.uuidString; + _contactPhoneNumber = contactAddress.phoneNumber; + _contactThreadSchemaVersion = TSContactThreadSchemaVersion; + + // Reset the conversation color to use our phone number, if available. The super initializer just uses the + // uniqueId + self.conversationColorName = + [[self class] stableColorNameForNewConversationWithString:contactAddress.stringForDisplay]; + } return self; } -+ (instancetype)getOrCreateThreadWithContactId:(NSString *)contactId - transaction:(YapDatabaseReadWriteTransaction *)transaction { - OWSAssertDebug(contactId.length > 0); - - TSContactThread *thread = - [self fetchObjectWithUniqueID:[self threadIdFromContactId:contactId] transaction:transaction]; - - if (!thread) { - thread = [[TSContactThread alloc] initWithContactId:contactId]; - [thread saveWithTransaction:transaction]; - } - - return thread; -} - -+ (instancetype)getOrCreateThreadWithContactId:(NSString *)contactId - anyTransaction:(SDSAnyWriteTransaction *)transaction ++ (instancetype)getOrCreateThreadWithContactAddress:(SignalServiceAddress *)contactAddress + transaction:(SDSAnyWriteTransaction *)transaction { - OWSAssertDebug(contactId.length > 0); + OWSAssertDebug(contactAddress.isValid); - NSString *uniqueId = [self threadIdFromContactId:contactId]; - TSContactThread *thread = (TSContactThread *)[self anyFetchWithUniqueId:uniqueId transaction:transaction]; + TSContactThread *thread = [self.threadFinder contactThreadForAddress:contactAddress transaction:transaction]; if (!thread) { - thread = [[TSContactThread alloc] initWithContactId:contactId]; + thread = [[TSContactThread alloc] initWithContactAddress:contactAddress]; [thread anyInsertWithTransaction:transaction]; } return thread; } -+ (instancetype)getOrCreateThreadWithContactId:(NSString *)contactId ++ (instancetype)getOrCreateThreadWithContactAddress:(SignalServiceAddress *)contactAddress { - OWSAssertDebug(contactId.length > 0); + OWSAssertDebug(contactAddress.isValid); __block TSContactThread *thread; - [[self dbReadWriteConnection] readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - thread = [self getOrCreateThreadWithContactId:contactId transaction:transaction]; + [self.databaseStorage writeWithBlock:^(SDSAnyWriteTransaction *transaction) { + thread = [self getOrCreateThreadWithContactAddress:contactAddress transaction:transaction]; }]; return thread; } -+ (nullable instancetype)getThreadWithContactId:(NSString *)contactId - transaction:(YapDatabaseReadTransaction *)transaction ++ (nullable instancetype)getThreadWithContactAddress:(SignalServiceAddress *)contactAddress + transaction:(SDSAnyReadTransaction *)transaction { - return [TSContactThread fetchObjectWithUniqueID:[self threadIdFromContactId:contactId] transaction:transaction]; -} - -+ (nullable instancetype)getThreadWithContactId:(NSString *)contactId - anyTransaction:(SDSAnyReadTransaction *)transaction -{ - return (TSContactThread *)[TSContactThread anyFetchWithUniqueId:[self threadIdFromContactId:contactId] - transaction:transaction]; -} - -- (NSString *)contactIdentifier { - return [[self class] contactIdFromThreadId:self.uniqueId]; + return [self.threadFinder contactThreadForAddress:contactAddress transaction:transaction]; } - (SignalServiceAddress *)contactAddress { - return [[SignalServiceAddress alloc] initWithPhoneNumber:self.contactIdentifier]; + return [[SignalServiceAddress alloc] initWithUuidString:self.contactUUID phoneNumber:self.contactPhoneNumber]; } - (NSArray *)recipientIdentifiers { - return @[self.contactIdentifier]; + return @[ self.contactAddress.transitional_phoneNumber ]; } - (BOOL)isGroupThread { - return false; + return NO; +} + +- (BOOL)isNoteToSelf +{ + if (!IsNoteToSelfEnabled()) { + return NO; + } + + return self.contactAddress.isLocalAddress; +} + +- (NSString *)colorSeed +{ + NSString *_Nullable phoneNumber = self.contactAddress.phoneNumber; + if (!phoneNumber) { + phoneNumber = [[self class] legacyContactPhoneNumberFromThreadId:self.uniqueId]; + } + + return phoneNumber ?: self.uniqueId; } - (BOOL)hasSafetyNumbers { - return !![[OWSIdentityManager sharedManager] identityKeyForRecipientId:self.contactIdentifier]; + return !! + [[OWSIdentityManager sharedManager] identityKeyForRecipientId:self.contactAddress.transitional_phoneNumber]; } // TODO deprecate this? seems weird to access the displayName in the DB model @@ -155,25 +201,34 @@ isArchivedByLegacyTimestampForSorting:isArchivedByLegacyTimestampForSorting return [SSKEnvironment.shared.contactsManager displayNameForAddress:self.contactAddress]; } -+ (NSString *)threadIdFromContactId:(NSString *)contactId { - return [TSContactThreadPrefix stringByAppendingString:contactId]; ++ (nullable SignalServiceAddress *)contactAddressFromThreadId:(NSString *)threadId + transaction:(SDSAnyReadTransaction *)transaction +{ + TSContactThread *_Nullable contactThread = (TSContactThread *)[TSContactThread anyFetchWithUniqueId:threadId + transaction:transaction]; + return contactThread.contactAddress; } -+ (NSString *)contactIdFromThreadId:(NSString *)threadId { ++ (nullable NSString *)legacyContactPhoneNumberFromThreadId:(NSString *)threadId +{ + if (![threadId hasPrefix:TSContactThreadLegacyPrefix]) { + return nil; + } + return [threadId substringWithRange:NSMakeRange(1, threadId.length - 1)]; } -+ (NSString *)conversationColorNameForRecipientId:(NSString *)recipientId - transaction:(SDSAnyReadTransaction *)transaction ++ (NSString *)conversationColorNameForContactAddress:(SignalServiceAddress *)address + transaction:(SDSAnyReadTransaction *)transaction { - OWSAssertDebug(recipientId.length > 0); + OWSAssertDebug(address); - TSContactThread *_Nullable contactThread = - [TSContactThread getThreadWithContactId:recipientId anyTransaction:transaction]; + TSContactThread *_Nullable contactThread = [TSContactThread getThreadWithContactAddress:address + transaction:transaction]; if (contactThread) { return contactThread.conversationColorName; } - return [self stableColorNameForNewConversationWithString:recipientId]; + return [self stableColorNameForNewConversationWithString:address.stringForDisplay]; } @end diff --git a/SignalServiceKit/src/Contacts/Threads/TSGroupThread+SDS.swift b/SignalServiceKit/src/Contacts/Threads/TSGroupThread+SDS.swift index 8ebe9a2b7c..3106938cda 100644 --- a/SignalServiceKit/src/Contacts/Threads/TSGroupThread+SDS.swift +++ b/SignalServiceKit/src/Contacts/Threads/TSGroupThread+SDS.swift @@ -43,9 +43,12 @@ class TSGroupThreadSerializer: SDSSerializer { let shouldThreadBeVisible: Bool = model.shouldThreadBeVisible // Subclass properties + let contactPhoneNumber: String? = nil + let contactThreadSchemaVersion: UInt? = nil + let contactUUID: String? = nil let groupModel: Data? = optionalArchive(model.groupModel) let hasDismissedOffers: Bool? = nil - return ThreadRecord(id: id, recordType: recordType, uniqueId: uniqueId, archivalDate: archivalDate, archivedAsOfMessageSortId: archivedAsOfMessageSortId, conversationColorName: conversationColorName, creationDate: creationDate, isArchivedByLegacyTimestampForSorting: isArchivedByLegacyTimestampForSorting, lastMessageDate: lastMessageDate, messageDraft: messageDraft, mutedUntilDate: mutedUntilDate, shouldThreadBeVisible: shouldThreadBeVisible, groupModel: groupModel, hasDismissedOffers: hasDismissedOffers) + return ThreadRecord(id: id, recordType: recordType, uniqueId: uniqueId, archivalDate: archivalDate, archivedAsOfMessageSortId: archivedAsOfMessageSortId, conversationColorName: conversationColorName, creationDate: creationDate, isArchivedByLegacyTimestampForSorting: isArchivedByLegacyTimestampForSorting, lastMessageDate: lastMessageDate, messageDraft: messageDraft, mutedUntilDate: mutedUntilDate, shouldThreadBeVisible: shouldThreadBeVisible, contactPhoneNumber: contactPhoneNumber, contactThreadSchemaVersion: contactThreadSchemaVersion, contactUUID: contactUUID, groupModel: groupModel, hasDismissedOffers: hasDismissedOffers) } } diff --git a/SignalServiceKit/src/Contacts/YAPDBSignalServiceAddressExtension.swift b/SignalServiceKit/src/Contacts/YAPDBSignalServiceAddressExtension.swift new file mode 100644 index 0000000000..07f9b7d97a --- /dev/null +++ b/SignalServiceKit/src/Contacts/YAPDBSignalServiceAddressExtension.swift @@ -0,0 +1,151 @@ +// +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. +// + +import Foundation + +protocol YAPDBSignalServiceAddressIndexable: class { + var indexableUUIDValue: String? { get } + var indexablePhoneNumberValue: String? { get } +} + +extension SignalAccount: YAPDBSignalServiceAddressIndexable { + var indexableUUIDValue: String? { return recipientUUID } + var indexablePhoneNumberValue: String? { return recipientPhoneNumber } +} + +extension SignalRecipient: YAPDBSignalServiceAddressIndexable { + var indexableUUIDValue: String? { return recipientUUID } + var indexablePhoneNumberValue: String? { return recipientPhoneNumber } +} + +extension TSContactThread: YAPDBSignalServiceAddressIndexable { + var indexableUUIDValue: String? { return contactUUID } + var indexablePhoneNumberValue: String? { return contactPhoneNumber } +} + +@objc +class YAPDBSignalServiceAddressIndex: NSObject { + private static let indexableTypes: [YAPDBSignalServiceAddressIndexable.Type] = [ + SignalAccount.self, + SignalRecipient.self, + TSContactThread.self + ] + + private static let uuidKey = "uuidKey" + private static let phoneNumberKey = "phoneNumberKey" + private static let classNameKey = "classNameKey" + + private static let phoneNumberIndexName = "index_on_recipientPhoneNumber" + private static let uuidIndexName = "index_on_recipientUUID" + + func fetchOne(for address: SignalServiceAddress, transaction: YapDatabaseReadTransaction) -> T? { + if let result: T = fetchOneForUUID(address.uuid, transaction: transaction) { + return result + } else if let result: T = fetchOneForPhoneNumber(address.phoneNumber, transaction: transaction) { + return result + } else { + return nil + } + } + + private func fetchOneForUUID(_ uuid: UUID?, transaction: YapDatabaseReadTransaction) -> T? { + guard let uuidString = uuid?.uuidString else { return nil } + + guard let ext = transaction.ext(YAPDBSignalServiceAddressIndex.uuidIndexName) as? YapDatabaseSecondaryIndexTransaction else { + owsFailDebug("Unexpected transaction type for extension") + return nil + } + + let queryFormat = String( + format: "WHERE %@ = \"%@\" AND %@ = \"%@\"", + YAPDBSignalServiceAddressIndex.uuidKey, + uuidString, + YAPDBSignalServiceAddressIndex.classNameKey, + NSStringFromClass(T.self) + ) + let query = YapDatabaseQuery(string: queryFormat, parameters: []) + + var matchedAccount: T? + + ext.enumerateKeysAndObjects(matching: query) { _, _, object, stop in + guard let account = object as? T else { + return + } + matchedAccount = account + stop.pointee = true + } + + return matchedAccount + } + + private func fetchOneForPhoneNumber(_ phoneNumber: String?, transaction: YapDatabaseReadTransaction) -> T? { + guard let phoneNumber = phoneNumber else { return nil } + + guard let ext = transaction.ext(YAPDBSignalServiceAddressIndex.phoneNumberIndexName) as? YapDatabaseSecondaryIndexTransaction else { + owsFailDebug("Unexpected transaction type for extension") + return nil + } + + let queryFormat = String( + format: "WHERE %@ = \"%@\" AND %@ = \"%@\"", + YAPDBSignalServiceAddressIndex.phoneNumberKey, + phoneNumber, + YAPDBSignalServiceAddressIndex.classNameKey, + NSStringFromClass(T.self) + ) + let query = YapDatabaseQuery(string: queryFormat, parameters: []) + + var matchedAccount: T? + + ext.enumerateKeysAndObjects(matching: query) { _, _, object, stop in + guard let account = object as? T else { + return + } + matchedAccount = account + stop.pointee = true + } + + return matchedAccount + } + + @objc + static func asyncRegisterDatabaseExtensions(_ storage: OWSStorage) { + storage.asyncRegister(indexUUIDExtension(), withName: uuidIndexName) + storage.asyncRegister(indexPhoneNumberExtension(), withName: phoneNumberIndexName) + } + + private static func indexUUIDExtension() -> YapDatabaseSecondaryIndex { + let setup = YapDatabaseSecondaryIndexSetup() + setup.addColumn(uuidKey, with: .text) + setup.addColumn(classNameKey, with: .text) + + let handler = YapDatabaseSecondaryIndexHandler.withObjectBlock { _, dict, _, _, object in + guard let indexableObject = object as? YAPDBSignalServiceAddressIndexable else { + return + } + + dict[uuidKey] = indexableObject.indexableUUIDValue + dict[classNameKey] = NSStringFromClass(type(of: indexableObject)) + } + + return YapDatabaseSecondaryIndex(setup: setup, handler: handler, versionTag: "1") + } + + private static func indexPhoneNumberExtension() -> YapDatabaseSecondaryIndex { + let setup = YapDatabaseSecondaryIndexSetup() + setup.addColumn(phoneNumberKey, with: .text) + setup.addColumn(classNameKey, with: .text) + + let handler = YapDatabaseSecondaryIndexHandler.withObjectBlock { _, dict, _, _, object in + guard let indexableObject = object as? YAPDBSignalServiceAddressIndexable else { + return + } + + dict[phoneNumberKey] = indexableObject.indexablePhoneNumberValue + dict[classNameKey] = NSStringFromClass(type(of: indexableObject)) + } + + return YapDatabaseSecondaryIndex(setup: setup, handler: handler, versionTag: "1") + } +} diff --git a/SignalServiceKit/src/Messages/DeviceSyncing/OWSIncomingSentMessageTranscript.m b/SignalServiceKit/src/Messages/DeviceSyncing/OWSIncomingSentMessageTranscript.m index b1cc2a94a2..24ee957893 100644 --- a/SignalServiceKit/src/Messages/DeviceSyncing/OWSIncomingSentMessageTranscript.m +++ b/SignalServiceKit/src/Messages/DeviceSyncing/OWSIncomingSentMessageTranscript.m @@ -65,7 +65,9 @@ NS_ASSUME_NONNULL_BEGIN if (self.dataMessage.group) { _thread = [TSGroupThread getOrCreateThreadWithGroupId:_dataMessage.group.id transaction:transaction]; } else { - _thread = [TSContactThread getOrCreateThreadWithContactId:_recipientId transaction:transaction]; + _thread = + [TSContactThread getOrCreateThreadWithContactAddress:_recipientId.transitional_signalServiceAddress + transaction:transaction.asAnyWrite]; } _quotedMessage = [TSQuotedMessage quotedMessageForDataMessage:_dataMessage diff --git a/SignalServiceKit/src/Messages/DeviceSyncing/OWSOutgoingSentMessageTranscript.m b/SignalServiceKit/src/Messages/DeviceSyncing/OWSOutgoingSentMessageTranscript.m index 33059a9a91..8abde702bf 100644 --- a/SignalServiceKit/src/Messages/DeviceSyncing/OWSOutgoingSentMessageTranscript.m +++ b/SignalServiceKit/src/Messages/DeviceSyncing/OWSOutgoingSentMessageTranscript.m @@ -52,10 +52,13 @@ NS_ASSUME_NONNULL_BEGIN } _message = message; - // This will be nil for groups. - _sentRecipientId = message.thread.contactIdentifier; _isRecipientUpdate = isRecipientUpdate; + if ([message.thread isKindOfClass:[TSContactThread class]]) { + TSContactThread *contactThread = (TSContactThread *)message.thread; + _sentRecipientId = contactThread.contactAddress.transitional_phoneNumber; + } + return self; } diff --git a/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncContactsMessage.m b/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncContactsMessage.m index ce4436a1b2..0108cc2e19 100644 --- a/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncContactsMessage.m +++ b/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncContactsMessage.m @@ -129,8 +129,8 @@ NS_ASSUME_NONNULL_BEGIN NSString *conversationColorName; TSContactThread *_Nullable contactThread = - [TSContactThread getThreadWithContactId:signalAccount.recipientAddress.transitional_phoneNumber - transaction:transaction]; + [TSContactThread getThreadWithContactAddress:signalAccount.recipientAddress + transaction:transaction.asAnyRead]; if (contactThread) { conversationColorName = contactThread.conversationColorName; disappearingMessagesConfiguration = [contactThread disappearingMessagesConfigurationWithTransaction:transaction]; diff --git a/SignalServiceKit/src/Messages/Interactions/TSErrorMessage.m b/SignalServiceKit/src/Messages/Interactions/TSErrorMessage.m index e7d1738dee..c6a6fe772b 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSErrorMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/TSErrorMessage.m @@ -91,8 +91,8 @@ NSUInteger TSErrorMessageSchemaVersion = 1; withTransaction:(YapDatabaseReadWriteTransaction *)transaction failedMessageType:(TSErrorMessageType)errorMessageType { - TSContactThread *contactThread = [TSContactThread getOrCreateThreadWithContactId:envelope.sourceE164 - transaction:transaction]; + TSContactThread *contactThread = [TSContactThread getOrCreateThreadWithContactAddress:envelope.sourceAddress + transaction:transaction.asAnyWrite]; // Legit usage of senderTimestamp. We don't actually currently surface it in the UI, but it serves as // a reference to the envelope which we failed to process. diff --git a/SignalServiceKit/src/Messages/Interactions/TSIncomingMessage.m b/SignalServiceKit/src/Messages/Interactions/TSIncomingMessage.m index 04f6a796cf..d62ea136a8 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSIncomingMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/TSIncomingMessage.m @@ -37,8 +37,7 @@ NS_ASSUME_NONNULL_BEGIN } if (_authorId == nil) { - OWSAssertDebug([self.uniqueThreadId hasPrefix:TSContactThreadPrefix]); - _authorId = [TSContactThread contactIdFromThreadId:self.uniqueThreadId]; + _authorId = [TSContactThread legacyContactPhoneNumberFromThreadId:self.uniqueThreadId]; } return self; diff --git a/SignalServiceKit/src/Messages/Interactions/TSInfoMessage.m b/SignalServiceKit/src/Messages/Interactions/TSInfoMessage.m index 519cf6bec1..cfc84556ea 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSInfoMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/TSInfoMessage.m @@ -237,9 +237,10 @@ perMessageExpirationDurationSeconds:perMessageExpirationDurationSeconds case TSInfoMessageUserJoinedSignal: { NSString *recipientName; if (transaction.transitional_yapReadTransaction != nil) { - NSString *contactId = [TSContactThread contactIdFromThreadId:self.uniqueThreadId]; + SignalServiceAddress *address = [TSContactThread contactAddressFromThreadId:self.uniqueThreadId + transaction:transaction]; recipientName = - [self.contactsManager displayNameForAddress:contactId.transitional_signalServiceAddress + [self.contactsManager displayNameForAddress:address transaction:transaction.transitional_yapReadTransaction]; } NSString *format = NSLocalizedString(@"INFO_MESSAGE_USER_JOINED_SIGNAL_BODY_FORMAT", diff --git a/SignalServiceKit/src/Messages/InvalidKeyMessages/TSInvalidIdentityKeyReceivingErrorMessage.m b/SignalServiceKit/src/Messages/InvalidKeyMessages/TSInvalidIdentityKeyReceivingErrorMessage.m index 8d2efd14a4..43c9a69704 100644 --- a/SignalServiceKit/src/Messages/InvalidKeyMessages/TSInvalidIdentityKeyReceivingErrorMessage.m +++ b/SignalServiceKit/src/Messages/InvalidKeyMessages/TSInvalidIdentityKeyReceivingErrorMessage.m @@ -41,8 +41,8 @@ __attribute__((deprecated)) @interface TSInvalidIdentityKeyReceivingErrorMessage + (nullable instancetype)untrustedKeyWithEnvelope:(SSKProtoEnvelope *)envelope withTransaction:(YapDatabaseReadWriteTransaction *)transaction { - TSContactThread *contactThread = [TSContactThread getOrCreateThreadWithContactId:envelope.sourceE164 - transaction:transaction]; + TSContactThread *contactThread = [TSContactThread getOrCreateThreadWithContactAddress:envelope.sourceAddress + transaction:transaction.asAnyWrite]; // Legit usage of senderTimestamp, references message which failed to decrypt TSInvalidIdentityKeyReceivingErrorMessage *errorMessage = diff --git a/SignalServiceKit/src/Messages/OWSBlockingManager.m b/SignalServiceKit/src/Messages/OWSBlockingManager.m index 40fab06bb6..fbc537e838 100644 --- a/SignalServiceKit/src/Messages/OWSBlockingManager.m +++ b/SignalServiceKit/src/Messages/OWSBlockingManager.m @@ -95,7 +95,7 @@ NSString *const kOWSBlockingManager_SyncedBlockedGroupIdsKey = @"kOWSBlockingMan { if ([thread isKindOfClass:[TSContactThread class]]) { TSContactThread *contactThread = (TSContactThread *)thread; - return [self isRecipientIdBlocked:contactThread.contactIdentifier]; + return [self isRecipientIdBlocked:contactThread.contactAddress.transitional_phoneNumber]; } else if ([thread isKindOfClass:[TSGroupThread class]]) { TSGroupThread *groupThread = (TSGroupThread *)thread; return [self isGroupIdBlocked:groupThread.groupModel.groupId]; diff --git a/SignalServiceKit/src/Messages/OWSIdentityManager.m b/SignalServiceKit/src/Messages/OWSIdentityManager.m index d239d4a7dd..6e5ce288ef 100644 --- a/SignalServiceKit/src/Messages/OWSIdentityManager.m +++ b/SignalServiceKit/src/Messages/OWSIdentityManager.m @@ -550,7 +550,8 @@ NSString *const kNSNotificationName_IdentityStateDidChange = @"kNSNotificationNa NSMutableArray *messages = [NSMutableArray new]; TSContactThread *contactThread = - [TSContactThread getOrCreateThreadWithContactId:recipientId anyTransaction:transaction]; + [TSContactThread getOrCreateThreadWithContactAddress:recipientId.transitional_signalServiceAddress + transaction:transaction]; OWSAssertDebug(contactThread != nil); TSErrorMessage *errorMessage = @@ -652,8 +653,9 @@ NSString *const kNSNotificationName_IdentityStateDidChange = @"kNSNotificationNa OWSAssertDebug(message); OWSAssertDebug(message.verificationForRecipientId.length > 0); - TSContactThread *contactThread = [TSContactThread getOrCreateThreadWithContactId:message.verificationForRecipientId]; - + TSContactThread *contactThread = [TSContactThread + getOrCreateThreadWithContactAddress:message.verificationForRecipientId.transitional_signalServiceAddress]; + // Send null message to appear as though we're sending a normal message to cover the sync messsage sent // subsequently OWSOutgoingNullMessage *nullMessage = [[OWSOutgoingNullMessage alloc] initWithContactThread:contactThread @@ -876,7 +878,8 @@ NSString *const kNSNotificationName_IdentityStateDidChange = @"kNSNotificationNa NSMutableArray *messages = [NSMutableArray new]; TSContactThread *contactThread = - [TSContactThread getOrCreateThreadWithContactId:recipientId anyTransaction:transaction]; + [TSContactThread getOrCreateThreadWithContactAddress:recipientId.transitional_signalServiceAddress + transaction:transaction]; OWSAssertDebug(contactThread); // MJK TODO - should be safe to remove senderTimestamp [messages addObject:[[OWSVerificationStateChangeMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp] diff --git a/SignalServiceKit/src/Messages/OWSMessageDecrypter.m b/SignalServiceKit/src/Messages/OWSMessageDecrypter.m index 60e1c1cea4..b50f9ec31f 100644 --- a/SignalServiceKit/src/Messages/OWSMessageDecrypter.m +++ b/SignalServiceKit/src/Messages/OWSMessageDecrypter.m @@ -653,8 +653,8 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes envelope:(SSKProtoEnvelope *)envelope transaction:(SDSAnyWriteTransaction *)transaction { - TSThread *contactThread = [TSContactThread getOrCreateThreadWithContactId:envelope.sourceE164 - anyTransaction:transaction]; + TSThread *contactThread = [TSContactThread getOrCreateThreadWithContactAddress:envelope.sourceAddress + transaction:transaction]; [SSKEnvironment.shared.notificationsManager notifyUserForErrorMessage:errorMessage thread:contactThread transaction:transaction]; diff --git a/SignalServiceKit/src/Messages/OWSMessageManager.m b/SignalServiceKit/src/Messages/OWSMessageManager.m index 498e8808c4..2b27415121 100644 --- a/SignalServiceKit/src/Messages/OWSMessageManager.m +++ b/SignalServiceKit/src/Messages/OWSMessageManager.m @@ -581,9 +581,8 @@ NS_ASSUME_NONNULL_BEGIN // FIXME: https://github.com/signalapp/Signal-iOS/issues/1340 OWSLogInfo(@"Sending group info request: %@", envelopeAddress(envelope)); - NSString *recipientId = envelope.sourceE164; - - TSThread *thread = [TSContactThread getOrCreateThreadWithContactId:recipientId anyTransaction:transaction]; + TSThread *thread = [TSContactThread getOrCreateThreadWithContactAddress:envelope.sourceAddress + transaction:transaction]; OWSSyncGroupsRequestMessage *syncGroupsRequestMessage = [[OWSSyncGroupsRequestMessage alloc] initWithThread:thread groupId:groupId]; @@ -719,7 +718,7 @@ NS_ASSUME_NONNULL_BEGIN thread = groupThread; } else { - thread = [TSContactThread getThreadWithContactId:envelope.sourceE164 anyTransaction:transaction]; + thread = [TSContactThread getThreadWithContactAddress:envelope.sourceAddress transaction:transaction]; } if (!thread) { @@ -1029,8 +1028,8 @@ NS_ASSUME_NONNULL_BEGIN return; } - TSContactThread *thread = [TSContactThread getOrCreateThreadWithContactId:envelope.sourceE164 - anyTransaction:transaction]; + TSContactThread *thread = [TSContactThread getOrCreateThreadWithContactAddress:envelope.sourceAddress + transaction:transaction]; // MJK TODO - safe to remove senderTimestamp [[[TSInfoMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp] @@ -1379,8 +1378,8 @@ NS_ASSUME_NONNULL_BEGIN } } } else { - TSContactThread *thread = [TSContactThread getOrCreateThreadWithContactId:envelope.sourceE164 - anyTransaction:transaction]; + TSContactThread *thread = [TSContactThread getOrCreateThreadWithContactAddress:envelope.sourceAddress + transaction:transaction]; if (dataMessage.hasRequiredProtocolVersion && dataMessage.requiredProtocolVersion > SSKProtos.currentProtocolVersion) { @@ -1661,7 +1660,7 @@ NS_ASSUME_NONNULL_BEGIN OWSAssertDebug(groupThread); return groupThread; } else { - return [TSContactThread getOrCreateThreadWithContactId:envelope.sourceE164 anyTransaction:transaction]; + return [TSContactThread getOrCreateThreadWithContactAddress:envelope.sourceAddress transaction:transaction]; } } diff --git a/SignalServiceKit/src/Messages/OWSMessageSender.m b/SignalServiceKit/src/Messages/OWSMessageSender.m index 7c85f19df5..03a6477df2 100644 --- a/SignalServiceKit/src/Messages/OWSMessageSender.m +++ b/SignalServiceKit/src/Messages/OWSMessageSender.m @@ -557,23 +557,24 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; OWSFailDebug(@"Message send recipients should not include self."); } } else if ([thread isKindOfClass:[TSContactThread class]]) { - NSString *recipientContactId = ((TSContactThread *)thread).contactIdentifier; + TSContactThread *contactThread = (TSContactThread *)thread; + SignalServiceAddress *recipientAddress = contactThread.contactAddress; // Treat 1:1 sends to blocked contacts as failures. // If we block a user, don't send 1:1 messages to them. The UI // should prevent this from occurring, but in some edge cases // you might, for example, have a pending outgoing message when // you block them. - OWSAssertDebug(recipientContactId.length > 0); - if ([self.blockingManager isRecipientIdBlocked:recipientContactId]) { - OWSLogInfo(@"skipping 1:1 send to blocked contact: %@", recipientContactId); + OWSAssertDebug(recipientAddress); + if ([self.blockingManager isRecipientIdBlocked:recipientAddress.transitional_phoneNumber]) { + OWSLogInfo(@"skipping 1:1 send to blocked contact: %@", recipientAddress); NSError *error = OWSErrorMakeMessageSendFailedDueToBlockListError(); [error setIsRetryable:NO]; *errorHandle = error; return nil; } - [recipientIds addObject:recipientContactId]; + [recipientIds addObject:recipientAddress.transitional_phoneNumber]; if ([recipientIds containsObject:self.tsAccountManager.localNumber]) { OWSFailDebug(@"Message send recipients should not include self."); @@ -715,9 +716,13 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; return failureHandler(error); } + TSContactThread *_Nullable contactThread; + if ([thread isKindOfClass:[TSContactThread class]]) { + contactThread = (TSContactThread *)thread; + } + // In the "self-send" special case, we ony need to send a sync message with a delivery receipt. - if ([thread isKindOfClass:[TSContactThread class]] && - [((TSContactThread *)thread).contactIdentifier isEqualToString:self.tsAccountManager.localNumber]) { + if (contactThread && contactThread.contactAddress.isLocalAddress) { // Send to self. OWSAssertDebug(message.recipientIds.count == 1); // Don't mark self-sent messages as read (or sent) until the sync transcript is sent. @@ -1411,8 +1416,13 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; { dispatch_block_t success = ^{ TSThread *_Nullable thread = message.thread; - if (thread && [thread isKindOfClass:[TSContactThread class]] && - [thread.contactIdentifier isEqualToString:self.tsAccountManager.localNumber]) { + + TSContactThread *_Nullable contactThread; + if ([thread isKindOfClass:[TSContactThread class]]) { + contactThread = (TSContactThread *)thread; + } + + if (contactThread && contactThread.contactAddress.isLocalAddress) { OWSAssertDebug(message.recipientIds.count == 1); // Don't mark self-sent messages as read (or sent) until the sync transcript is sent. [self.databaseStorage writeWithBlock:^(SDSAnyWriteTransaction *transaction) { diff --git a/SignalServiceKit/src/Messages/OWSOutgoingReceiptManager.m b/SignalServiceKit/src/Messages/OWSOutgoingReceiptManager.m index f1e7291fce..ee7d7d94db 100644 --- a/SignalServiceKit/src/Messages/OWSOutgoingReceiptManager.m +++ b/SignalServiceKit/src/Messages/OWSOutgoingReceiptManager.m @@ -172,7 +172,8 @@ NSString *const kOutgoingReadReceiptManagerCollection = @"kOutgoingReadReceiptMa continue; } - TSThread *thread = [TSContactThread getOrCreateThreadWithContactId:recipientId]; + TSThread *thread = + [TSContactThread getOrCreateThreadWithContactAddress:recipientId.transitional_signalServiceAddress]; OWSReceiptsForSenderMessage *message; NSString *receiptName; switch (receiptType) { diff --git a/SignalServiceKit/src/Storage/Database/SDSDatabaseStorage.swift b/SignalServiceKit/src/Storage/Database/SDSDatabaseStorage.swift index 850852e6c3..8fa2fae758 100644 --- a/SignalServiceKit/src/Storage/Database/SDSDatabaseStorage.swift +++ b/SignalServiceKit/src/Storage/Database/SDSDatabaseStorage.swift @@ -502,6 +502,32 @@ public class GRDBDatabaseStorageAdapter: NSObject { on: SignalAccountRecord.databaseTableName, columns: [SignalAccountRecord.columnName(.recipientUUID)] ) + + // Signal Recipient Indices + try db.create( + index: "index_signal_recipients_on_recipientPhoneNumber", + on: SignalRecipientRecord.databaseTableName, + columns: [SignalRecipientRecord.columnName(.recipientPhoneNumber)] + ) + + try db.create( + index: "index_signal_recipients_on_recipientUUID", + on: SignalRecipientRecord.databaseTableName, + columns: [SignalRecipientRecord.columnName(.recipientUUID)] + ) + + // Thread Indices + try db.create( + index: "index_thread_on_contactPhoneNumber", + on: ThreadRecord.databaseTableName, + columns: [ThreadRecord.columnName(.contactPhoneNumber)] + ) + + try db.create( + index: "index_tsthread_on_contactUUID", + on: ThreadRecord.databaseTableName, + columns: [ThreadRecord.columnName(.contactUUID)] + ) } return migrator }() diff --git a/SignalServiceKit/src/Storage/Database/SSKAccessors+SDS.h b/SignalServiceKit/src/Storage/Database/SSKAccessors+SDS.h index e09533b485..d3c7aec4d1 100644 --- a/SignalServiceKit/src/Storage/Database/SSKAccessors+SDS.h +++ b/SignalServiceKit/src/Storage/Database/SSKAccessors+SDS.h @@ -166,4 +166,16 @@ NS_ASSUME_NONNULL_BEGIN @end +#pragma mark - + +@interface TSContactThread (SDS) + +@property (nonatomic, nullable, readonly) NSString *contactPhoneNumber; +@property (nonatomic, nullable, readonly) NSString *contactUUID; +@property (nonatomic, readonly) NSUInteger contactThreadSchemaVersion; + +@end + +#pragma mark - + NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Storage/FullTextSearchFinder.swift b/SignalServiceKit/src/Storage/FullTextSearchFinder.swift index 035e66d091..13f523eb8c 100644 --- a/SignalServiceKit/src/Storage/FullTextSearchFinder.swift +++ b/SignalServiceKit/src/Storage/FullTextSearchFinder.swift @@ -169,12 +169,12 @@ public class FullTextSearchFinder: NSObject { } private static let contactThreadIndexer: SearchIndexer = SearchIndexer { (contactThread: TSContactThread, transaction: YapDatabaseReadTransaction) in - let recipientId = contactThread.contactIdentifier() - var result = recipientIndexer.index(recipientId, transaction: transaction) + let recipientAddress = contactThread.contactAddress + var result = recipientIndexer.index(recipientAddress.transitional_phoneNumber, transaction: transaction) if IsNoteToSelfEnabled(), let localNumber = tsAccountManager.storedOrCachedLocalNumber(transaction.asAnyRead), - localNumber == recipientId { + localNumber == recipientAddress.transitional_phoneNumber { let noteToSelfLabel = NSLocalizedString("NOTE_TO_SELF", comment: "Label for 1:1 conversation with yourself.") result += " \(noteToSelfLabel)" diff --git a/SignalServiceKit/src/Storage/OWSPrimaryStorage.m b/SignalServiceKit/src/Storage/OWSPrimaryStorage.m index 85b619e734..caf6f2e4d4 100644 --- a/SignalServiceKit/src/Storage/OWSPrimaryStorage.m +++ b/SignalServiceKit/src/Storage/OWSPrimaryStorage.m @@ -230,8 +230,7 @@ void VerifyRegistrationsForPrimaryStorage(OWSStorage *storage, dispatch_block_t [YAPDBMediaGalleryFinder asyncRegisterDatabaseExtensionsWithPrimaryStorage:self]; [TSDatabaseView asyncRegisterLazyRestoreAttachmentsDatabaseView:self]; [YAPDBJobRecordFinderSetup asyncRegisterDatabaseExtensionObjCWithStorage:self]; - [YAPDBSignalAccountFinder asyncRegisterDatabaseExtensions:self]; - [YAPDBSignalRecipientFinder asyncRegisterDatabaseExtensions:self]; + [YAPDBSignalServiceAddressIndex asyncRegisterDatabaseExtensions:self]; [self.database flushExtensionRequestsWithCompletionQueue:dispatch_get_global_queue( diff --git a/SignalServiceKit/src/TestUtils/Factories.swift b/SignalServiceKit/src/TestUtils/Factories.swift index 9b1c113664..ff08270348 100644 --- a/SignalServiceKit/src/TestUtils/Factories.swift +++ b/SignalServiceKit/src/TestUtils/Factories.swift @@ -97,7 +97,7 @@ public class ContactThreadFactory: NSObject, Factory { @objc public func create(transaction: SDSAnyWriteTransaction) -> TSContactThread { let threadId = generateContactThreadId() - let thread = TSContactThread.getOrCreateThread(withContactId: threadId, anyTransaction: transaction) + let thread = TSContactThread.getOrCreateThread(withContactAddress: SignalServiceAddress(phoneNumber: threadId), transaction: transaction) let incomingMessageFactory = IncomingMessageFactory() incomingMessageFactory.threadCreator = { _ in return thread } @@ -301,7 +301,7 @@ public class IncomingMessageFactory: NSObject, Factory { public var authorIdBuilder: (TSThread) -> String = { thread in switch thread { case let contactThread as TSContactThread: - return contactThread.contactIdentifier() + return contactThread.contactAddress.transitional_phoneNumber case let groupThread as TSGroupThread: return groupThread.recipientIdentifiers.ows_randomElement() ?? CommonGenerator.contactId default: diff --git a/SignalServiceKit/tests/Contacts/TSContactThreadTest.m b/SignalServiceKit/tests/Contacts/TSContactThreadTest.m index 2c76f132f0..f32163c4f3 100644 --- a/SignalServiceKit/tests/Contacts/TSContactThreadTest.m +++ b/SignalServiceKit/tests/Contacts/TSContactThreadTest.m @@ -1,11 +1,12 @@ // -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // #import "MockSSKEnvironment.h" #import "OWSIdentityManager.h" #import "SSKBaseTestObjC.h" #import "TSContactThread.h" +#import NS_ASSUME_NONNULL_BEGIN @@ -21,7 +22,8 @@ NS_ASSUME_NONNULL_BEGIN { [super setUp]; - self.contactThread = [TSContactThread getOrCreateThreadWithContactId:@"fake-contact-id"]; + self.contactThread = + [TSContactThread getOrCreateThreadWithContactAddress:@"fake-contact-id".transitional_signalServiceAddress]; } - (void)testHasSafetyNumbersWithoutRemoteIdentity @@ -31,8 +33,9 @@ NS_ASSUME_NONNULL_BEGIN - (void)testHasSafetyNumbersWithRemoteIdentity { - [[OWSIdentityManager sharedManager] saveRemoteIdentity:[[NSMutableData alloc] initWithLength:kStoredIdentityKeyLength] - recipientId:self.contactThread.contactIdentifier]; + [[OWSIdentityManager sharedManager] + saveRemoteIdentity:[[NSMutableData alloc] initWithLength:kStoredIdentityKeyLength] + recipientId:self.contactThread.contactAddress.transitional_phoneNumber]; XCTAssert(self.contactThread.hasSafetyNumbers); } diff --git a/SignalServiceKit/tests/Contacts/TSThreadTest.m b/SignalServiceKit/tests/Contacts/TSThreadTest.m index 345f494a5e..9de6af1d3e 100644 --- a/SignalServiceKit/tests/Contacts/TSThreadTest.m +++ b/SignalServiceKit/tests/Contacts/TSThreadTest.m @@ -35,7 +35,7 @@ - (void)testDeletingThreadDeletesInteractions { TSContactThread *thread = - [[TSContactThread alloc] initWithUniqueId:[TSContactThread threadIdFromContactId:@"+13334445555"]]; + [[TSContactThread alloc] initWithContactAddress:@"+13334445555".transitional_signalServiceAddress]; [thread save]; [self readWithBlock:^(SDSAnyReadTransaction *_Nonnull transaction) { @@ -89,7 +89,7 @@ - (void)testDeletingThreadDeletesAttachmentFiles { TSContactThread *thread = - [[TSContactThread alloc] initWithUniqueId:[TSContactThread threadIdFromContactId:@"+13334445555"]]; + [[TSContactThread alloc] initWithContactAddress:@"+13334445555".transitional_signalServiceAddress]; [thread save]; // Sanity check diff --git a/SignalServiceKit/tests/Messages/Interactions/TSMessageTest.m b/SignalServiceKit/tests/Messages/Interactions/TSMessageTest.m index bfc41e6ea5..52ed7a9d2e 100644 --- a/SignalServiceKit/tests/Messages/Interactions/TSMessageTest.m +++ b/SignalServiceKit/tests/Messages/Interactions/TSMessageTest.m @@ -2,11 +2,12 @@ // Copyright (c) 2019 Open Whisper Systems. All rights reserved. // -#import "TSMessage.h" #import "SSKBaseTestObjC.h" #import "TSAttachmentStream.h" #import "TSContactThread.h" +#import "TSMessage.h" #import +#import NS_ASSUME_NONNULL_BEGIN @@ -20,7 +21,8 @@ NS_ASSUME_NONNULL_BEGIN - (void)setUp { [super setUp]; - self.thread = [TSContactThread getOrCreateThreadWithContactId:@"fake-thread-id"]; + self.thread = + [TSContactThread getOrCreateThreadWithContactAddress:@"fake-thread-id".transitional_signalServiceAddress]; } - (void)tearDown { diff --git a/SignalServiceKit/tests/Messages/MessageProcessingIntegrationTest.swift b/SignalServiceKit/tests/Messages/MessageProcessingIntegrationTest.swift index fbe1d9743a..94167c710a 100644 --- a/SignalServiceKit/tests/Messages/MessageProcessingIntegrationTest.swift +++ b/SignalServiceKit/tests/Messages/MessageProcessingIntegrationTest.swift @@ -86,7 +86,7 @@ class MessageProcessingIntegrationTest: SSKBaseTestSwift { XCTFail("thread was unexpetedly nil") return } - XCTAssertEqual(thread.contactIdentifier(), self.bobClient.e164Identifier) + XCTAssertEqual(thread.contactAddress.transitional_phoneNumber, self.bobClient.e164Identifier) expectMessageProcessed.fulfill() } } @@ -140,7 +140,7 @@ class MessageProcessingIntegrationTest: SSKBaseTestSwift { XCTFail("thread was unexpetedly nil") return } - XCTAssertEqual(thread.contactIdentifier(), self.bobClient.e164Identifier) + XCTAssertEqual(thread.contactAddress.transitional_phoneNumber, self.bobClient.e164Identifier) expectMessageProcessed.fulfill() } } diff --git a/SignalServiceKit/tests/Messages/OWSIncomingMessageFinderTest.m b/SignalServiceKit/tests/Messages/OWSIncomingMessageFinderTest.m index d26e400a27..96996b99fb 100644 --- a/SignalServiceKit/tests/Messages/OWSIncomingMessageFinderTest.m +++ b/SignalServiceKit/tests/Messages/OWSIncomingMessageFinderTest.m @@ -8,6 +8,7 @@ #import "SSKBaseTestObjC.h" #import "TSContactThread.h" #import "TSIncomingMessage.h" +#import NS_ASSUME_NONNULL_BEGIN @@ -31,7 +32,7 @@ NS_ASSUME_NONNULL_BEGIN { [super setUp]; self.sourceId = @"+19999999999"; - self.thread = [TSContactThread getOrCreateThreadWithContactId:self.sourceId]; + self.thread = [TSContactThread getOrCreateThreadWithContactAddress:self.sourceId.transitional_signalServiceAddress]; self.finder = [OWSIncomingMessageFinder new]; } diff --git a/SignalServiceKit/tests/Storage/SDSDatabaseStorageTest.swift b/SignalServiceKit/tests/Storage/SDSDatabaseStorageTest.swift index 5eaab020af..ec27683128 100644 --- a/SignalServiceKit/tests/Storage/SDSDatabaseStorageTest.swift +++ b/SignalServiceKit/tests/Storage/SDSDatabaseStorageTest.swift @@ -41,7 +41,7 @@ class SDSDatabaseStorageTest: SSKBaseTestSwift { XCTAssertEqual(0, TSThread.anyFetchAll(databaseStorage: storage).count) let contactId = "+13213214321" - let contactThread = TSContactThread(contactId: contactId) + let contactThread = TSContactThread(contactAddress: contactId.transitional_signalServiceAddress) storage.write { (transaction) in XCTAssertEqual(0, TSThread.anyFetchAll(transaction: transaction).count) @@ -111,7 +111,7 @@ class SDSDatabaseStorageTest: SSKBaseTestSwift { XCTAssertEqual(0, TSInteraction.anyFetchAll(databaseStorage: storage).count) let contactId = "+13213214321" - let contactThread = TSContactThread(contactId: contactId) + let contactThread = TSContactThread(contactAddress: contactId.transitional_signalServiceAddress) storage.write { (transaction) in XCTAssertEqual(0, TSThread.anyFetchAll(transaction: transaction).count)