diff --git a/Podfile b/Podfile index 85d88303da..49e5f8b9ab 100644 --- a/Podfile +++ b/Podfile @@ -7,6 +7,8 @@ use_frameworks! # OWS Pods ### +pod 'SwiftProtobuf', "1.7.0" + pod 'SignalCoreKit', git: 'https://github.com/signalapp/SignalCoreKit.git', testspecs: ["Tests"] # pod 'SignalCoreKit', path: '../SignalCoreKit', testspecs: ["Tests"] diff --git a/SignalServiceKit/src/Contacts/SignalRecipient.m b/SignalServiceKit/src/Contacts/SignalRecipient.m index 977b7e4afb..ad3286702c 100644 --- a/SignalServiceKit/src/Contacts/SignalRecipient.m +++ b/SignalServiceKit/src/Contacts/SignalRecipient.m @@ -296,9 +296,6 @@ const NSUInteger SignalRecipientSchemaVersion = 1; OWSAssertDebug(address.isValid); OWSAssertDebug(transaction); - OWSLogVerbose(@"address: %@", address); - OWSLogFlush(); - SignalRecipient *_Nullable phoneNumberInstance = nil; SignalRecipient *_Nullable uuidInstance = nil; if (address.phoneNumber != nil) { @@ -325,44 +322,28 @@ const NSUInteger SignalRecipientSchemaVersion = 1; // TODO: Should we clean up any state related to the discarded recipient? // We try to preserve the recipient that has a session. - BOOL hasSessionForUuid = [self.sessionStore containsAnyActiveSessionForAccountId:uuidInstance.accountId - transaction:transaction]; - BOOL hasSessionForPhoneNumber = - [self.sessionStore containsAnyActiveSessionForAccountId:phoneNumberInstance.accountId - transaction:transaction]; + NSNumber *_Nullable sessionIndexForUuid = + [self.sessionStore maxSessionSenderChainKeyIndexForAccountId:uuidInstance.accountId + transaction:transaction]; + NSNumber *_Nullable sessionIndexForPhoneNumber = + [self.sessionStore maxSessionSenderChainKeyIndexForAccountId:phoneNumberInstance.accountId + transaction:transaction]; - // We try to preserve the recipient that has the contact thread with the most interactions. - NSUInteger numberOfInteractionsWithUUID = 0; - TSThread *_Nullable contactThreadForUuid = [[AnyContactThreadFinder new] contactThreadForUUID:address.uuid - transaction:transaction]; - if (contactThreadForUuid != nil) { - numberOfInteractionsWithUUID = [contactThreadForUuid numberOfInteractionsWithTransaction:transaction]; - } - NSUInteger numberOfInteractionsWithPhoneNumber = 0; - TSThread *_Nullable contactThreadForPhoneNumber = - [[AnyContactThreadFinder new] contactThreadForPhoneNumber:address.phoneNumber transaction:transaction]; - if (contactThreadForPhoneNumber != nil) { - numberOfInteractionsWithPhoneNumber = - [contactThreadForPhoneNumber numberOfInteractionsWithTransaction:transaction]; + if (SSKDebugFlags.verboseSignalRecipientLogging) { + OWSLogInfo(@"phoneNumberInstance: %@", phoneNumberInstance); + OWSLogInfo(@"uuidInstance: %@", uuidInstance); + OWSLogInfo(@"sessionIndexForUuid: %@", sessionIndexForUuid); + OWSLogInfo(@"sessionIndexForPhoneNumber: %@", sessionIndexForPhoneNumber); } - OWSLogWarn(@"phoneNumberInstance: %@", phoneNumberInstance); - OWSLogWarn(@"uuidInstance: %@", uuidInstance); - OWSLogWarn(@"numberOfInteractionsWithUUID: %lu", (unsigned long)numberOfInteractionsWithUUID); - OWSLogWarn(@"numberOfInteractionsWithPhoneNumber: %lu", (unsigned long)numberOfInteractionsWithPhoneNumber); - OWSLogWarn(@"hasSessionForUuid: %d", hasSessionForUuid); - OWSLogWarn(@"hasSessionForPhoneNumber: %d", hasSessionForPhoneNumber); - BOOL shouldUseUuid = NO; - if (hasSessionForPhoneNumber && !hasSessionForUuid) { - shouldUseUuid = NO; - } else if (hasSessionForUuid && !hasSessionForPhoneNumber) { - shouldUseUuid = YES; - } else if (numberOfInteractionsWithPhoneNumber > numberOfInteractionsWithUUID) { - shouldUseUuid = NO; - } else { - // Default to retaining the UUID recipient. - shouldUseUuid = YES; - } + // We want to retain the phone number recipient if it + // has a session and the uuid recipient doesn't or if + // both have a session but the phone number recipient + // has seen more use. + // + // All things being equal, we default to retaining the + // UUID recipient. + BOOL shouldUseUuid = (sessionIndexForPhoneNumber.intValue <= sessionIndexForUuid.intValue); if (shouldUseUuid) { OWSFailDebug(@"Discarding phone number recipient in favor of uuid recipient."); existingInstance = uuidInstance; diff --git a/SignalServiceKit/src/Storage/AxolotlStore/SSKSessionStore.h b/SignalServiceKit/src/Storage/AxolotlStore/SSKSessionStore.h index 42946798ef..561326a2d0 100644 --- a/SignalServiceKit/src/Storage/AxolotlStore/SSKSessionStore.h +++ b/SignalServiceKit/src/Storage/AxolotlStore/SSKSessionStore.h @@ -28,7 +28,8 @@ NS_ASSUME_NONNULL_BEGIN deviceId:(int)deviceId transaction:(SDSAnyWriteTransaction *)transaction; -- (BOOL)containsAnyActiveSessionForAccountId:(NSString *)accountId transaction:(SDSAnyReadTransaction *)transaction; +- (nullable NSNumber *)maxSessionSenderChainKeyIndexForAccountId:(NSString *)accountId + transaction:(SDSAnyReadTransaction *)transaction; - (void)deleteSessionForAddress:(SignalServiceAddress *)address deviceId:(int)deviceId diff --git a/SignalServiceKit/src/Storage/AxolotlStore/SSKSessionStore.m b/SignalServiceKit/src/Storage/AxolotlStore/SSKSessionStore.m index c5242ef575..0c0f1b3edd 100644 --- a/SignalServiceKit/src/Storage/AxolotlStore/SSKSessionStore.m +++ b/SignalServiceKit/src/Storage/AxolotlStore/SSKSessionStore.m @@ -205,11 +205,13 @@ NS_ASSUME_NONNULL_BEGIN [self loadSessionForAccountId:accountId deviceId:deviceId transaction:transaction].sessionState.hasSenderChain; } -- (BOOL)containsAnyActiveSessionForAccountId:(NSString *)accountId transaction:(SDSAnyReadTransaction *)transaction +- (nullable NSNumber *)maxSessionSenderChainKeyIndexForAccountId:(NSString *)accountId + transaction:(SDSAnyReadTransaction *)transaction { OWSAssertDebug(accountId.length > 0); OWSAssertDebug([transaction isKindOfClass:[SDSAnyReadTransaction class]]); + NSNumber *_Nullable result = nil; NSDictionary *_Nullable dictionary = [self.keyValueStore getObjectForKey:accountId transaction:transaction]; for (id value in dictionary.allValues) { if (![value isKindOfClass:[SessionRecord class]]) { @@ -218,12 +220,20 @@ NS_ASSUME_NONNULL_BEGIN continue; } SessionRecord *record = (SessionRecord *)value; - OWSLogVerbose(@"Record: %d.", record.sessionState.hasSenderChain); + if (SSKDebugFlags.verboseSignalRecipientLogging) { + OWSLogInfo(@"Record hasSenderChain: %d.", record.sessionState.hasSenderChain); + } if (record.sessionState.hasSenderChain) { - return YES; + int index = record.sessionState.senderChainKey.index; + if (SSKDebugFlags.verboseSignalRecipientLogging) { + OWSLogInfo(@"Record index: %d.", index); + } + if (result == nil || result.intValue < index) { + result = @(index); + } } } - return NO; + return result; } - (void)deleteSessionForContact:(NSString *)contactIdentifier diff --git a/SignalServiceKit/src/Util/FeatureFlags.swift b/SignalServiceKit/src/Util/FeatureFlags.swift index e99017f22f..823a07404e 100644 --- a/SignalServiceKit/src/Util/FeatureFlags.swift +++ b/SignalServiceKit/src/Util/FeatureFlags.swift @@ -309,4 +309,7 @@ public class DebugFlags: NSObject { @objc public static let verboseNotificationLogging = build.includes(.qa) + + @objc + public static let verboseSignalRecipientLogging = build.includes(.qa) }