diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index e35686507..8e6a9287c 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -295,6 +295,7 @@ 450DF2051E0D74AC003D14BE /* Platform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 450DF2041E0D74AC003D14BE /* Platform.swift */; }; 450DF2091E0DD2C6003D14BE /* UserNotificationsAdaptee.swift in Sources */ = {isa = PBXBuildFile; fileRef = 450DF2081E0DD2C6003D14BE /* UserNotificationsAdaptee.swift */; }; 451166C01FD86B98000739BA /* AccountManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 451166BF1FD86B98000739BA /* AccountManager.swift */; }; + 451686AB1F520CDA00AC3D4B /* MultiDeviceProfileKeyUpdateJob.swift in Sources */ = {isa = PBXBuildFile; fileRef = 451686AA1F520CDA00AC3D4B /* MultiDeviceProfileKeyUpdateJob.swift */; }; 4517642B1DE939FD00EDB8B9 /* ContactCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 451764291DE939FD00EDB8B9 /* ContactCell.swift */; }; 45194F8F1FD71FF500333B2C /* ThreadUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 346129BE1FD2068600532771 /* ThreadUtil.m */; }; 45194F901FD7200000333B2C /* ThreadUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 346129BD1FD2068600532771 /* ThreadUtil.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -978,6 +979,7 @@ 450DF2041E0D74AC003D14BE /* Platform.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Platform.swift; sourceTree = ""; }; 450DF2081E0DD2C6003D14BE /* UserNotificationsAdaptee.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = UserNotificationsAdaptee.swift; path = UserInterface/Notifications/UserNotificationsAdaptee.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; 451166BF1FD86B98000739BA /* AccountManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountManager.swift; sourceTree = ""; }; + 451686AA1F520CDA00AC3D4B /* MultiDeviceProfileKeyUpdateJob.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MultiDeviceProfileKeyUpdateJob.swift; sourceTree = ""; }; 451764291DE939FD00EDB8B9 /* ContactCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContactCell.swift; sourceTree = ""; }; 451777C71FD61554001225FF /* ConversationSearcher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConversationSearcher.swift; sourceTree = ""; }; 451A13B01E13DED2000A50FD /* CallNotificationsAdapter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = CallNotificationsAdapter.swift; path = ../UserInterface/Notifications/CallNotificationsAdapter.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; @@ -2099,6 +2101,7 @@ 45D231761DC7E8F10034FA89 /* SessionResetJob.swift */, 45CD81EE1DC030E7004C9430 /* SyncPushTokensJob.swift */, 452ECA4C1E087E7200E2F016 /* MessageFetcherJob.swift */, + 451686AA1F520CDA00AC3D4B /* MultiDeviceProfileKeyUpdateJob.swift */, 4CC0B59B20EC5F2E00CF6EE0 /* ConversationConfigurationSyncOperation.swift */, ); path = Jobs; @@ -3336,6 +3339,7 @@ 34D1F0AE1F867BFC0066283D /* OWSMessageCell.m in Sources */, 4C4AEC4520EC343B0020E72B /* DismissableTextField.swift in Sources */, 4CB5F26720F6E1E2004D1B42 /* MenuActionsViewController.swift in Sources */, + 451686AB1F520CDA00AC3D4B /* MultiDeviceProfileKeyUpdateJob.swift in Sources */, 45D231771DC7E8F10034FA89 /* SessionResetJob.swift in Sources */, 340FC8A9204DAC8D007AEB0F /* NotificationSettingsOptionsViewController.m in Sources */, 452037D11EE84975004E4CDF /* DebugUISessionState.m in Sources */, diff --git a/Signal/src/Jobs/ConversationConfigurationSyncOperation.swift b/Signal/src/Jobs/ConversationConfigurationSyncOperation.swift index 90ad18a31..0da2481e2 100644 --- a/Signal/src/Jobs/ConversationConfigurationSyncOperation.swift +++ b/Signal/src/Jobs/ConversationConfigurationSyncOperation.swift @@ -23,8 +23,12 @@ class ConversationConfigurationSyncOperation: OWSOperation { return Environment.shared.contactsManager } - private var syncManager: OWSSyncManagerProtocol { - return SSKEnvironment.shared.syncManager + private var profileManager: OWSProfileManager { + return OWSProfileManager.shared() + } + + private var identityManager: OWSIdentityManager { + return OWSIdentityManager.shared() } private let thread: TSThread @@ -56,7 +60,25 @@ class ConversationConfigurationSyncOperation: OWSOperation { return } - syncManager.syncContacts(for: [signalAccount]) + let syncMessage: OWSSyncContactsMessage = OWSSyncContactsMessage(signalAccounts: [signalAccount], + identityManager: self.identityManager, + profileManager: self.profileManager) + + var dataSource: DataSource? + self.dbConnection.readWrite { transaction in + guard let messageData: Data = syncMessage.buildPlainTextAttachmentData(with: transaction) else { + owsFailDebug("could not serialize sync contacts data") + return + } + dataSource = DataSourceValue.dataSource(withSyncMessageData: messageData) + } + + guard let attachmentDataSource = dataSource else { + self.reportAssertionError(description: "unable to build attachment data source") + return + } + + self.sendConfiguration(attachmentDataSource: attachmentDataSource, syncMessage: syncMessage) } private func sync(groupThread: TSGroupThread) { diff --git a/Signal/src/Jobs/MultiDeviceProfileKeyUpdateJob.swift b/Signal/src/Jobs/MultiDeviceProfileKeyUpdateJob.swift new file mode 100644 index 000000000..177cfeb85 --- /dev/null +++ b/Signal/src/Jobs/MultiDeviceProfileKeyUpdateJob.swift @@ -0,0 +1,76 @@ +// +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// + +import Foundation +import PromiseKit +import SignalServiceKit +import SignalMessaging + +/** + * Used to distribute our profile key to legacy linked devices, newly linked devices will have our profile key as part of provisioning. + * Syncing is accomplished via the existing contact syncing mechanism, except the only contact synced is ourself. It's incumbent on the linked device + * to treat this "self contact" record specially. + */ +@objc public class MultiDeviceProfileKeyUpdateJob: NSObject { + + private let profileKey: OWSAES256Key + private let identityManager: OWSIdentityManager + private let messageSender: MessageSender + private let profileManager: OWSProfileManager + private var editingDatabaseConnection: YapDatabaseConnection { + return OWSPrimaryStorage.shared().dbReadWriteConnection + } + + @objc public required init(profileKey: OWSAES256Key, identityManager: OWSIdentityManager, messageSender: MessageSender, profileManager: OWSProfileManager) { + self.profileKey = profileKey + + self.identityManager = identityManager + self.messageSender = messageSender + self.profileManager = profileManager + } + + @objc public class func run(profileKey: OWSAES256Key, identityManager: OWSIdentityManager, messageSender: MessageSender, profileManager: OWSProfileManager) { + return self.init(profileKey: profileKey, identityManager: identityManager, messageSender: messageSender, profileManager: profileManager).run() + } + + func run(retryDelay: TimeInterval = 1) { + guard let localNumber = TSAccountManager.localNumber() else { + owsFailDebug("localNumber was unexpectedly nil") + return + } + + let localSignalAccount = SignalAccount(recipientId: localNumber) + localSignalAccount.contact = Contact() + let syncContactsMessage = OWSSyncContactsMessage(signalAccounts: [localSignalAccount], + identityManager: self.identityManager, + profileManager: self.profileManager) + + var dataSource: DataSource? + self.editingDatabaseConnection.readWrite { transaction in + guard let messageData: Data = syncContactsMessage.buildPlainTextAttachmentData(with: transaction) else { + owsFailDebug("could not serialize sync contacts data") + return + } + dataSource = DataSourceValue.dataSource(withSyncMessageData: messageData) + } + + guard let attachmentDataSource = dataSource else { + owsFailDebug("dataSource was unexpectedly nil") + return + } + + self.messageSender.enqueueTemporaryAttachment(attachmentDataSource, + contentType: OWSMimeTypeApplicationOctetStream, + in: syncContactsMessage, + success: { + Logger.info("Successfully synced profile key") + }, + failure: { error in + Logger.error("failed with error: \(error) retrying in \(retryDelay)s.") + after(seconds: retryDelay).done { + self.run(retryDelay: retryDelay * 2) + }.retainUntilComplete() + }) + } +} diff --git a/Signal/src/Signal-Bridging-Header.h b/Signal/src/Signal-Bridging-Header.h index 3c01da122..98bf68bb4 100644 --- a/Signal/src/Signal-Bridging-Header.h +++ b/Signal/src/Signal-Bridging-Header.h @@ -104,6 +104,7 @@ #import #import #import +#import #import #import #import diff --git a/Signal/src/ViewControllers/DebugUI/DebugUISyncMessages.m b/Signal/src/ViewControllers/DebugUI/DebugUISyncMessages.m index 8a897c14b..1e02461ea 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUISyncMessages.m +++ b/Signal/src/ViewControllers/DebugUI/DebugUISyncMessages.m @@ -17,6 +17,7 @@ #import #import #import +#import #import #import #import @@ -90,14 +91,28 @@ NS_ASSUME_NONNULL_BEGIN return [OWSPrimaryStorage.sharedManager newDatabaseConnection]; } -+ (id)syncManager { - OWSAssertDebug(SSKEnvironment.shared.syncManager); - - return SSKEnvironment.shared.syncManager; -} ++ (void)sendContactsSyncMessage +{ + OWSSyncContactsMessage *syncContactsMessage = + [[OWSSyncContactsMessage alloc] initWithSignalAccounts:self.contactsManager.signalAccounts + identityManager:self.identityManager + profileManager:self.profileManager]; + __block DataSource *dataSource; + [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + dataSource = [DataSourceValue + dataSourceWithSyncMessageData:[syncContactsMessage + buildPlainTextAttachmentDataWithTransaction:transaction]]; + }]; -+ (void)sendContactsSyncMessage { - [self.syncManager syncAllContacts]; + [self.messageSender enqueueTemporaryAttachment:dataSource + contentType:OWSMimeTypeApplicationOctetStream + inMessage:syncContactsMessage + success:^{ + OWSLogInfo(@"Successfully sent Contacts response syncMessage."); + } + failure:^(NSError *error) { + OWSLogError(@"Failed to send Contacts response syncMessage with error: %@", error); + }]; } + (void)sendGroupSyncMessage diff --git a/Signal/src/util/MainAppContext.m b/Signal/src/util/MainAppContext.m index 160f6bd53..6aaa75b31 100644 --- a/Signal/src/util/MainAppContext.m +++ b/Signal/src/util/MainAppContext.m @@ -220,6 +220,16 @@ NS_ASSUME_NONNULL_BEGIN }]; } +- (void)doMultiDeviceUpdateWithProfileKey:(OWSAES256Key *)profileKey +{ + OWSAssertDebug(profileKey); + + [MultiDeviceProfileKeyUpdateJob runWithProfileKey:profileKey + identityManager:OWSIdentityManager.sharedManager + messageSender:SSKEnvironment.shared.messageSender + profileManager:OWSProfileManager.sharedManager]; +} + - (BOOL)isRunningTests { return getenv("runningTests_dontStartApp"); diff --git a/SignalMessaging/contacts/OWSSyncManager.h b/SignalMessaging/contacts/OWSSyncManager.h index 07ecad360..7e30be498 100644 --- a/SignalMessaging/contacts/OWSSyncManager.h +++ b/SignalMessaging/contacts/OWSSyncManager.h @@ -6,7 +6,6 @@ NS_ASSUME_NONNULL_BEGIN -@class AnyPromise; @class OWSContactsManager; @class OWSIdentityManager; @class OWSMessageSender; diff --git a/SignalMessaging/contacts/OWSSyncManager.m b/SignalMessaging/contacts/OWSSyncManager.m index 725932b35..3447c5dbf 100644 --- a/SignalMessaging/contacts/OWSSyncManager.m +++ b/SignalMessaging/contacts/OWSSyncManager.m @@ -8,7 +8,6 @@ #import "OWSPreferences.h" #import "OWSProfileManager.h" #import "OWSReadReceiptManager.h" -#import #import #import #import @@ -17,8 +16,6 @@ #import #import #import -#import -#import #import #import @@ -94,10 +91,6 @@ NSString *const kSyncManagerLastContactSyncKey = @"kTSStorageManagerOWSSyncManag return SSKEnvironment.shared.profileManager; } -- (TSAccountManager *)tsAccountManager { - return TSAccountManager.sharedInstance; -} - #pragma mark - Notifications - (void)signalAccountsDidChange:(id)notification { @@ -222,49 +215,6 @@ NSString *const kSyncManagerLastContactSyncKey = @"kTSStorageManagerOWSSyncManag }]; } -#pragma mark - Local Sync - -- (AnyPromise *)syncLocalContact { - NSString *localNumber = self.tsAccountManager.localNumber; - SignalAccount *signalAccount = [[SignalAccount alloc] initWithRecipientId:localNumber]; - signalAccount.contact = [Contact new]; - - return [self syncContactsForSignalAccounts:@[ signalAccount ]]; -} - -- (AnyPromise *)syncAllContacts { - return [self syncContactsForSignalAccounts:self.contactsManager.signalAccounts]; -} - -- (AnyPromise *)syncContactsForSignalAccounts:(NSArray *)signalAccounts { - OWSSyncContactsMessage *syncContactsMessage = - [[OWSSyncContactsMessage alloc] initWithSignalAccounts:signalAccounts - identityManager:self.identityManager - profileManager:self.profileManager]; - __block DataSource *dataSource; - [self.editingDatabaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - dataSource = [DataSourceValue - dataSourceWithSyncMessageData:[syncContactsMessage - buildPlainTextAttachmentDataWithTransaction:transaction]]; - }]; - - AnyPromise *promise = [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) { - [self.messageSender enqueueTemporaryAttachment:dataSource - contentType:OWSMimeTypeApplicationOctetStream - inMessage:syncContactsMessage - success:^{ - OWSLogInfo(@"Successfully sent contacts sync message."); - resolve(@(1)); - } - failure:^(NSError *error) { - OWSLogError(@"Failed to send contacts sync message with error: %@", error); - resolve(error); - }]; - }]; - [promise retainUntilComplete]; - return promise; -} - @end NS_ASSUME_NONNULL_END diff --git a/SignalMessaging/profiles/OWSProfileManager.m b/SignalMessaging/profiles/OWSProfileManager.m index bdb7b148e..de7232af5 100644 --- a/SignalMessaging/profiles/OWSProfileManager.m +++ b/SignalMessaging/profiles/OWSProfileManager.m @@ -150,10 +150,6 @@ typedef void (^ProfileManagerFailureBlock)(NSError *error); return SSKEnvironment.shared.blockingManager; } -- (id)syncManager { - return SSKEnvironment.shared.syncManager; -} - #pragma mark - User Profile Accessor - (void)ensureLocalProfileCached @@ -744,13 +740,8 @@ typedef void (^ProfileManagerFailureBlock)(NSError *error); // Fetch local profile. promise = promise.then(^(id value) { [self fetchLocalUsersProfile]; - - return @(1); - }); - // Sync local profile key. - promise = promise.then(^(id value) { - return [self.syncManager syncLocalContact]; + return @(1); }); promise = promise.then(^(id value) { diff --git a/SignalMessaging/profiles/OWSUserProfile.m b/SignalMessaging/profiles/OWSUserProfile.m index 914b67b01..4f188bbef 100644 --- a/SignalMessaging/profiles/OWSUserProfile.m +++ b/SignalMessaging/profiles/OWSUserProfile.m @@ -10,7 +10,6 @@ #import #import #import -#import #import #import #import @@ -98,15 +97,6 @@ NSString *const kLocalProfileUniqueId = @"kLocalProfileUniqueId"; return self; } -#pragma mark - Dependencies - -- (id)syncManager { - return SSKEnvironment.shared.syncManager; -} - -#pragma mark - - - - (nullable NSString *)avatarUrlPath { @synchronized(self) @@ -219,8 +209,8 @@ NSString *const kLocalProfileUniqueId = @"kLocalProfileUniqueId"; // We populate an initial (empty) profile on launch of a new install, but until // we have a registered account, syncing will fail (and there could not be any // linked device to sync to at this point anyway). - if ([TSAccountManager isRegistered] && CurrentAppContext().isMainApp) { - [self.syncManager syncLocalContact]; + if ([TSAccountManager isRegistered]) { + [CurrentAppContext() doMultiDeviceUpdateWithProfileKey:self.profileKey]; } [[NSNotificationCenter defaultCenter] postNotificationNameAsync:kNSNotificationName_LocalProfileDidChange diff --git a/SignalServiceKit/src/Messages/OWSMessageManager.m b/SignalServiceKit/src/Messages/OWSMessageManager.m index b511e98d4..27f30e68e 100644 --- a/SignalServiceKit/src/Messages/OWSMessageManager.m +++ b/SignalServiceKit/src/Messages/OWSMessageManager.m @@ -27,6 +27,7 @@ #import "OWSPrimaryStorage.h" #import "OWSReadReceiptManager.h" #import "OWSRecordTranscriptJob.h" +#import "OWSSyncContactsMessage.h" #import "OWSSyncGroupsMessage.h" #import "OWSSyncGroupsRequestMessage.h" #import "ProfileManagerProtocol.h" @@ -138,12 +139,6 @@ NS_ASSUME_NONNULL_BEGIN return SSKEnvironment.shared.outgoingReceiptManager; } -- (id)syncManager { - OWSAssertDebug(SSKEnvironment.shared.syncManager); - - return SSKEnvironment.shared.syncManager; -} - #pragma mark - - (void)startObserving @@ -809,7 +804,28 @@ NS_ASSUME_NONNULL_BEGIN // 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), ^{ - [self.syncManager syncAllContacts]; + OWSSyncContactsMessage *syncContactsMessage = + [[OWSSyncContactsMessage alloc] initWithSignalAccounts:self.contactsManager.signalAccounts + identityManager:self.identityManager + profileManager:self.profileManager]; + __block NSData *_Nullable syncData; + [self.dbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { + syncData = [syncContactsMessage buildPlainTextAttachmentDataWithTransaction:transaction]; + }]; + if (!syncData) { + OWSFailDebug(@"Failed to serialize contacts sync message."); + return; + } + DataSource *dataSource = [DataSourceValue dataSourceWithSyncMessageData:syncData]; + [self.messageSender enqueueTemporaryAttachment:dataSource + contentType:OWSMimeTypeApplicationOctetStream + inMessage:syncContactsMessage + success:^{ + OWSLogInfo(@"Successfully sent Contacts response syncMessage."); + } + failure:^(NSError *error) { + OWSLogError(@"Failed to send Contacts response syncMessage with error: %@", error); + }]; }); } else if (syncMessage.request.type == SSKProtoSyncMessageRequestTypeGroups) { OWSSyncGroupsMessage *syncGroupsMessage = [[OWSSyncGroupsMessage alloc] init]; diff --git a/SignalServiceKit/src/SSKEnvironment.h b/SignalServiceKit/src/SSKEnvironment.h index 131664c39..d9bfbfcaa 100644 --- a/SignalServiceKit/src/SSKEnvironment.h +++ b/SignalServiceKit/src/SSKEnvironment.h @@ -2,8 +2,6 @@ // Copyright (c) 2018 Open Whisper Systems. All rights reserved. // -#import "OWSSyncManagerProtocol.h" - NS_ASSUME_NONNULL_BEGIN @class ContactDiscoveryService; @@ -30,6 +28,7 @@ NS_ASSUME_NONNULL_BEGIN @protocol OWSCallMessageHandler; @protocol ProfileManagerProtocol; @protocol OWSUDManager; +@protocol OWSSyncManagerProtocol; @interface SSKEnvironment : NSObject diff --git a/SignalServiceKit/src/TestUtils/OWSMockSyncManager.swift b/SignalServiceKit/src/TestUtils/OWSMockSyncManager.swift index 2655257a6..cd3cf9eb5 100644 --- a/SignalServiceKit/src/TestUtils/OWSMockSyncManager.swift +++ b/SignalServiceKit/src/TestUtils/OWSMockSyncManager.swift @@ -3,7 +3,6 @@ // import Foundation -import PromiseKit #if DEBUG @@ -13,24 +12,6 @@ public class OWSMockSyncManager: NSObject, OWSSyncManagerProtocol { @objc public func sendConfigurationSyncMessage() { Logger.info("") } - - @objc public func syncLocalContact() -> AnyPromise { - Logger.info("") - - return AnyPromise() - } - - @objc public func syncAllContacts() -> AnyPromise { - Logger.info("") - - return AnyPromise() - } - - @objc public func syncContacts(for signalAccounts: [SignalAccount]) -> AnyPromise { - Logger.info("") - - return AnyPromise() - } } #endif diff --git a/SignalServiceKit/src/TestUtils/TestAppContext.m b/SignalServiceKit/src/TestUtils/TestAppContext.m index a04229119..43ccb2614 100644 --- a/SignalServiceKit/src/TestUtils/TestAppContext.m +++ b/SignalServiceKit/src/TestUtils/TestAppContext.m @@ -112,6 +112,10 @@ NS_ASSUME_NONNULL_BEGIN return nil; } +- (void)doMultiDeviceUpdateWithProfileKey:(OWSAES256Key *)profileKey +{ +} + - (BOOL)isRunningTests { return YES; diff --git a/SignalServiceKit/src/Util/AppContext.h b/SignalServiceKit/src/Util/AppContext.h index b2dd7b73e..b42a7042d 100755 --- a/SignalServiceKit/src/Util/AppContext.h +++ b/SignalServiceKit/src/Util/AppContext.h @@ -87,6 +87,10 @@ NSString *NSStringForUIApplicationState(UIApplicationState value); // Returns nil if isMainApp is NO @property (nullable, nonatomic, readonly) UIAlertAction *openSystemSettingsAction; +// Should only be called if isMainApp is YES, +// but should only be necessary to call if isMainApp is YES. +- (void)doMultiDeviceUpdateWithProfileKey:(OWSAES256Key *)profileKey; + // Should be a NOOP if isMainApp is NO. - (void)setNetworkActivityIndicatorVisible:(BOOL)value; diff --git a/SignalServiceKit/src/Util/OWSSyncManagerProtocol.h b/SignalServiceKit/src/Util/OWSSyncManagerProtocol.h index e4e3fa090..73540e29e 100644 --- a/SignalServiceKit/src/Util/OWSSyncManagerProtocol.h +++ b/SignalServiceKit/src/Util/OWSSyncManagerProtocol.h @@ -4,19 +4,10 @@ NS_ASSUME_NONNULL_BEGIN -@class AnyPromise; -@class SignalAccount; - @protocol OWSSyncManagerProtocol - (void)sendConfigurationSyncMessage; -- (AnyPromise *)syncLocalContact; - -- (AnyPromise *)syncAllContacts; - -- (AnyPromise *)syncContactsForSignalAccounts:(NSArray *)signalAccounts; - @end NS_ASSUME_NONNULL_END diff --git a/SignalShareExtension/utils/ShareAppExtensionContext.m b/SignalShareExtension/utils/ShareAppExtensionContext.m index 733bb3bbc..86d22afc5 100644 --- a/SignalShareExtension/utils/ShareAppExtensionContext.m +++ b/SignalShareExtension/utils/ShareAppExtensionContext.m @@ -193,6 +193,11 @@ NS_ASSUME_NONNULL_BEGIN return nil; } +- (void)doMultiDeviceUpdateWithProfileKey:(OWSAES256Key *)profileKey +{ + OWSFailDebug(@""); +} + - (BOOL)isRunningTests { // We don't need to distinguish this in the SAE.