Avoid deadlocks in contact manager.
This commit is contained in:
parent
bf140971e2
commit
f26241ebd0
|
@ -76,7 +76,6 @@ extern NSString *const OWSContactsManagerSignalAccountsDidChangeNotification;
|
|||
- (BOOL)isSystemContact:(NSString *)recipientId;
|
||||
- (BOOL)isSystemContactWithSignalAccount:(NSString *)recipientId;
|
||||
- (BOOL)hasNameInSystemContactsForRecipientId:(NSString *)recipientId;
|
||||
- (NSString *)displayNameForPhoneIdentifier:(nullable NSString *)identifier;
|
||||
- (NSString *)displayNameForSignalAccount:(SignalAccount *)signalAccount;
|
||||
|
||||
/**
|
||||
|
|
|
@ -87,7 +87,7 @@ NSString *const OWSContactsManagerKeyNextFullIntersectionDate = @"OWSContactsMan
|
|||
|
||||
- (void)setup {
|
||||
__block NSMutableArray<SignalAccount *> *signalAccounts;
|
||||
[self.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) {
|
||||
[self.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
||||
NSUInteger signalAccountCount = [SignalAccount numberOfKeysInCollectionWithTransaction:transaction];
|
||||
OWSLogInfo(@"loading %lu signal accounts from cache.", (unsigned long)signalAccountCount);
|
||||
|
||||
|
@ -480,7 +480,7 @@ NSString *const OWSContactsManagerKeyNextFullIntersectionDate = @"OWSContactsMan
|
|||
}
|
||||
|
||||
NSMutableDictionary<NSString *, SignalAccount *> *oldSignalAccounts = [NSMutableDictionary new];
|
||||
[self.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) {
|
||||
[self.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
||||
[SignalAccount
|
||||
enumerateCollectionObjectsWithTransaction:transaction
|
||||
usingBlock:^(id _Nonnull object, BOOL *_Nonnull stop) {
|
||||
|
@ -585,10 +585,27 @@ NSString *const OWSContactsManagerKeyNextFullIntersectionDate = @"OWSContactsMan
|
|||
}
|
||||
|
||||
- (NSString *_Nullable)cachedContactNameForRecipientId:(NSString *)recipientId
|
||||
{
|
||||
SignalAccount *_Nullable signalAccount = [self fetchSignalAccountForRecipientId:recipientId];
|
||||
return [self cachedContactNameForRecipientId:recipientId signalAccount:signalAccount];
|
||||
}
|
||||
|
||||
- (NSString *_Nullable)cachedContactNameForRecipientId:(NSString *)recipientId
|
||||
transaction:(YapDatabaseReadTransaction *)transaction
|
||||
{
|
||||
OWSAssertDebug(recipientId.length > 0);
|
||||
OWSAssertDebug(transaction);
|
||||
|
||||
SignalAccount *_Nullable signalAccount =
|
||||
[self fetchSignalAccountForRecipientId:recipientId transaction:transaction];
|
||||
return [self cachedContactNameForRecipientId:recipientId signalAccount:signalAccount];
|
||||
}
|
||||
|
||||
- (NSString *_Nullable)cachedContactNameForRecipientId:(NSString *)recipientId
|
||||
signalAccount:(nullable SignalAccount *)signalAccount
|
||||
{
|
||||
OWSAssertDebug(recipientId.length > 0);
|
||||
|
||||
SignalAccount *_Nullable signalAccount = [self fetchSignalAccountForRecipientId:recipientId];
|
||||
if (!signalAccount) {
|
||||
// search system contacts for no-longer-registered signal users, for which there will be no SignalAccount
|
||||
OWSLogDebug(@"no signal account");
|
||||
|
@ -723,8 +740,19 @@ NSString *const OWSContactsManagerKeyNextFullIntersectionDate = @"OWSContactsMan
|
|||
return [self cachedContactNameForRecipientId:recipientId];
|
||||
}
|
||||
|
||||
- (nullable NSString *)nameFromSystemContactsForRecipientId:(NSString *)recipientId
|
||||
transaction:(YapDatabaseReadTransaction *)transaction
|
||||
{
|
||||
OWSAssertDebug(recipientId.length > 0);
|
||||
OWSAssertDebug(transaction);
|
||||
|
||||
return [self cachedContactNameForRecipientId:recipientId transaction:transaction];
|
||||
}
|
||||
|
||||
- (NSString *_Nonnull)displayNameForPhoneIdentifier:(NSString *_Nullable)recipientId
|
||||
{
|
||||
OWSAssertDebug(recipientId.length > 0);
|
||||
|
||||
if (!recipientId) {
|
||||
return self.unknownContactName;
|
||||
}
|
||||
|
@ -739,6 +767,26 @@ NSString *const OWSContactsManagerKeyNextFullIntersectionDate = @"OWSContactsMan
|
|||
return displayName;
|
||||
}
|
||||
|
||||
- (NSString *_Nonnull)displayNameForPhoneIdentifier:(NSString *_Nullable)recipientId
|
||||
transaction:(YapDatabaseReadTransaction *)transaction
|
||||
{
|
||||
OWSAssertDebug(recipientId.length > 0);
|
||||
OWSAssertDebug(transaction);
|
||||
|
||||
if (!recipientId) {
|
||||
return self.unknownContactName;
|
||||
}
|
||||
|
||||
NSString *_Nullable displayName = [self nameFromSystemContactsForRecipientId:recipientId transaction:transaction];
|
||||
|
||||
// Fall back to just using their recipientId
|
||||
if (displayName.length < 1) {
|
||||
displayName = recipientId;
|
||||
}
|
||||
|
||||
return displayName;
|
||||
}
|
||||
|
||||
- (NSString *_Nonnull)displayNameForSignalAccount:(SignalAccount *)signalAccount
|
||||
{
|
||||
OWSAssertDebug(signalAccount);
|
||||
|
@ -925,7 +973,7 @@ NSString *const OWSContactsManagerKeyNextFullIntersectionDate = @"OWSContactsMan
|
|||
if (profileName.length > 0) {
|
||||
NSString *numberAndProfileNameFormat = NSLocalizedString(@"PROFILE_NAME_AND_PHONE_NUMBER_LABEL_FORMAT",
|
||||
@"Label text combining the phone number and profile name separated by a simple demarcation character. "
|
||||
@"Phone number should be most prominent. '%1$@' is replaced with {{phone number}} and '%2$@' is replaced "
|
||||
@"Phone number should be masost prominent. '%1$@' is replaced with {{phone number}} and '%2$@' is replaced "
|
||||
@"with {{profile name}}");
|
||||
|
||||
NSString *numberAndProfileName =
|
||||
|
@ -947,7 +995,7 @@ NSString *const OWSContactsManagerKeyNextFullIntersectionDate = @"OWSContactsMan
|
|||
// If contact intersection hasn't completed, it might exist on disk
|
||||
// even if it doesn't exist in memory yet.
|
||||
if (!signalAccount) {
|
||||
[self.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) {
|
||||
[self.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
||||
signalAccount = [SignalAccount fetchObjectWithUniqueID:recipientId transaction:transaction];
|
||||
}];
|
||||
}
|
||||
|
@ -955,6 +1003,23 @@ NSString *const OWSContactsManagerKeyNextFullIntersectionDate = @"OWSContactsMan
|
|||
return signalAccount;
|
||||
}
|
||||
|
||||
- (nullable SignalAccount *)fetchSignalAccountForRecipientId:(NSString *)recipientId
|
||||
transaction:(YapDatabaseReadTransaction *)transaction
|
||||
{
|
||||
OWSAssertDebug(recipientId.length > 0);
|
||||
OWSAssertDebug(transaction);
|
||||
|
||||
__block SignalAccount *signalAccount = self.signalAccountMap[recipientId];
|
||||
|
||||
// If contact intersection hasn't completed, it might exist on disk
|
||||
// even if it doesn't exist in memory yet.
|
||||
if (!signalAccount) {
|
||||
signalAccount = [SignalAccount fetchObjectWithUniqueID:recipientId transaction:transaction];
|
||||
}
|
||||
|
||||
return signalAccount;
|
||||
}
|
||||
|
||||
- (SignalAccount *)fetchOrBuildSignalAccountForRecipientId:(NSString *)recipientId
|
||||
{
|
||||
OWSAssertDebug(recipientId.length > 0);
|
||||
|
|
|
@ -125,7 +125,8 @@ NSUInteger TSErrorMessageSchemaVersion = 1;
|
|||
@"Shown when signal users safety numbers changed, embeds the user's {{name or phone number}}");
|
||||
|
||||
NSString *recipientDisplayName =
|
||||
[SSKEnvironment.shared.contactsManager displayNameForPhoneIdentifier:self.recipientId];
|
||||
[SSKEnvironment.shared.contactsManager displayNameForPhoneIdentifier:self.recipientId
|
||||
transaction:transaction];
|
||||
return [NSString stringWithFormat:messageFormat, recipientDisplayName];
|
||||
} else {
|
||||
// recipientId will be nil for legacy errors
|
||||
|
|
|
@ -121,7 +121,8 @@ NSUInteger TSInfoMessageSchemaVersion = 1;
|
|||
case TSInfoMessageUserNotRegistered:
|
||||
if (self.unregisteredRecipientId.length > 0) {
|
||||
id<ContactsManagerProtocol> contactsManager = SSKEnvironment.shared.contactsManager;
|
||||
NSString *recipientName = [contactsManager displayNameForPhoneIdentifier:self.unregisteredRecipientId];
|
||||
NSString *recipientName = [contactsManager displayNameForPhoneIdentifier:self.unregisteredRecipientId
|
||||
transaction:transaction];
|
||||
return [NSString stringWithFormat:NSLocalizedString(@"ERROR_UNREGISTERED_USER_FORMAT",
|
||||
@"Format string for 'unregistered user' error. Embeds {{the "
|
||||
@"unregistered user's name or signal id}}."),
|
||||
|
|
|
@ -199,7 +199,8 @@ void AssertIsOnDisappearingMessagesQueue()
|
|||
NSString *remoteContactName = nil;
|
||||
if ([message isKindOfClass:[TSIncomingMessage class]]) {
|
||||
TSIncomingMessage *incomingMessage = (TSIncomingMessage *)message;
|
||||
remoteContactName = [contactsManager displayNameForPhoneIdentifier:incomingMessage.messageAuthorId];
|
||||
remoteContactName =
|
||||
[contactsManager displayNameForPhoneIdentifier:incomingMessage.messageAuthorId transaction:transaction];
|
||||
}
|
||||
|
||||
[self becomeConsistentWithDisappearingDuration:message.expiresInSeconds
|
||||
|
|
|
@ -934,7 +934,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
}
|
||||
OWSAssertDebug(disappearingMessagesConfiguration);
|
||||
[disappearingMessagesConfiguration saveWithTransaction:transaction];
|
||||
NSString *name = [self.contactsManager displayNameForPhoneIdentifier:envelope.source];
|
||||
NSString *name = [self.contactsManager displayNameForPhoneIdentifier:envelope.source transaction:transaction];
|
||||
OWSDisappearingConfigurationUpdateInfoMessage *message =
|
||||
[[OWSDisappearingConfigurationUpdateInfoMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
|
||||
thread:thread
|
||||
|
@ -1192,7 +1192,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
oldGroupThread.groupModel.groupMemberIds = [newMemberIds.allObjects mutableCopy];
|
||||
[oldGroupThread saveWithTransaction:transaction];
|
||||
|
||||
NSString *nameString = [self.contactsManager displayNameForPhoneIdentifier:envelope.source];
|
||||
NSString *nameString =
|
||||
[self.contactsManager displayNameForPhoneIdentifier:envelope.source transaction:transaction];
|
||||
NSString *updateGroupInfo =
|
||||
[NSString stringWithFormat:NSLocalizedString(@"GROUP_MEMBER_LEFT", @""), nameString];
|
||||
[[[TSInfoMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
|
||||
|
|
|
@ -9,10 +9,13 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
@class PhoneNumber;
|
||||
@class SignalAccount;
|
||||
@class UIImage;
|
||||
@class YapDatabaseReadTransaction;
|
||||
|
||||
@protocol ContactsManagerProtocol <NSObject>
|
||||
|
||||
- (NSString *)displayNameForPhoneIdentifier:(NSString *_Nullable)phoneNumber;
|
||||
- (NSString *)displayNameForPhoneIdentifier:(nullable NSString *)recipientId;
|
||||
- (NSString *_Nonnull)displayNameForPhoneIdentifier:(NSString *_Nullable)recipientId
|
||||
transaction:(YapDatabaseReadTransaction *)transaction;
|
||||
- (NSArray<SignalAccount *> *)signalAccounts;
|
||||
|
||||
- (BOOL)isSystemContact:(NSString *)recipientId;
|
||||
|
|
|
@ -172,8 +172,8 @@ public class FullTextSearchFinder: NSObject {
|
|||
return recipientIndexer.index(recipientId, transaction: transaction)
|
||||
}
|
||||
|
||||
private static let recipientIndexer: SearchIndexer<String> = SearchIndexer { (recipientId: String, _: YapDatabaseReadTransaction) in
|
||||
let displayName = contactsManager.displayName(forPhoneIdentifier: recipientId)
|
||||
private static let recipientIndexer: SearchIndexer<String> = SearchIndexer { (recipientId: String, transaction: YapDatabaseReadTransaction) in
|
||||
let displayName = contactsManager.displayName(forPhoneIdentifier: recipientId, transaction: transaction)
|
||||
|
||||
let nationalNumber: String = { (recipientId: String) -> String in
|
||||
|
||||
|
|
Loading…
Reference in New Issue