diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index 951df802a..595a93577 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -20,6 +20,7 @@ 34330A5C1E787A9800DF2FB9 /* dripicons-v2.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 34330A5B1E787A9800DF2FB9 /* dripicons-v2.ttf */; }; 34330A5E1E787BD800DF2FB9 /* ElegantIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 34330A5D1E787BD800DF2FB9 /* ElegantIcons.ttf */; }; 34330AA31E79686200DF2FB9 /* OWSProgressView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34330AA21E79686200DF2FB9 /* OWSProgressView.m */; }; + 343A65951FC47D5E000477A1 /* DebugUISyncMessages.m in Sources */ = {isa = PBXBuildFile; fileRef = 343A65941FC47D5E000477A1 /* DebugUISyncMessages.m */; }; 343D3D9B1E9283F100165CA4 /* BlockListUIUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 343D3D9A1E9283F100165CA4 /* BlockListUIUtils.m */; }; 344F2F671E57A932000D9322 /* UIViewController+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = 344F2F661E57A932000D9322 /* UIViewController+OWS.m */; }; 34533F181EA8D2070006114F /* OWSAudioAttachmentPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 34533F171EA8D2070006114F /* OWSAudioAttachmentPlayer.m */; }; @@ -421,6 +422,8 @@ 34330A5D1E787BD800DF2FB9 /* ElegantIcons.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = ElegantIcons.ttf; sourceTree = ""; }; 34330AA11E79686200DF2FB9 /* OWSProgressView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSProgressView.h; sourceTree = ""; }; 34330AA21E79686200DF2FB9 /* OWSProgressView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSProgressView.m; sourceTree = ""; }; + 343A65931FC47D5D000477A1 /* DebugUISyncMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugUISyncMessages.h; sourceTree = ""; }; + 343A65941FC47D5E000477A1 /* DebugUISyncMessages.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUISyncMessages.m; sourceTree = ""; }; 343D3D991E9283F100165CA4 /* BlockListUIUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlockListUIUtils.h; sourceTree = ""; }; 343D3D9A1E9283F100165CA4 /* BlockListUIUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BlockListUIUtils.m; sourceTree = ""; }; 34491FC11FB0F78500B3E5A3 /* my */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = my; path = translations/my.lproj/Localizable.strings; sourceTree = ""; }; @@ -1183,6 +1186,8 @@ 452037D01EE84975004E4CDF /* DebugUISessionState.m */, 34BECE291F74C12700D7438D /* DebugUIStress.h */, 34BECE2A1F74C12700D7438D /* DebugUIStress.m */, + 343A65931FC47D5D000477A1 /* DebugUISyncMessages.h */, + 343A65941FC47D5E000477A1 /* DebugUISyncMessages.m */, 34D8C0251ED3673300188D7C /* DebugUITableViewController.h */, 34D8C0261ED3673300188D7C /* DebugUITableViewController.m */, ); @@ -2272,6 +2277,7 @@ 450DF2051E0D74AC003D14BE /* Platform.swift in Sources */, 34BECE301F7ABCF800D7438D /* GifPickerLayout.swift in Sources */, 3472229F1EB22FFE00E53955 /* AddToGroupViewController.m in Sources */, + 343A65951FC47D5E000477A1 /* DebugUISyncMessages.m in Sources */, 45666F561D9B2827008FE134 /* OWSScrubbingLogFormatter.m in Sources */, 45C0DC1E1E69011F00E04C47 /* UIStoryboard+OWS.swift in Sources */, 34B3F8861E8DF1700035BE1A /* NotificationSettingsOptionsViewController.m in Sources */, diff --git a/Signal/src/ViewControllers/DebugUI/DebugUISyncMessages.h b/Signal/src/ViewControllers/DebugUI/DebugUISyncMessages.h new file mode 100644 index 000000000..c9d7f5776 --- /dev/null +++ b/Signal/src/ViewControllers/DebugUI/DebugUISyncMessages.h @@ -0,0 +1,15 @@ +// +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// + +#import "DebugUIPage.h" + +NS_ASSUME_NONNULL_BEGIN + +@class TSThread; + +@interface DebugUISyncMessages : DebugUIPage + +@end + +NS_ASSUME_NONNULL_END diff --git a/Signal/src/ViewControllers/DebugUI/DebugUISyncMessages.m b/Signal/src/ViewControllers/DebugUI/DebugUISyncMessages.m new file mode 100644 index 000000000..319a344b2 --- /dev/null +++ b/Signal/src/ViewControllers/DebugUI/DebugUISyncMessages.m @@ -0,0 +1,161 @@ +// +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// + +#import "DebugUISyncMessages.h" +#import "DebugUIContacts.h" +#import "Environment.h" +#import "OWSTableViewController.h" +#import "Signal-Swift.h" +#import "ThreadUtil.h" +#import <25519/Randomness.h> +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@implementation DebugUISyncMessages + +#pragma mark - Factory Methods + +- (NSString *)name +{ + return @"Sync Messages"; +} + +- (nullable OWSTableSection *)sectionForThread:(nullable TSThread *)thread +{ + NSArray *items = @[ + [OWSTableItem itemWithTitle:@"Send Contacts Sync Message" + actionBlock:^{ + [DebugUISyncMessages sendContactsSyncMessage]; + }], + [OWSTableItem itemWithTitle:@"Send Groups Sync Message" + actionBlock:^{ + [DebugUISyncMessages sendGroupSyncMessage]; + }], + [OWSTableItem itemWithTitle:@"Send Blocklist Sync Message" + actionBlock:^{ + [DebugUISyncMessages sendBlockListSyncMessage]; + }], + [OWSTableItem itemWithTitle:@"Send Configuration Sync Message" + actionBlock:^{ + [DebugUISyncMessages sendConfigurationSyncMessage]; + }], + ]; + return [OWSTableSection sectionWithTitle:self.name items:items]; +} + ++ (OWSMessageSender *)messageSender +{ + return [Environment getCurrent].messageSender; +} + ++ (OWSContactsManager *)contactsManager +{ + return [Environment getCurrent].contactsManager; +} + ++ (OWSIdentityManager *)identityManager +{ + return [OWSIdentityManager sharedManager]; +} + ++ (OWSBlockingManager *)blockingManager +{ + return [OWSBlockingManager sharedManager]; +} + ++ (OWSProfileManager *)profileManager +{ + return [OWSProfileManager sharedManager]; +} + ++ (YapDatabaseConnection *)dbConnection +{ + return [TSStorageManager.sharedManager newDatabaseConnection]; +} + ++ (void)sendContactsSyncMessage +{ + OWSSyncContactsMessage *syncContactsMessage = + [[OWSSyncContactsMessage alloc] initWithSignalAccounts:self.contactsManager.signalAccounts + identityManager:self.identityManager + profileManager:self.profileManager]; + DataSource *dataSource = + [DataSourceValue dataSourceWithSyncMessage:[syncContactsMessage buildPlainTextAttachmentData]]; + [self.messageSender enqueueTemporaryAttachment:dataSource + contentType:OWSMimeTypeApplicationOctetStream + inMessage:syncContactsMessage + success:^{ + DDLogInfo(@"%@ Successfully sent Contacts response syncMessage.", self.logTag); + } + failure:^(NSError *error) { + DDLogError(@"%@ Failed to send Contacts response syncMessage with error: %@", self.logTag, error); + }]; +} + ++ (void)sendGroupSyncMessage +{ + OWSSyncGroupsMessage *syncGroupsMessage = [[OWSSyncGroupsMessage alloc] init]; + __block DataSource *dataSource; + [self.dbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { + dataSource = [DataSourceValue + dataSourceWithSyncMessage:[syncGroupsMessage buildPlainTextAttachmentDataWithTransaction:transaction]]; + }]; + [self.messageSender enqueueTemporaryAttachment:dataSource + contentType:OWSMimeTypeApplicationOctetStream + inMessage:syncGroupsMessage + success:^{ + DDLogInfo(@"%@ Successfully sent Groups response syncMessage.", self.logTag); + } + failure:^(NSError *error) { + DDLogError(@"%@ Failed to send Groups response syncMessage with error: %@", self.logTag, error); + }]; +} + ++ (void)sendBlockListSyncMessage +{ + [self.blockingManager syncBlockedPhoneNumbers]; +} + ++ (void)sendConfigurationSyncMessage +{ + __block BOOL areReadReceiptsEnabled; + [self.dbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { + areReadReceiptsEnabled = + [[OWSReadReceiptManager sharedManager] areReadReceiptsEnabledWithTransaction:transaction]; + }]; + + OWSSyncConfigurationMessage *syncConfigurationMessage = + [[OWSSyncConfigurationMessage alloc] initWithReadReceiptsEnabled:areReadReceiptsEnabled]; + [self.messageSender enqueueMessage:syncConfigurationMessage + success:^{ + DDLogInfo(@"%@ Successfully sent Configuration response syncMessage.", self.logTag); + } + failure:^(NSError *error) { + DDLogError(@"%@ Failed to send Configuration response syncMessage with error: %@", self.logTag, error); + }]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Signal/src/ViewControllers/DebugUI/DebugUITableViewController.m b/Signal/src/ViewControllers/DebugUI/DebugUITableViewController.m index fd2d267d6..47d07fb32 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUITableViewController.m +++ b/Signal/src/ViewControllers/DebugUI/DebugUITableViewController.m @@ -9,6 +9,7 @@ #import "DebugUIMisc.h" #import "DebugUISessionState.h" #import "DebugUIStress.h" +#import "DebugUISyncMessages.h" #import "Signal-Swift.h" #import #import @@ -87,6 +88,8 @@ NS_ASSUME_NONNULL_BEGIN [subsectionItems addObject:[self itemForSubsection:[DebugUIProfile new] viewController:viewController thread:thread]]; [subsectionItems addObject:[self itemForSubsection:[DebugUIStress new] viewController:viewController thread:thread]]; + [subsectionItems + addObject:[self itemForSubsection:[DebugUISyncMessages new] viewController:viewController thread:thread]]; [subsectionItems addObject:[self itemForSubsection:[DebugUIMisc new] viewController:viewController thread:thread]]; [contents addSection:[OWSTableSection sectionWithTitle:@"Sections" items:subsectionItems]]; @@ -108,6 +111,8 @@ NS_ASSUME_NONNULL_BEGIN [subsectionItems addObject:[self itemForSubsection:[DebugUIContacts new] viewController:viewController thread:nil]]; [subsectionItems addObject:[self itemForSubsection:[DebugUIDiskUsage new] viewController:viewController thread:nil]]; + [subsectionItems + addObject:[self itemForSubsection:[DebugUISyncMessages new] viewController:viewController thread:nil]]; [subsectionItems addObject:[self itemForSubsection:[DebugUIMisc new] viewController:viewController thread:nil]]; [contents addSection:[OWSTableSection sectionWithTitle:@"Sections" items:subsectionItems]]; diff --git a/SignalServiceKit/src/Messages/OWSMessageManager.m b/SignalServiceKit/src/Messages/OWSMessageManager.m index 6ec4b9a72..d5d7dedb1 100644 --- a/SignalServiceKit/src/Messages/OWSMessageManager.m +++ b/SignalServiceKit/src/Messages/OWSMessageManager.m @@ -606,21 +606,30 @@ NS_ASSUME_NONNULL_BEGIN } } else if (syncMessage.hasRequest) { if (syncMessage.request.type == OWSSignalServiceProtosSyncMessageRequestTypeContacts) { - OWSSyncContactsMessage *syncContactsMessage = - [[OWSSyncContactsMessage alloc] initWithSignalAccounts:self.contactsManager.signalAccounts - identityManager:self.identityManager - profileManager:self.profileManager]; - DataSource *dataSource = - [DataSourceValue dataSourceWithSyncMessage:[syncContactsMessage buildPlainTextAttachmentData]]; - [self.messageSender enqueueTemporaryAttachment:dataSource - contentType:OWSMimeTypeApplicationOctetStream - inMessage:syncContactsMessage - success:^{ - DDLogInfo(@"%@ Successfully sent Contacts response syncMessage.", self.logTag); - } - failure:^(NSError *error) { - DDLogError(@"%@ Failed to send Contacts response syncMessage with error: %@", self.logTag, error); - }]; + // We respond asynchronously because populating the sync message will + // create transactions and it's not practical (due to locking in the OWSIdentityManager) + // to plumb our transaction through. + // + // In rare cases this means we won't respond to the sync request, but that's + // acceptable. + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + OWSSyncContactsMessage *syncContactsMessage = + [[OWSSyncContactsMessage alloc] initWithSignalAccounts:self.contactsManager.signalAccounts + identityManager:self.identityManager + profileManager:self.profileManager]; + DataSource *dataSource = + [DataSourceValue dataSourceWithSyncMessage:[syncContactsMessage buildPlainTextAttachmentData]]; + [self.messageSender enqueueTemporaryAttachment:dataSource + contentType:OWSMimeTypeApplicationOctetStream + inMessage:syncContactsMessage + success:^{ + DDLogInfo(@"%@ Successfully sent Contacts response syncMessage.", self.logTag); + } + failure:^(NSError *error) { + DDLogError( + @"%@ Failed to send Contacts response syncMessage with error: %@", self.logTag, error); + }]; + }); } else if (syncMessage.request.type == OWSSignalServiceProtosSyncMessageRequestTypeGroups) { OWSSyncGroupsMessage *syncGroupsMessage = [[OWSSyncGroupsMessage alloc] init]; DataSource *dataSource = [DataSourceValue diff --git a/SignalServiceKit/src/Security/OWSRecipientIdentity.m b/SignalServiceKit/src/Security/OWSRecipientIdentity.m index ea221f106..e9f70b1be 100644 --- a/SignalServiceKit/src/Security/OWSRecipientIdentity.m +++ b/SignalServiceKit/src/Security/OWSRecipientIdentity.m @@ -123,6 +123,35 @@ OWSSignalServiceProtosVerifiedState OWSVerificationStateToProtoState(OWSVerifica return sharedDBConnection; } +- (void)saveWithTransaction:(YapDatabaseReadWriteTransaction *)transaction +{ + OWSAssert(transaction.connection == [OWSRecipientIdentity dbConnection]); + + [super saveWithTransaction:transaction]; +} + +- (void)removeWithTransaction:(YapDatabaseReadWriteTransaction *)transaction +{ + OWSAssert(transaction.connection == [OWSRecipientIdentity dbConnection]); + + [super removeWithTransaction:transaction]; +} + +- (void)touchWithTransaction:(YapDatabaseReadWriteTransaction *)transaction +{ + OWSAssert(transaction.connection == [OWSRecipientIdentity dbConnection]); + + [super touchWithTransaction:transaction]; +} + ++ (nullable instancetype)fetchObjectWithUniqueID:(NSString *)uniqueID + transaction:(YapDatabaseReadTransaction *)transaction +{ + OWSAssert(transaction.connection == [OWSRecipientIdentity dbConnection]); + + return [super fetchObjectWithUniqueID:uniqueID transaction:transaction]; +} + #pragma mark - debug + (void)printAllIdentities