From 95e57a676679f72327be0a9ed92518c5e97e8673 Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Tue, 2 Jun 2020 17:11:04 +1000 Subject: [PATCH 01/19] Fix: When a master device links a slave device, the slave doesn't appear to get the profile picture --- .../Messages/Interactions/TSOutgoingMessage.m | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m index 8b2b148c5..f9ef89d83 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m @@ -1125,21 +1125,23 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt } - (SSKProtoContentBuilder *)prepareCustomContentBuilder:(SignalRecipient *)recipient { - return SSKProtoContent.builder; + SSKProtoDataMessage *_Nullable dataMessage = [self buildDataMessage:recipient.recipientId]; + if (!dataMessage) { + OWSFailDebug(@"could not build protobuf"); + return nil; + } + + SSKProtoContentBuilder *contentBuilder = SSKProtoContent.builder; + [contentBuilder setDataMessage:dataMessage]; + + return contentBuilder; } - (nullable NSData *)buildPlainTextData:(SignalRecipient *)recipient { - NSError *error; - SSKProtoDataMessage *_Nullable dataMessage = [self buildDataMessage:recipient.recipientId]; - if (error || !dataMessage) { - OWSFailDebug(@"could not build protobuf: %@", error); - return nil; - } - SSKProtoContentBuilder *contentBuilder = [self prepareCustomContentBuilder:recipient]; + NSError *error; - [contentBuilder setDataMessage:dataMessage]; NSData *_Nullable contentData = [contentBuilder buildSerializedDataAndReturnError:&error]; if (error || !contentData) { OWSFailDebug(@"could not serialize protobuf: %@", error); From 00373181751841e3a2427d905efd9efd10643382 Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Thu, 4 Jun 2020 12:26:09 +1000 Subject: [PATCH 02/19] Fix open group name and profile picture not updating --- Signal/src/Loki/View Controllers/JoinPublicChatVC.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Signal/src/Loki/View Controllers/JoinPublicChatVC.swift b/Signal/src/Loki/View Controllers/JoinPublicChatVC.swift index 54994be0d..94e7de5ae 100644 --- a/Signal/src/Loki/View Controllers/JoinPublicChatVC.swift +++ b/Signal/src/Loki/View Controllers/JoinPublicChatVC.swift @@ -134,11 +134,13 @@ final class JoinPublicChatVC : BaseVC, UIPageViewControllerDataSource, UIPageVie let channelID: UInt64 = 1 let urlAsString = url.absoluteString let displayName = OWSProfileManager.shared().localProfileName() - // TODO: Profile picture & profile key + let profilePictureURL = OWSProfileManager.shared().profilePictureURL() + let profileKey = OWSProfileManager.shared().localProfileKey().keyData LokiPublicChatManager.shared.addChat(server: urlAsString, channel: channelID) .done(on: .main) { [weak self] _ in let _ = LokiPublicChatAPI.getMessages(for: channelID, on: urlAsString) let _ = LokiPublicChatAPI.setDisplayName(to: displayName, on: urlAsString) + let _ = LokiPublicChatAPI.setProfilePictureURL(to: profilePictureURL, using: profileKey, on: urlAsString) let _ = LokiPublicChatAPI.join(channelID, on: urlAsString) let syncManager = SSKEnvironment.shared.syncManager let _ = syncManager.syncAllOpenGroups() From 56dface3ba18c73fe2a4f2f88d0fa96dbd0956d3 Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Thu, 4 Jun 2020 15:53:18 +1000 Subject: [PATCH 03/19] add profile picture to public chat info --- .../src/Loki/API/Open Groups/LokiPublicChatAPI.swift | 3 ++- .../src/Loki/API/Open Groups/LokiPublicChatInfo.swift | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatAPI.swift b/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatAPI.swift index 716eb37ff..f238b02ea 100644 --- a/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatAPI.swift +++ b/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatAPI.swift @@ -395,12 +395,13 @@ public final class LokiPublicChatAPI : LokiDotNetAPI { print("[Loki] Couldn't parse info for public chat channel with ID: \(channel) on server: \(server) from: \(rawResponse).") throw LokiDotNetAPIError.parsingFailed } + let profilePictureURL = info["avatar"] as? String let storage = OWSPrimaryStorage.shared() storage.dbReadWriteConnection.readWrite { transaction in storage.setUserCount(memberCount, forPublicChatWithID: "\(server).\(channel)", in: transaction) } // TODO: Use this to update open group names as needed - return LokiPublicChatInfo(displayName: displayName, memberCount: memberCount) + return LokiPublicChatInfo(displayName: displayName, profilePictureURL: profilePictureURL, memberCount: memberCount) } } diff --git a/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatInfo.swift b/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatInfo.swift index 90c2a1685..607f06ba3 100644 --- a/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatInfo.swift +++ b/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatInfo.swift @@ -1,5 +1,6 @@ public struct LokiPublicChatInfo { public let displayName: String + public let profilePictureURL: String? public let memberCount: Int } From 837aa54e07f0b55aa1946211689fb41b1d7beb1e Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Fri, 5 Jun 2020 11:53:44 +1000 Subject: [PATCH 04/19] fix when rejoining open groups messages sent were not loaded (case 4) --- .../src/Loki/API/Open Groups/LokiPublicChatPoller.swift | 1 + .../Protocol/Sync Messages/SyncMessagesProtocol.swift | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatPoller.swift b/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatPoller.swift index 974eb814b..f7cb017c1 100644 --- a/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatPoller.swift +++ b/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatPoller.swift @@ -150,6 +150,7 @@ public final class LokiPublicChatPoller : NSObject { if !wasSentByCurrentUser { content.setDataMessage(try! dataMessage.build()) } else { + SyncMessagesProtocol.addForceSyncMessageTimestamp(message.timestamp, from: senderHexEncodedPublicKey) let syncMessageSentBuilder = SSKProtoSyncMessageSent.builder() syncMessageSentBuilder.setMessage(try! dataMessage.build()) syncMessageSentBuilder.setDestination(userHexEncodedPublicKey) diff --git a/SignalServiceKit/src/Loki/Protocol/Sync Messages/SyncMessagesProtocol.swift b/SignalServiceKit/src/Loki/Protocol/Sync Messages/SyncMessagesProtocol.swift index 5574c8463..868c0774d 100644 --- a/SignalServiceKit/src/Loki/Protocol/Sync Messages/SyncMessagesProtocol.swift +++ b/SignalServiceKit/src/Loki/Protocol/Sync Messages/SyncMessagesProtocol.swift @@ -96,6 +96,15 @@ public final class SyncMessagesProtocol : NSObject { let hexEncodedPublicKey = envelope.source! return LokiDatabaseUtilities.isUserLinkedDevice(hexEncodedPublicKey, transaction: transaction) } + + @objc(addForceSyncMessageTimestamp:from:) + public static func addForceSyncMessageTimestamp(_ timestamp: UInt64, from hexEncodedPublicKey: String) { + var timestamps: Set = syncMessageTimestamps[hexEncodedPublicKey] ?? [] + if timestamps.contains(timestamp) { + timestamps.remove(timestamp) + } + syncMessageTimestamps[hexEncodedPublicKey] = timestamps + } // TODO: We should probably look at why sync messages are being duplicated rather than doing this @objc(isDuplicateSyncMessage:fromHexEncodedPublicKey:) From d9bca8b5b91f0f4b2086e726d729af7b59a89c7e Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Tue, 9 Jun 2020 10:40:39 +1000 Subject: [PATCH 05/19] Update display name when an open group sync message coming --- .../src/Loki/Protocol/Sync Messages/SyncMessagesProtocol.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/SignalServiceKit/src/Loki/Protocol/Sync Messages/SyncMessagesProtocol.swift b/SignalServiceKit/src/Loki/Protocol/Sync Messages/SyncMessagesProtocol.swift index 868c0774d..d5a4d0666 100644 --- a/SignalServiceKit/src/Loki/Protocol/Sync Messages/SyncMessagesProtocol.swift +++ b/SignalServiceKit/src/Loki/Protocol/Sync Messages/SyncMessagesProtocol.swift @@ -237,6 +237,9 @@ public final class SyncMessagesProtocol : NSObject { for openGroup in groups { let openGroupManager = LokiPublicChatManager.shared guard openGroupManager.getChat(server: openGroup.url, channel: openGroup.channel) == nil else { return } + let userHexEncodedPublicKey = UserDefaults.standard[.masterHexEncodedPublicKey] ?? getUserHexEncodedPublicKey() + let displayName = SSKEnvironment.shared.profileManager.profileNameForRecipient(withID: userHexEncodedPublicKey) + LokiPublicChatAPI.setDisplayName(to: displayName, on: openGroup.url) openGroupManager.addChat(server: openGroup.url, channel: openGroup.channel) } } From 335704c3624eaccaa0cfda380b94a59fd3ee51f5 Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Tue, 9 Jun 2020 10:41:42 +1000 Subject: [PATCH 06/19] Upload the right display name to open group from the slave device --- Signal/src/Loki/View Controllers/JoinPublicChatVC.swift | 3 ++- .../src/Loki/API/Open Groups/LokiPublicChatAPI.swift | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Signal/src/Loki/View Controllers/JoinPublicChatVC.swift b/Signal/src/Loki/View Controllers/JoinPublicChatVC.swift index 94e7de5ae..601b6c06a 100644 --- a/Signal/src/Loki/View Controllers/JoinPublicChatVC.swift +++ b/Signal/src/Loki/View Controllers/JoinPublicChatVC.swift @@ -133,7 +133,8 @@ final class JoinPublicChatVC : BaseVC, UIPageViewControllerDataSource, UIPageVie isJoining = true let channelID: UInt64 = 1 let urlAsString = url.absoluteString - let displayName = OWSProfileManager.shared().localProfileName() + let userHexEncodedPublicKey = UserDefaults.standard[.masterHexEncodedPublicKey] ?? getUserHexEncodedPublicKey() + let displayName = OWSProfileManager.shared().profileNameForRecipient(withID: userHexEncodedPublicKey) let profilePictureURL = OWSProfileManager.shared().profilePictureURL() let profileKey = OWSProfileManager.shared().localProfileKey().keyData LokiPublicChatManager.shared.addChat(server: urlAsString, channel: channelID) diff --git a/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatAPI.swift b/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatAPI.swift index f238b02ea..37ba968c8 100644 --- a/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatAPI.swift +++ b/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatAPI.swift @@ -19,7 +19,8 @@ public final class LokiPublicChatAPI : LokiDotNetAPI { // MARK: Convenience private static var userDisplayName: String { - return SSKEnvironment.shared.contactsManager.displayName(forPhoneIdentifier: getUserHexEncodedPublicKey()) ?? "Anonymous" + let userHexEncodedPublicKey = UserDefaults.standard[.masterHexEncodedPublicKey] ?? getUserHexEncodedPublicKey() + return SSKEnvironment.shared.profileManager.profileNameForRecipient(withID: userHexEncodedPublicKey) ?? "Anonymous" } // MARK: Database From c8af41cd5c0f034e7dba07df06d2bea7f413253e Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Wed, 10 Jun 2020 15:14:16 +1000 Subject: [PATCH 07/19] Show real profile picture of open groups --- .../Loki/Components/ConversationCell.swift | 21 ++++--- .../OWSConversationSettingsViewController.m | 10 +++- .../Components/ProfilePictureView.swift | 6 +- .../API/Open Groups/LokiPublicChatAPI.swift | 57 +++++++++++++++++-- .../Database/OWSPrimaryStorage+Loki.swift | 9 +++ 5 files changed, 85 insertions(+), 18 deletions(-) diff --git a/Signal/src/Loki/Components/ConversationCell.swift b/Signal/src/Loki/Components/ConversationCell.swift index d6fdde318..2b75f5850 100644 --- a/Signal/src/Loki/Components/ConversationCell.swift +++ b/Signal/src/Loki/Components/ConversationCell.swift @@ -141,15 +141,20 @@ final class ConversationCell : UITableViewCell { profilePictureView.hexEncodedPublicKey = "" profilePictureView.isRSSFeed = true } else { - var users = MentionsManager.userPublicKeyCache[threadViewModel.threadRecord.uniqueId!] ?? [] - users.remove(getUserHexEncodedPublicKey()) - let randomUsers = users.sorted().prefix(2) // Sort to provide a level of stability - if !randomUsers.isEmpty { - profilePictureView.hexEncodedPublicKey = randomUsers[0] - profilePictureView.additionalHexEncodedPublicKey = randomUsers.count >= 2 ? randomUsers[1] : "" + if let groupAvatarImage = (threadViewModel.threadRecord as? TSGroupThread)?.groupModel.groupImage { + profilePictureView.groupAvatarImage = groupAvatarImage } else { - profilePictureView.hexEncodedPublicKey = "" - profilePictureView.additionalHexEncodedPublicKey = "" + profilePictureView.groupAvatarImage = nil + var users = MentionsManager.userPublicKeyCache[threadViewModel.threadRecord.uniqueId!] ?? [] + users.remove(getUserHexEncodedPublicKey()) + let randomUsers = users.sorted().prefix(2) // Sort to provide a level of stability + if !randomUsers.isEmpty { + profilePictureView.hexEncodedPublicKey = randomUsers[0] + profilePictureView.additionalHexEncodedPublicKey = randomUsers.count >= 2 ? randomUsers[1] : "" + } else { + profilePictureView.hexEncodedPublicKey = "" + profilePictureView.additionalHexEncodedPublicKey = "" + } } profilePictureView.isRSSFeed = (threadViewModel.threadRecord as? TSGroupThread)?.isRSSFeed ?? false } diff --git a/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m b/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m index 792bf68cf..022225a04 100644 --- a/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m +++ b/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m @@ -957,8 +957,14 @@ const CGFloat kIconViewLength = 24; [stackView setLayoutMarginsRelativeArrangement:YES]; if (self.isGroupThread) { - profilePictureView.hexEncodedPublicKey = @""; - profilePictureView.isRSSFeed = true; // For now just always show the Session logo + TSGroupThread* groupThread = (TSGroupThread*)self.thread; + if (groupThread.isPublicChat && groupThread.groupModel.groupImage != nil) { + profilePictureView.groupAvatarImage = groupThread.groupModel.groupImage; + profilePictureView.isRSSFeed = false; + } else { + profilePictureView.hexEncodedPublicKey = @""; + profilePictureView.isRSSFeed = true; // For now just always show the Session logo + } } else { profilePictureView.hexEncodedPublicKey = self.thread.contactIdentifier; diff --git a/SignalMessaging/Loki/Redesign/Components/ProfilePictureView.swift b/SignalMessaging/Loki/Redesign/Components/ProfilePictureView.swift index 809fa8f24..6aacb8f21 100644 --- a/SignalMessaging/Loki/Redesign/Components/ProfilePictureView.swift +++ b/SignalMessaging/Loki/Redesign/Components/ProfilePictureView.swift @@ -7,6 +7,7 @@ public final class ProfilePictureView : UIView { @objc public var isRSSFeed = false @objc public var hexEncodedPublicKey: String! @objc public var additionalHexEncodedPublicKey: String? + @objc public var groupAvatarImage: UIImage? // MARK: Components private lazy var imageView = getImageView() @@ -61,8 +62,9 @@ public final class ProfilePictureView : UIView { additionalImageView.isHidden = true additionalImageView.image = nil } - guard hexEncodedPublicKey != nil else { return } // Can happen in rare cases - imageView.image = isRSSFeed ? nil : getProfilePicture(of: size, for: hexEncodedPublicKey) + guard hexEncodedPublicKey != nil || groupAvatarImage != nil else { return } // Can happen in rare cases + + imageView.image = isRSSFeed ? nil : groupAvatarImage != nil ? groupAvatarImage! : getProfilePicture(of: size, for: hexEncodedPublicKey) imageView.backgroundColor = isRSSFeed ? UIColor(rgbHex: 0x353535) : UIColor(rgbHex: 0xD8D8D8) // UIColor(rgbHex: 0xD8D8D8) = Colors.unimportant imageView.layer.cornerRadius = size / 2 imageView.contentMode = isRSSFeed ? .center : .scaleAspectFit diff --git a/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatAPI.swift b/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatAPI.swift index 37ba968c8..d503f0159 100644 --- a/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatAPI.swift +++ b/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatAPI.swift @@ -391,18 +391,63 @@ public final class LokiPublicChatAPI : LokiDotNetAPI { let annotation = annotations.first, let info = annotation["value"] as? JSON, let displayName = info["name"] as? String, + let profilePictureURL = info["avatar"] as? String, let countInfo = data["counts"] as? JSON, let memberCount = countInfo["subscribers"] as? Int else { print("[Loki] Couldn't parse info for public chat channel with ID: \(channel) on server: \(server) from: \(rawResponse).") throw LokiDotNetAPIError.parsingFailed } - let profilePictureURL = info["avatar"] as? String - let storage = OWSPrimaryStorage.shared() - storage.dbReadWriteConnection.readWrite { transaction in - storage.setUserCount(memberCount, forPublicChatWithID: "\(server).\(channel)", in: transaction) + let publicChatInfo = LokiPublicChatInfo(displayName: displayName, profilePictureURL: profilePictureURL, memberCount: memberCount) + updateOpenGroupProfileIfNeeded(for: channel, on: server, with: publicChatInfo) + return publicChatInfo + } + } + + static func updateOpenGroupProfileIfNeeded(for channel: UInt64, on server: String, with info: LokiPublicChatInfo) { + let storage = OWSPrimaryStorage.shared() + let publicChatID = "\(server).\(channel)" + storage.dbReadWriteConnection.readWrite { transaction in + //Save user count + storage.setUserCount(info.memberCount, forPublicChatWithID: publicChatID, in: transaction) + + let groupThread = TSGroupThread.getOrCreateThread(withGroupId: publicChatID.data(using: .utf8)!, groupType: .openGroup, transaction: transaction) + + //Update display name if needed + let groupModel = groupThread.groupModel + if groupModel.groupName != info.displayName { + let newGroupModel = TSGroupModel.init(title: info.displayName, memberIds: groupModel.groupMemberIds, image: groupModel.groupImage, groupId: groupModel.groupId, groupType: groupModel.groupType, adminIds: groupModel.groupAdminIds) + groupThread.groupModel = newGroupModel + groupThread.save(with: transaction) + } + + //Download and update profile picture if needed + let oldAvatarURL = storage.getAvatarURL(forPublicChatWithID: publicChatID, in: transaction) + if oldAvatarURL != info.profilePictureURL || groupModel.groupImage == nil { + storage.setAvatarURL(info.profilePictureURL, forPublicChatWithID: publicChatID, in: transaction) + if let avatarURL = info.profilePictureURL { + let configuration = URLSessionConfiguration.default + let manager = AFURLSessionManager.init(sessionConfiguration: configuration) + let url = URL(string: "\(server)\(avatarURL)")! + let request = URLRequest(url: url) + let task = manager.downloadTask(with: request, progress: nil, + destination: {(targetPath: URL, response: URLResponse) -> URL in + let tempFilePath = URL(fileURLWithPath: OWSTemporaryDirectoryAccessibleAfterFirstAuth()).appendingPathComponent(UUID().uuidString) + return tempFilePath + }, + completionHandler: { (response: URLResponse, filePath: URL?, error: Error?) in + if let error = error { + print("[Loki] Couldn't download profile picture for public chat channel with ID: \(channel) on server: \(server)") + return + } + if let path = filePath, let avatarData = try? Data.init(contentsOf: path) { + let attachmentStream = TSAttachmentStream.init(contentType: OWSMimeTypeImageJpeg, byteCount: UInt32(avatarData.count), sourceFilename: nil, caption: nil, albumMessageId: nil) + try! attachmentStream.write(avatarData) + groupThread.updateAvatar(with: attachmentStream) + } + }) + task.resume() + } } - // TODO: Use this to update open group names as needed - return LokiPublicChatInfo(displayName: displayName, profilePictureURL: profilePictureURL, memberCount: memberCount) } } diff --git a/SignalServiceKit/src/Loki/Database/OWSPrimaryStorage+Loki.swift b/SignalServiceKit/src/Loki/Database/OWSPrimaryStorage+Loki.swift index c69a996a5..e3ac306b3 100644 --- a/SignalServiceKit/src/Loki/Database/OWSPrimaryStorage+Loki.swift +++ b/SignalServiceKit/src/Loki/Database/OWSPrimaryStorage+Loki.swift @@ -151,6 +151,7 @@ public extension OWSPrimaryStorage { // MARK: - Open Groups private static let openGroupUserCountCollection = "LokiPublicChatUserCountCollection" + private static let openGroupAvatarURLCollection = "LokiPublicChatAvatarURLCollection" public func getUserCount(for publicChat: LokiPublicChat, in transaction: YapDatabaseReadTransaction) -> Int? { return transaction.object(forKey: publicChat.id, inCollection: OWSPrimaryStorage.openGroupUserCountCollection) as? Int @@ -159,4 +160,12 @@ public extension OWSPrimaryStorage { public func setUserCount(_ userCount: Int, forPublicChatWithID publicChatID: String, in transaction: YapDatabaseReadWriteTransaction) { transaction.setObject(userCount, forKey: publicChatID, inCollection: OWSPrimaryStorage.openGroupUserCountCollection) } + + public func getAvatarURL(forPublicChatWithID publicChatID: String, in transaction: YapDatabaseReadTransaction) -> String? { + return transaction.object(forKey: publicChatID, inCollection: OWSPrimaryStorage.openGroupAvatarURLCollection) as? String + } + + public func setAvatarURL(_ avatarURL: String?, forPublicChatWithID publicChatID: String, in transaction: YapDatabaseReadWriteTransaction) { + transaction.setObject(avatarURL, forKey: publicChatID, inCollection: OWSPrimaryStorage.openGroupAvatarURLCollection) + } } From ce416ae82cd4be83b547202389622d6565ebd069 Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Wed, 10 Jun 2020 12:21:36 +1000 Subject: [PATCH 08/19] Don't repair session if there's an outstanding session request Also fix non-UD send cases --- .../View Controllers/NewClosedGroupVC.swift | 3 +- .../Closed Groups/ClosedGroupsProtocol.swift | 1 + .../Multi Device/MultiDeviceProtocol.swift | 44 +++++++++++++------ .../SessionManagementProtocol.swift | 7 +++ .../src/Messages/OWSMessageDecrypter.m | 1 - .../src/Messages/OWSMessageSender.m | 9 ++-- 6 files changed, 45 insertions(+), 20 deletions(-) diff --git a/Signal/src/Loki/View Controllers/NewClosedGroupVC.swift b/Signal/src/Loki/View Controllers/NewClosedGroupVC.swift index ad4f87698..66b42e50f 100644 --- a/Signal/src/Loki/View Controllers/NewClosedGroupVC.swift +++ b/Signal/src/Loki/View Controllers/NewClosedGroupVC.swift @@ -47,7 +47,8 @@ final class NewClosedGroupVC : BaseVC, UITableViewDataSource, UITableViewDelegat super.viewDidLoad() setUpGradientBackground() setUpNavBarStyle() - setNavBarTitle(NSLocalizedString("New Closed Group", comment: "")) + let customTitleFontSize = isSmallScreen ? Values.largeFontSize : Values.veryLargeFontSize + setNavBarTitle(NSLocalizedString("New Closed Group", comment: ""), customFontSize: customTitleFontSize) // Set up navigation bar buttons let closeButton = UIBarButtonItem(image: #imageLiteral(resourceName: "X"), style: .plain, target: self, action: #selector(close)) closeButton.tintColor = Colors.text diff --git a/SignalServiceKit/src/Loki/Protocol/Closed Groups/ClosedGroupsProtocol.swift b/SignalServiceKit/src/Loki/Protocol/Closed Groups/ClosedGroupsProtocol.swift index ec5a18a7f..13c9275aa 100644 --- a/SignalServiceKit/src/Loki/Protocol/Closed Groups/ClosedGroupsProtocol.swift +++ b/SignalServiceKit/src/Loki/Protocol/Closed Groups/ClosedGroupsProtocol.swift @@ -38,6 +38,7 @@ public final class ClosedGroupsProtocol : NSObject { guard hexEncodedPublicKey != getUserHexEncodedPublicKey() else { return } let hasSession = storage.containsSession(hexEncodedPublicKey, deviceId: Int32(OWSDevicePrimaryDeviceId), protocolContext: transaction) guard !hasSession else { return } + print("[Loki] Establishing session with: \(hexEncodedPublicKey).") let thread = TSContactThread.getOrCreateThread(withContactId: hexEncodedPublicKey, transaction: transaction) thread.save(with: transaction) let sessionRequestMessage = SessionRequestMessage(thread: thread) diff --git a/SignalServiceKit/src/Loki/Protocol/Multi Device/MultiDeviceProtocol.swift b/SignalServiceKit/src/Loki/Protocol/Multi Device/MultiDeviceProtocol.swift index b1e740029..6d6e0d4dd 100644 --- a/SignalServiceKit/src/Loki/Protocol/Multi Device/MultiDeviceProtocol.swift +++ b/SignalServiceKit/src/Loki/Protocol/Multi Device/MultiDeviceProtocol.swift @@ -9,6 +9,9 @@ import PromiseKit // • Document the expected cases for everything. // • Express those cases in tests. +// FIXME: We're manually attaching the sender certificate and UD recipient access to message sends in a lot of places. It'd be great +// to clean this up and just do it in one spot. + @objc(LKMultiDeviceProtocol) public final class MultiDeviceProtocol : NSObject { @@ -46,9 +49,15 @@ public final class MultiDeviceProtocol : NSObject { storage.dbReadConnection.read { transaction in recipient = SignalRecipient.getOrBuildUnsavedRecipient(forRecipientId: destination.hexEncodedPublicKey, transaction: transaction) } - // TODO: Why is it okay that the thread, sender certificate, etc. don't get changed? + let udManager = SSKEnvironment.shared.udManager + let senderCertificate = udManager.getSenderCertificate() + var recipientUDAccess: OWSUDAccess? + if let senderCertificate = senderCertificate { + recipientUDAccess = udManager.udAccess(forRecipientId: destination.hexEncodedPublicKey, requireSyncAccess: true) // Starts a new write transaction internally + } + // TODO: Why is it okay that the thread doesn't get changed? return OWSMessageSend(message: messageSend.message, thread: messageSend.thread, recipient: recipient, - senderCertificate: messageSend.senderCertificate, udAccess: messageSend.udAccess, localNumber: messageSend.localNumber, success: { + senderCertificate: senderCertificate, udAccess: recipientUDAccess, localNumber: messageSend.localNumber, success: { seal.fulfill(()) }, failure: { error in seal.reject(error) @@ -70,7 +79,7 @@ public final class MultiDeviceProtocol : NSObject { } } } - return threadPromise.then(on: OWSDispatch.sendingQueue()) { thread -> Promise in + return threadPromise.then(on: DispatchQueue.main) { thread -> Promise in // Intentionally the main queue let message = messageSend.message let messageSender = SSKEnvironment.shared.messageSender let (promise, seal) = Promise.pending() @@ -79,15 +88,14 @@ public final class MultiDeviceProtocol : NSObject { && message.shouldBeSaved() // shouldBeSaved indicates it isn't a transient message if !shouldSendAutoGeneratedFR { let messageSendCopy = copy(messageSend, for: destination, with: seal) - messageSender.sendMessage(messageSendCopy) + OWSDispatch.sendingQueue().async { + messageSender.sendMessage(messageSendCopy) + } } else { - // Dispatch async on the main queue to avoid nested write transactions - DispatchQueue.main.async { - storage.dbReadWriteConnection.readWrite { transaction in - getAutoGeneratedMultiDeviceFRMessageSend(for: destination.hexEncodedPublicKey, in: transaction, seal: seal) - .done(on: OWSDispatch.sendingQueue()) { autoGeneratedFRMessageSend in - messageSender.sendMessage(autoGeneratedFRMessageSend) - } + storage.dbReadWriteConnection.readWrite { transaction in + getAutoGeneratedMultiDeviceFRMessageSend(for: destination.hexEncodedPublicKey, in: transaction, seal: seal) + .done(on: OWSDispatch.sendingQueue()) { autoGeneratedFRMessageSend in + messageSender.sendMessage(autoGeneratedFRMessageSend) } } } @@ -137,10 +145,20 @@ public final class MultiDeviceProtocol : NSObject { messageSend.failure(errors.first!) } } - }.catch(on: OWSDispatch.sendingQueue()) { error in + }.catch(on: DispatchQueue.main) { error in // Intentionally the main queue // Proceed even if updating the recipient's device links failed, so that message sending // is independent of whether the file server is online - messageSender.sendMessage(messageSend) + let udManager = SSKEnvironment.shared.udManager + let senderCertificate = udManager.getSenderCertificate() + var recipientUDAccess: OWSUDAccess? + if let senderCertificate = senderCertificate { + recipientUDAccess = udManager.udAccess(forRecipientId: recipientID, requireSyncAccess: true) // Starts a new write transaction internally + } + messageSend.senderCertificate = senderCertificate + messageSend.udAccess = recipientUDAccess + OWSDispatch.sendingQueue().async { + messageSender.sendMessage(messageSend) + } } } diff --git a/SignalServiceKit/src/Loki/Protocol/Session Management/SessionManagementProtocol.swift b/SignalServiceKit/src/Loki/Protocol/Session Management/SessionManagementProtocol.swift index d34af79aa..47f8239d8 100644 --- a/SignalServiceKit/src/Loki/Protocol/Session Management/SessionManagementProtocol.swift +++ b/SignalServiceKit/src/Loki/Protocol/Session Management/SessionManagementProtocol.swift @@ -141,8 +141,14 @@ public final class SessionManagementProtocol : NSObject { @objc(repairSessionIfNeededForMessage:to:) public static func repairSessionIfNeeded(for message: TSOutgoingMessage, to hexEncodedPublicKey: String) { guard (message.thread as? TSGroupThread)?.groupModel.groupType == .closedGroup else { return } + var hasSentSessionRequest = false + storage.dbReadConnection.read { transaction in + hasSentSessionRequest = storage.getSessionRequestTimestamp(for: hexEncodedPublicKey, in: transaction) != nil + } + guard !hasSentSessionRequest else { return } DispatchQueue.main.async { storage.dbReadWriteConnection.readWrite { transaction in + print("[Loki] Repairing session with: \(hexEncodedPublicKey).") let thread = TSContactThread.getOrCreateThread(withContactId: hexEncodedPublicKey, transaction: transaction) let sessionRequestMessage = SessionRequestMessage(thread: thread) storage.setSessionRequestTimestamp(for: hexEncodedPublicKey, to: Date(), in: transaction) @@ -196,6 +202,7 @@ public final class SessionManagementProtocol : NSObject { if let sentSessionRequestTimestamp = storage.getSessionRequestTimestamp(for: hexEncodedPublicKey, in: transaction), envelope.timestamp < NSDate.ows_millisecondsSince1970(for: sentSessionRequestTimestamp) { // We sent a session request after this one was sent + print("[Loki] Ignoring session request from: \(hexEncodedPublicKey).") return } var closedGroupMembers: Set = [] diff --git a/SignalServiceKit/src/Messages/OWSMessageDecrypter.m b/SignalServiceKit/src/Messages/OWSMessageDecrypter.m index cbf8f3024..37f221b1a 100644 --- a/SignalServiceKit/src/Messages/OWSMessageDecrypter.m +++ b/SignalServiceKit/src/Messages/OWSMessageDecrypter.m @@ -580,7 +580,6 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes return; } - OWSFailDebug(@"Could not decrypt UD message: %@.", underlyingError); failureBlock(underlyingError); return; } diff --git a/SignalServiceKit/src/Messages/OWSMessageSender.m b/SignalServiceKit/src/Messages/OWSMessageSender.m index a97455404..25badad67 100644 --- a/SignalServiceKit/src/Messages/OWSMessageSender.m +++ b/SignalServiceKit/src/Messages/OWSMessageSender.m @@ -610,11 +610,9 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; }]; if ([LKMultiDeviceProtocol isMultiDeviceRequiredForMessage:message]) { // Avoid the write transaction if possible - dispatch_async(dispatch_get_main_queue(), ^{ - [self.primaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - [LKMultiDeviceProtocol sendMessageToDestinationAndLinkedDevices:messageSend in:transaction]; - }]; - }); + [self.primaryStorage.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { + [LKMultiDeviceProtocol sendMessageToDestinationAndLinkedDevices:messageSend in:transaction]; + }]; } else { [self sendMessage:messageSend]; } @@ -930,6 +928,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; { OWSAssertDebug(messageSend); OWSAssertDebug(messageSend.thread || [messageSend.message isKindOfClass:[OWSOutgoingSyncMessage class]]); + OWSAssertDebug(messageSend.isUDSend); TSOutgoingMessage *message = messageSend.message; SignalRecipient *recipient = messageSend.recipient; From e9fc5b748e54f6512d62b2cd4e4de1883e7f4970 Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Thu, 11 Jun 2020 12:12:42 +1000 Subject: [PATCH 09/19] Integrate transaction handling utility part 1 --- .../src/Loki/Shelved/LokiRSSFeedPoller.swift | 2 +- .../View Controllers/DeviceLinkingModal.swift | 9 ++- .../Loki/View Controllers/DeviceLinksVC.swift | 4 +- .../View Controllers/JoinPublicChatVC.swift | 2 +- .../src/Loki/API/LokiAPI+SwarmAPI.swift | 40 ++++--------- SignalServiceKit/src/Loki/API/LokiAPI.swift | 6 +- .../src/Loki/API/LokiDotNetAPI.swift | 14 ++--- .../src/Loki/API/LokiFileServerAPI.swift | 34 ++--------- .../API/Onion Requests/OnionRequestAPI.swift | 18 ++---- .../API/Open Groups/LokiPublicChatAPI.swift | 12 ++-- .../Open Groups/LokiPublicChatManager.swift | 4 +- .../Open Groups/LokiPublicChatPoller.swift | 7 +-- .../Database/OWSPrimaryStorage+Loki.swift | 56 ++++++------------- .../Multi Device/MultiDeviceProtocol.swift | 20 +++---- .../SessionManagementProtocol.swift | 16 +++--- 15 files changed, 80 insertions(+), 164 deletions(-) diff --git a/Signal/src/Loki/Shelved/LokiRSSFeedPoller.swift b/Signal/src/Loki/Shelved/LokiRSSFeedPoller.swift index 62a0d0341..f29e3a884 100644 --- a/Signal/src/Loki/Shelved/LokiRSSFeedPoller.swift +++ b/Signal/src/Loki/Shelved/LokiRSSFeedPoller.swift @@ -63,7 +63,7 @@ public final class LokiRSSFeedPoller : NSObject { envelope.setSource(NSLocalizedString("Loki", comment: "")) envelope.setSourceDevice(OWSDevicePrimaryDeviceId) envelope.setContent(try! content.build().serializedData()) - OWSPrimaryStorage.shared().dbReadWriteConnection.readWrite { transaction in + try! Storage.syncWrite { transaction in SSKEnvironment.shared.messageManager.throws_processEnvelope(try! envelope.build(), plaintextData: try! content.build().serializedData(), wasReceivedByUD: false, transaction: transaction, serverID: 0) } } diff --git a/Signal/src/Loki/View Controllers/DeviceLinkingModal.swift b/Signal/src/Loki/View Controllers/DeviceLinkingModal.swift index b35c590a6..5aa389ca1 100644 --- a/Signal/src/Loki/View Controllers/DeviceLinkingModal.swift +++ b/Signal/src/Loki/View Controllers/DeviceLinkingModal.swift @@ -186,7 +186,7 @@ final class DeviceLinkingModal : Modal, DeviceLinkingSessionDelegate { SSKEnvironment.shared.messageSender.send(linkingAuthorizationMessage, success: { let storage = OWSPrimaryStorage.shared() let slaveHexEncodedPublicKey = deviceLink.slave.hexEncodedPublicKey - storage.dbReadWriteConnection.readWrite { transaction in + try! Storage.syncWrite { transaction in let thread = TSContactThread.getOrCreateThread(withContactId: slaveHexEncodedPublicKey, transaction: transaction) thread.save(with: transaction) } @@ -196,7 +196,7 @@ final class DeviceLinkingModal : Modal, DeviceLinkingSessionDelegate { let _ = SSKEnvironment.shared.syncManager.syncAllContacts() } let _ = SSKEnvironment.shared.syncManager.syncAllOpenGroups() - storage.dbReadWriteConnection.readWrite { transaction in + try! Storage.syncWrite { transaction in storage.setFriendRequestStatus(.friends, for: slaveHexEncodedPublicKey, transaction: transaction) } DispatchQueue.main.async { @@ -251,9 +251,8 @@ final class DeviceLinkingModal : Modal, DeviceLinkingSessionDelegate { session.markLinkingRequestAsProcessed() // Only relevant in master mode delegate?.handleDeviceLinkingModalDismissed() // Only relevant in slave mode if let deviceLink = deviceLink { - let storage = OWSPrimaryStorage.shared() - storage.dbReadWriteConnection.readWrite { transaction in - storage.removePreKeyBundle(forContact: deviceLink.slave.hexEncodedPublicKey, transaction: transaction) + try! Storage.syncWrite { transaction in + OWSPrimaryStorage.shared().removePreKeyBundle(forContact: deviceLink.slave.hexEncodedPublicKey, transaction: transaction) } } dismiss(animated: true, completion: nil) diff --git a/Signal/src/Loki/View Controllers/DeviceLinksVC.swift b/Signal/src/Loki/View Controllers/DeviceLinksVC.swift index 167a72303..85554b380 100644 --- a/Signal/src/Loki/View Controllers/DeviceLinksVC.swift +++ b/Signal/src/Loki/View Controllers/DeviceLinksVC.swift @@ -146,14 +146,14 @@ final class DeviceLinksVC : BaseVC, UITableViewDataSource, UITableViewDelegate, let unlinkDeviceMessage = UnlinkDeviceMessage(thread: thread) SSKEnvironment.shared.messageSender.send(unlinkDeviceMessage, success: { let storage = OWSPrimaryStorage.shared() - storage.dbReadWriteConnection.readWrite { transaction in + try! Storage.syncWrite { transaction in storage.removePreKeyBundle(forContact: linkedDeviceHexEncodedPublicKey, transaction: transaction) storage.deleteAllSessions(forContact: linkedDeviceHexEncodedPublicKey, protocolContext: transaction) } }, failure: { _ in print("[Loki] Failed to send unlink device message.") let storage = OWSPrimaryStorage.shared() - storage.dbReadWriteConnection.readWrite { transaction in + try! Storage.syncWrite { transaction in storage.removePreKeyBundle(forContact: linkedDeviceHexEncodedPublicKey, transaction: transaction) storage.deleteAllSessions(forContact: linkedDeviceHexEncodedPublicKey, protocolContext: transaction) } diff --git a/Signal/src/Loki/View Controllers/JoinPublicChatVC.swift b/Signal/src/Loki/View Controllers/JoinPublicChatVC.swift index 149ca58c8..9b0ad0188 100644 --- a/Signal/src/Loki/View Controllers/JoinPublicChatVC.swift +++ b/Signal/src/Loki/View Controllers/JoinPublicChatVC.swift @@ -135,7 +135,7 @@ final class JoinPublicChatVC : BaseVC, UIPageViewControllerDataSource, UIPageVie let urlAsString = url.absoluteString let displayName = OWSProfileManager.shared().localProfileName() // TODO: Profile picture & profile key - OWSPrimaryStorage.shared().dbReadWriteConnection.readWrite { transaction in + try! Storage.syncWrite { transaction in transaction.removeObject(forKey: "\(urlAsString).\(channelID)", inCollection: LokiPublicChatAPI.lastMessageServerIDCollection) transaction.removeObject(forKey: "\(urlAsString).\(channelID)", inCollection: LokiPublicChatAPI.lastDeletionServerIDCollection) } diff --git a/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift b/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift index 4cf2d374d..800758a59 100644 --- a/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift +++ b/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift @@ -53,12 +53,9 @@ public extension LokiAPI { } }.done(on: DispatchQueue.global()) { snode in seal.fulfill(snode) - // Dispatch async on the main queue to avoid nested write transactions - DispatchQueue.main.async { - storage.dbReadWriteConnection.readWrite { transaction in - print("[Loki] Persisting snode pool to database.") - storage.setSnodePool(LokiAPI.snodePool, in: transaction) - } + try! Storage.syncWrite { transaction in + print("[Loki] Persisting snode pool to database.") + storage.setSnodePool(LokiAPI.snodePool, in: transaction) } }.catch(on: DispatchQueue.global()) { error in print("[Loki] Failed to contact seed node at: \(target).") @@ -90,12 +87,8 @@ public extension LokiAPI { parseTargets(from: $0) }.get { swarm in swarmCache[hexEncodedPublicKey] = swarm - // Dispatch async on the main queue to avoid nested write transactions - DispatchQueue.main.async { - let storage = OWSPrimaryStorage.shared() - storage.dbReadWriteConnection.readWrite { transaction in - storage.setSwarm(swarm, for: hexEncodedPublicKey, in: transaction) - } + try! Storage.syncWrite { transaction in + storage.setSwarm(swarm, for: hexEncodedPublicKey, in: transaction) } } } @@ -108,12 +101,8 @@ public extension LokiAPI { internal static func dropSnodeFromSnodePool(_ target: LokiAPITarget) { LokiAPI.snodePool.remove(target) - // Dispatch async on the main queue to avoid nested write transactions - DispatchQueue.main.async { - let storage = OWSPrimaryStorage.shared() - storage.dbReadWriteConnection.readWrite { transaction in - storage.dropSnodeFromSnodePool(target, in: transaction) - } + try! Storage.syncWrite { transaction in + storage.dropSnodeFromSnodePool(target, in: transaction) } } @@ -122,12 +111,8 @@ public extension LokiAPI { if var swarm = swarm, let index = swarm.firstIndex(of: target) { swarm.remove(at: index) LokiAPI.swarmCache[hexEncodedPublicKey] = swarm - // Dispatch async on the main queue to avoid nested write transactions - DispatchQueue.main.async { - let storage = OWSPrimaryStorage.shared() - storage.dbReadWriteConnection.readWrite { transaction in - storage.setSwarm(swarm, for: hexEncodedPublicKey, in: transaction) - } + try! Storage.syncWrite { transaction in + storage.setSwarm(swarm, for: hexEncodedPublicKey, in: transaction) } } } @@ -135,11 +120,8 @@ public extension LokiAPI { // MARK: Public API @objc public static func clearSnodePool() { snodePool.removeAll() - // Dispatch async on the main queue to avoid nested write transactions - DispatchQueue.main.async { - storage.dbReadWriteConnection.readWrite { transaction in - storage.clearSnodePool(in: transaction) - } + try! Storage.syncWrite { transaction in + storage.clearSnodePool(in: transaction) } } diff --git a/SignalServiceKit/src/Loki/API/LokiAPI.swift b/SignalServiceKit/src/Loki/API/LokiAPI.swift index 4bd85fc5b..e8cdd58e9 100644 --- a/SignalServiceKit/src/Loki/API/LokiAPI.swift +++ b/SignalServiceKit/src/Loki/API/LokiAPI.swift @@ -194,14 +194,14 @@ public final class LokiAPI : NSObject { var result: String? = nil // Uses a read/write connection because getting the last message hash value also removes expired messages as needed // TODO: This shouldn't be the case; a getter shouldn't have an unexpected side effect - storage.dbReadWriteConnection.readWrite { transaction in + try! Storage.syncWrite { transaction in result = storage.getLastMessageHash(forSnode: target.address, transaction: transaction) } return result } private static func setLastMessageHashValue(for target: LokiAPITarget, hashValue: String, expirationDate: UInt64) { - storage.dbReadWriteConnection.readWrite { transaction in + try! Storage.syncWrite { transaction in storage.setLastMessageHash(forSnode: target.address, hash: hashValue, expiresAt: expirationDate, transaction: transaction) } } @@ -218,7 +218,7 @@ public final class LokiAPI : NSObject { } private static func setReceivedMessageHashValues(to receivedMessageHashValues: Set) { - storage.dbReadWriteConnection.readWrite { transaction in + try! Storage.syncWrite { transaction in transaction.setObject(receivedMessageHashValues, forKey: receivedMessageHashValuesKey, inCollection: receivedMessageHashValuesCollection) } } diff --git a/SignalServiceKit/src/Loki/API/LokiDotNetAPI.swift b/SignalServiceKit/src/Loki/API/LokiDotNetAPI.swift index 08071be7f..22cc15947 100644 --- a/SignalServiceKit/src/Loki/API/LokiDotNetAPI.swift +++ b/SignalServiceKit/src/Loki/API/LokiDotNetAPI.swift @@ -38,11 +38,8 @@ public class LokiDotNetAPI : NSObject { return Promise.value(token) } else { return requestNewAuthToken(for: server).then(on: DispatchQueue.global()) { submitAuthToken($0, for: server) }.map(on: DispatchQueue.global()) { token in - // Dispatch async on the main queue to avoid nested write transactions - DispatchQueue.main.async { - storage.dbReadWriteConnection.readWrite { transaction in - setAuthToken(for: server, to: token, in: transaction) - } + try! Storage.syncWrite { transaction in + setAuthToken(for: server, to: token, in: transaction) } return token } @@ -54,11 +51,8 @@ public class LokiDotNetAPI : NSObject { } public static func clearAuthToken(for server: String) { - // Dispatch async on the main queue to avoid nested write transactions - DispatchQueue.main.async { - storage.dbReadWriteConnection.readWrite { transaction in - transaction.removeObject(forKey: server, inCollection: authTokenCollection) - } + try! Storage.syncWrite { transaction in + transaction.removeObject(forKey: server, inCollection: authTokenCollection) } } diff --git a/SignalServiceKit/src/Loki/API/LokiFileServerAPI.swift b/SignalServiceKit/src/Loki/API/LokiFileServerAPI.swift index f50b18dfc..d0eabc4dc 100644 --- a/SignalServiceKit/src/Loki/API/LokiFileServerAPI.swift +++ b/SignalServiceKit/src/Loki/API/LokiFileServerAPI.swift @@ -81,15 +81,7 @@ public final class LokiFileServerAPI : LokiDotNetAPI { } }) }.map(on: DispatchQueue.global()) { deviceLinks in - storage.cacheDeviceLinks(deviceLinks) - /* - // Dispatch async on the main queue to avoid nested write transactions - DispatchQueue.main.async { - storage.dbReadWriteConnection.readWrite { transaction in - storage.setDeviceLinks(deviceLinks, in: transaction) - } - } - */ + storage.setDeviceLinks(deviceLinks) return deviceLinks } }.handlingInvalidAuthTokenIfNeeded(for: server) @@ -122,16 +114,8 @@ public final class LokiFileServerAPI : LokiDotNetAPI { deviceLinks = storage.getDeviceLinks(for: getUserHexEncodedPublicKey(), in: transaction) } deviceLinks.insert(deviceLink) - return setDeviceLinks(deviceLinks).then(on: LokiAPI.workQueue) { _ -> Promise in - let (promise, seal) = Promise.pending() - // Dispatch async on the main queue to avoid nested write transactions - DispatchQueue.main.async { - storage.dbReadWriteConnection.readWrite { transaction in - storage.addDeviceLink(deviceLink, in: transaction) - } - seal.fulfill(()) - } - return promise + return setDeviceLinks(deviceLinks).map(on: LokiAPI.workQueue) { _ in + storage.addDeviceLink(deviceLink) } } @@ -142,16 +126,8 @@ public final class LokiFileServerAPI : LokiDotNetAPI { deviceLinks = storage.getDeviceLinks(for: getUserHexEncodedPublicKey(), in: transaction) } deviceLinks.remove(deviceLink) - return setDeviceLinks(deviceLinks).then(on: LokiAPI.workQueue) { _ -> Promise in - let (promise, seal) = Promise.pending() - // Dispatch async on the main queue to avoid nested write transactions - DispatchQueue.main.async { - storage.dbReadWriteConnection.readWrite { transaction in - storage.removeDeviceLink(deviceLink, in: transaction) - } - seal.fulfill(()) - } - return promise + return setDeviceLinks(deviceLinks).map(on: LokiAPI.workQueue) { _ in + storage.removeDeviceLink(deviceLink) } } diff --git a/SignalServiceKit/src/Loki/API/Onion Requests/OnionRequestAPI.swift b/SignalServiceKit/src/Loki/API/Onion Requests/OnionRequestAPI.swift index 585a1b085..9ed5fb6f7 100644 --- a/SignalServiceKit/src/Loki/API/Onion Requests/OnionRequestAPI.swift +++ b/SignalServiceKit/src/Loki/API/Onion Requests/OnionRequestAPI.swift @@ -123,13 +123,11 @@ public enum OnionRequestAPI { } }.map(on: LokiAPI.workQueue) { paths in OnionRequestAPI.paths = paths - // Dispatch async on the main queue to avoid nested write transactions + try! Storage.syncWrite { transaction in + print("[Loki] Persisting onion request paths to database.") + OWSPrimaryStorage.shared().setOnionRequestPaths(paths, in: transaction) + } DispatchQueue.main.async { - let storage = OWSPrimaryStorage.shared() - storage.dbReadWriteConnection.readWrite { transaction in - print("[Loki] Persisting onion request paths to database.") - storage.setOnionRequestPaths(paths, in: transaction) - } NotificationCenter.default.post(name: .pathsBuilt, object: nil) } return paths @@ -165,12 +163,8 @@ public enum OnionRequestAPI { private static func dropAllPaths() { paths.removeAll() - // Dispatch async on the main queue to avoid nested write transactions - DispatchQueue.main.async { - let storage = OWSPrimaryStorage.shared() - storage.dbReadWriteConnection.readWrite { transaction in - storage.clearOnionRequestPaths(in: transaction) - } + try! Storage.syncWrite { transaction in + OWSPrimaryStorage.shared().clearOnionRequestPaths(in: transaction) } } diff --git a/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatAPI.swift b/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatAPI.swift index d58ce8356..815002664 100644 --- a/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatAPI.swift +++ b/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatAPI.swift @@ -37,13 +37,13 @@ public final class LokiPublicChatAPI : LokiDotNetAPI { } private static func setLastMessageServerID(for group: UInt64, on server: String, to newValue: UInt64) { - storage.dbReadWriteConnection.readWrite { transaction in + try! Storage.syncWrite { transaction in transaction.setObject(newValue, forKey: "\(server).\(group)", inCollection: lastMessageServerIDCollection) } } private static func removeLastMessageServerID(for group: UInt64, on server: String) { - storage.dbReadWriteConnection.readWrite { transaction in + try! Storage.syncWrite { transaction in transaction.removeObject(forKey: "\(server).\(group)", inCollection: lastMessageServerIDCollection) } } @@ -57,13 +57,13 @@ public final class LokiPublicChatAPI : LokiDotNetAPI { } private static func setLastDeletionServerID(for group: UInt64, on server: String, to newValue: UInt64) { - storage.dbReadWriteConnection.readWrite { transaction in + try! Storage.syncWrite { transaction in transaction.setObject(newValue, forKey: "\(server).\(group)", inCollection: lastDeletionServerIDCollection) } } private static func removeLastDeletionServerID(for group: UInt64, on server: String) { - storage.dbReadWriteConnection.readWrite { transaction in + try! Storage.syncWrite { transaction in transaction.removeObject(forKey: "\(server).\(group)", inCollection: lastDeletionServerIDCollection) } } @@ -271,7 +271,7 @@ public final class LokiPublicChatAPI : LokiDotNetAPI { print("[Loki] Couldn't parse display names for users: \(hexEncodedPublicKeys) from: \(rawResponse).") throw LokiDotNetAPIError.parsingFailed } - storage.dbReadWriteConnection.readWrite { transaction in + try! Storage.syncWrite { transaction in data.forEach { data in guard let user = data["user"] as? JSON, let hexEncodedPublicKey = user["username"] as? String, let rawDisplayName = user["name"] as? String else { return } let endIndex = hexEncodedPublicKey.endIndex @@ -355,7 +355,7 @@ public final class LokiPublicChatAPI : LokiDotNetAPI { throw LokiDotNetAPIError.parsingFailed } let storage = OWSPrimaryStorage.shared() - storage.dbReadWriteConnection.readWrite { transaction in + try! Storage.syncWrite { transaction in storage.setUserCount(memberCount, forPublicChatWithID: "\(server).\(channel)", in: transaction) } // TODO: Use this to update open group names as needed diff --git a/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatManager.swift b/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatManager.swift index 1d1bf5e0e..a04e20975 100644 --- a/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatManager.swift +++ b/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatManager.swift @@ -71,7 +71,7 @@ public final class LokiPublicChatManager : NSObject { let model = TSGroupModel(title: chat.displayName, memberIds: [userHexEncodedPublicKey!, chat.server], image: nil, groupId: LKGroupUtilities.getEncodedOpenGroupIDAsData(chat.id), groupType: .openGroup, adminIds: []) // Store the group chat mapping - self.storage.dbReadWriteConnection.readWrite { transaction in + try! Storage.syncWrite { transaction in let thread = TSGroupThread.getOrCreateThread(with: model, transaction: transaction) // Save the group chat @@ -118,7 +118,7 @@ public final class LokiPublicChatManager : NSObject { } // Remove the chat from the db - storage.dbReadWriteConnection.readWrite { transaction in + try! Storage.syncWrite { transaction in LokiDatabaseUtilities.removePublicChat(for: threadId, in: transaction) } diff --git a/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatPoller.swift b/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatPoller.swift index 974eb814b..9182ce78d 100644 --- a/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatPoller.swift +++ b/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatPoller.swift @@ -163,7 +163,7 @@ public final class LokiPublicChatPoller : NSObject { envelope.setSource(senderHexEncodedPublicKey) envelope.setSourceDevice(OWSDevicePrimaryDeviceId) envelope.setContent(try! content.build().serializedData()) - storage.dbReadWriteConnection.readWrite { transaction in + try! Storage.syncWrite { transaction in transaction.setObject(senderDisplayName, forKey: senderHexEncodedPublicKey, inCollection: publicChat.id) let messageServerID = message.serverID SSKEnvironment.shared.messageManager.throws_processEnvelope(try! envelope.build(), plaintextData: try! content.build().serializedData(), wasReceivedByUD: false, transaction: transaction, serverID: messageServerID ?? 0) @@ -213,9 +213,8 @@ public final class LokiPublicChatPoller : NSObject { private func pollForDeletedMessages() { let publicChat = self.publicChat let _ = LokiPublicChatAPI.getDeletedMessageServerIDs(for: publicChat.channel, on: publicChat.server).done(on: DispatchQueue.global()) { deletedMessageServerIDs in - let storage = OWSPrimaryStorage.shared() - storage.dbReadWriteConnection.readWrite { transaction in - let deletedMessageIDs = deletedMessageServerIDs.compactMap { storage.getIDForMessage(withServerID: UInt($0), in: transaction) } + try! Storage.syncWrite { transaction in + let deletedMessageIDs = deletedMessageServerIDs.compactMap { OWSPrimaryStorage.shared().getIDForMessage(withServerID: UInt($0), in: transaction) } deletedMessageIDs.forEach { messageID in TSMessage.fetch(uniqueId: messageID)?.remove(with: transaction) } diff --git a/SignalServiceKit/src/Loki/Database/OWSPrimaryStorage+Loki.swift b/SignalServiceKit/src/Loki/Database/OWSPrimaryStorage+Loki.swift index c69a996a5..f4d07f4ab 100644 --- a/SignalServiceKit/src/Loki/Database/OWSPrimaryStorage+Loki.swift +++ b/SignalServiceKit/src/Loki/Database/OWSPrimaryStorage+Loki.swift @@ -4,22 +4,20 @@ public extension OWSPrimaryStorage { // MARK: - Snode Pool - private static let snodePoolCollection = "LokiSnodePoolCollection" - public func setSnodePool(_ snodePool: Set, in transaction: YapDatabaseReadWriteTransaction) { clearSnodePool(in: transaction) snodePool.forEach { snode in - transaction.setObject(snode, forKey: snode.description, inCollection: OWSPrimaryStorage.snodePoolCollection) + transaction.setObject(snode, forKey: snode.description, inCollection: Storage.snodePoolCollection) } } public func clearSnodePool(in transaction: YapDatabaseReadWriteTransaction) { - transaction.removeAllObjects(inCollection: OWSPrimaryStorage.snodePoolCollection) + transaction.removeAllObjects(inCollection: Storage.snodePoolCollection) } public func getSnodePool(in transaction: YapDatabaseReadTransaction) -> Set { var result: Set = [] - transaction.enumerateKeysAndObjects(inCollection: OWSPrimaryStorage.snodePoolCollection) { _, object, _ in + transaction.enumerateKeysAndObjects(inCollection: Storage.snodePoolCollection) { _, object, _ in guard let snode = object as? LokiAPITarget else { return } result.insert(snode) } @@ -27,33 +25,29 @@ public extension OWSPrimaryStorage { } public func dropSnodeFromSnodePool(_ snode: LokiAPITarget, in transaction: YapDatabaseReadWriteTransaction) { - transaction.removeObject(forKey: snode.description, inCollection: OWSPrimaryStorage.snodePoolCollection) + transaction.removeObject(forKey: snode.description, inCollection: Storage.snodePoolCollection) } // MARK: - Swarm - private func getSwarmCollection(for publicKey: String) -> String { - return "LokiSwarmCollection-\(publicKey)" - } - public func setSwarm(_ swarm: [Snode], for publicKey: String, in transaction: YapDatabaseReadWriteTransaction) { print("[Loki] Caching swarm for: \(publicKey).") clearSwarm(for: publicKey, in: transaction) - let collection = getSwarmCollection(for: publicKey) + let collection = Storage.getSwarmCollection(for: publicKey) swarm.forEach { snode in transaction.setObject(snode, forKey: snode.description, inCollection: collection) } } public func clearSwarm(for publicKey: String, in transaction: YapDatabaseReadWriteTransaction) { - let collection = getSwarmCollection(for: publicKey) + let collection = Storage.getSwarmCollection(for: publicKey) transaction.removeAllObjects(inCollection: collection) } public func getSwarm(for publicKey: String, in transaction: YapDatabaseReadTransaction) -> [Snode] { var result: [Snode] = [] - let collection = getSwarmCollection(for: publicKey) + let collection = Storage.getSwarmCollection(for: publicKey) transaction.enumerateKeysAndObjects(inCollection: collection) { _, object, _ in guard let snode = object as? Snode else { return } result.append(snode) @@ -64,15 +58,13 @@ public extension OWSPrimaryStorage { // MARK: - Onion Request Paths - private static let onionRequestPathCollection = "LokiOnionRequestPathCollection" - public func setOnionRequestPaths(_ paths: [OnionRequestAPI.Path], in transaction: YapDatabaseReadWriteTransaction) { // FIXME: This is a bit of a dirty approach that assumes 2 paths of length 3 each. We should do better than this. guard paths.count == 2 else { return } let path0 = paths[0] let path1 = paths[1] guard path0.count == 3, path1.count == 3 else { return } - let collection = OWSPrimaryStorage.onionRequestPathCollection + let collection = Storage.onionRequestPathCollection transaction.setObject(path0[0], forKey: "0-0", inCollection: collection) transaction.setObject(path0[1], forKey: "0-1", inCollection: collection) transaction.setObject(path0[2], forKey: "0-2", inCollection: collection) @@ -82,7 +74,7 @@ public extension OWSPrimaryStorage { } public func getOnionRequestPaths(in transaction: YapDatabaseReadTransaction) -> [OnionRequestAPI.Path] { - let collection = OWSPrimaryStorage.onionRequestPathCollection + let collection = Storage.onionRequestPathCollection guard let path0Snode0 = transaction.object(forKey: "0-0", inCollection: collection) as? LokiAPITarget, let path0Snode1 = transaction.object(forKey: "0-1", inCollection: collection) as? LokiAPITarget, @@ -94,20 +86,18 @@ public extension OWSPrimaryStorage { } public func clearOnionRequestPaths(in transaction: YapDatabaseReadWriteTransaction) { - transaction.removeAllObjects(inCollection: OWSPrimaryStorage.onionRequestPathCollection) + transaction.removeAllObjects(inCollection: Storage.onionRequestPathCollection) } // MARK: - Session Requests - private static let sessionRequestTimestampCollection = "LokiSessionRequestTimestampCollection" - public func setSessionRequestTimestamp(for publicKey: String, to timestamp: Date, in transaction: YapDatabaseReadWriteTransaction) { - transaction.setDate(timestamp, forKey: publicKey, inCollection: OWSPrimaryStorage.sessionRequestTimestampCollection) + transaction.setDate(timestamp, forKey: publicKey, inCollection: Storage.sessionRequestTimestampCollection) } public func getSessionRequestTimestamp(for publicKey: String, in transaction: YapDatabaseReadTransaction) -> Date? { - transaction.date(forKey: publicKey, inCollection: OWSPrimaryStorage.sessionRequestTimestampCollection) + transaction.date(forKey: publicKey, inCollection: Storage.sessionRequestTimestampCollection) } @@ -115,23 +105,15 @@ public extension OWSPrimaryStorage { // MARK: - Multi Device private static var deviceLinkCache: Set = [] - private func getDeviceLinkCollection(for masterHexEncodedPublicKey: String) -> String { - return "LokiDeviceLinkCollection-\(masterHexEncodedPublicKey)" - } - - public func cacheDeviceLinks(_ deviceLinks: Set) { - OWSPrimaryStorage.deviceLinkCache.formUnion(deviceLinks) + public func setDeviceLinks(_ deviceLinks: Set) { + deviceLinks.forEach { addDeviceLink($0) } } - public func setDeviceLinks(_ deviceLinks: Set, in transaction: YapDatabaseReadWriteTransaction) { - deviceLinks.forEach { addDeviceLink($0, in: transaction) } - } - - public func addDeviceLink(_ deviceLink: DeviceLink, in transaction: YapDatabaseReadWriteTransaction) { + public func addDeviceLink(_ deviceLink: DeviceLink) { OWSPrimaryStorage.deviceLinkCache.insert(deviceLink) } - public func removeDeviceLink(_ deviceLink: DeviceLink, in transaction: YapDatabaseReadWriteTransaction) { + public func removeDeviceLink(_ deviceLink: DeviceLink) { OWSPrimaryStorage.deviceLinkCache.remove(deviceLink) } @@ -150,13 +132,11 @@ public extension OWSPrimaryStorage { // MARK: - Open Groups - private static let openGroupUserCountCollection = "LokiPublicChatUserCountCollection" - public func getUserCount(for publicChat: LokiPublicChat, in transaction: YapDatabaseReadTransaction) -> Int? { - return transaction.object(forKey: publicChat.id, inCollection: OWSPrimaryStorage.openGroupUserCountCollection) as? Int + return transaction.object(forKey: publicChat.id, inCollection: Storage.openGroupUserCountCollection) as? Int } public func setUserCount(_ userCount: Int, forPublicChatWithID publicChatID: String, in transaction: YapDatabaseReadWriteTransaction) { - transaction.setObject(userCount, forKey: publicChatID, inCollection: OWSPrimaryStorage.openGroupUserCountCollection) + transaction.setObject(userCount, forKey: publicChatID, inCollection: Storage.openGroupUserCountCollection) } } diff --git a/SignalServiceKit/src/Loki/Protocol/Multi Device/MultiDeviceProtocol.swift b/SignalServiceKit/src/Loki/Protocol/Multi Device/MultiDeviceProtocol.swift index b1e740029..4a944c6b8 100644 --- a/SignalServiceKit/src/Loki/Protocol/Multi Device/MultiDeviceProtocol.swift +++ b/SignalServiceKit/src/Loki/Protocol/Multi Device/MultiDeviceProtocol.swift @@ -62,12 +62,9 @@ public final class MultiDeviceProtocol : NSObject { } else if let thread = TSContactThread.getWithContactId(destination.hexEncodedPublicKey, transaction: transaction) { threadPromiseSeal.fulfill(thread) } else { - // Dispatch async on the main queue to avoid nested write transactions - DispatchQueue.main.async { - storage.dbReadWriteConnection.readWrite { transaction in - let thread = TSContactThread.getOrCreateThread(withContactId: destination.hexEncodedPublicKey, transaction: transaction) - threadPromiseSeal.fulfill(thread) - } + Storage.write { transaction in + let thread = TSContactThread.getOrCreateThread(withContactId: destination.hexEncodedPublicKey, transaction: transaction) + threadPromiseSeal.fulfill(thread) } } return threadPromise.then(on: OWSDispatch.sendingQueue()) { thread -> Promise in @@ -81,13 +78,10 @@ public final class MultiDeviceProtocol : NSObject { let messageSendCopy = copy(messageSend, for: destination, with: seal) messageSender.sendMessage(messageSendCopy) } else { - // Dispatch async on the main queue to avoid nested write transactions - DispatchQueue.main.async { - storage.dbReadWriteConnection.readWrite { transaction in - getAutoGeneratedMultiDeviceFRMessageSend(for: destination.hexEncodedPublicKey, in: transaction, seal: seal) - .done(on: OWSDispatch.sendingQueue()) { autoGeneratedFRMessageSend in - messageSender.sendMessage(autoGeneratedFRMessageSend) - } + Storage.write { transaction in + getAutoGeneratedMultiDeviceFRMessageSend(for: destination.hexEncodedPublicKey, in: transaction, seal: seal) + .done(on: OWSDispatch.sendingQueue()) { autoGeneratedFRMessageSend in + messageSender.sendMessage(autoGeneratedFRMessageSend) } } } diff --git a/SignalServiceKit/src/Loki/Protocol/Session Management/SessionManagementProtocol.swift b/SignalServiceKit/src/Loki/Protocol/Session Management/SessionManagementProtocol.swift index d34af79aa..2c9afcc96 100644 --- a/SignalServiceKit/src/Loki/Protocol/Session Management/SessionManagementProtocol.swift +++ b/SignalServiceKit/src/Loki/Protocol/Session Management/SessionManagementProtocol.swift @@ -141,14 +141,12 @@ public final class SessionManagementProtocol : NSObject { @objc(repairSessionIfNeededForMessage:to:) public static func repairSessionIfNeeded(for message: TSOutgoingMessage, to hexEncodedPublicKey: String) { guard (message.thread as? TSGroupThread)?.groupModel.groupType == .closedGroup else { return } - DispatchQueue.main.async { - storage.dbReadWriteConnection.readWrite { transaction in - let thread = TSContactThread.getOrCreateThread(withContactId: hexEncodedPublicKey, transaction: transaction) - let sessionRequestMessage = SessionRequestMessage(thread: thread) - storage.setSessionRequestTimestamp(for: hexEncodedPublicKey, to: Date(), in: transaction) - let messageSenderJobQueue = SSKEnvironment.shared.messageSenderJobQueue - messageSenderJobQueue.add(message: sessionRequestMessage, transaction: transaction) - } + Storage.write { transaction in + let thread = TSContactThread.getOrCreateThread(withContactId: hexEncodedPublicKey, transaction: transaction) + let sessionRequestMessage = SessionRequestMessage(thread: thread) + storage.setSessionRequestTimestamp(for: hexEncodedPublicKey, to: Date(), in: transaction) + let messageSenderJobQueue = SSKEnvironment.shared.messageSenderJobQueue + messageSenderJobQueue.add(message: sessionRequestMessage, transaction: transaction) } } @@ -205,7 +203,7 @@ public final class SessionManagementProtocol : NSObject { closedGroupMembers.formUnion(group.groupModel.groupMemberIds) } LokiFileServerAPI.getDeviceLinks(associatedWith: closedGroupMembers).ensure { - storage.dbReadWriteConnection.readWrite { transaction in + Storage.write { transaction in let validHEPKs = closedGroupMembers.flatMap { LokiDatabaseUtilities.getLinkedDeviceHexEncodedPublicKeys(for: $0, in: transaction) } From a42b6afce8825ba1b8603a441e9def6384693cbe Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Thu, 11 Jun 2020 12:23:06 +1000 Subject: [PATCH 10/19] Integrate transaction handling utility part 2 --- Signal/src/Jobs/SessionResetJob.swift | 10 +++++----- .../src/Loki/Components/ConversationTitleView.swift | 2 +- Signal/src/Loki/Shelved/LokiRSSFeedPoller.swift | 2 +- .../Loki/View Controllers/DeviceLinkingModal.swift | 6 +++--- Signal/src/Loki/View Controllers/DeviceLinksVC.swift | 4 ++-- Signal/src/Loki/View Controllers/HomeVC.swift | 2 +- .../src/Loki/View Controllers/JoinPublicChatVC.swift | 2 +- .../src/Loki/View Controllers/NewClosedGroupVC.swift | 2 +- .../Notifications/AppNotifications.swift | 2 +- .../ExperienceUpgradesPageViewController.swift | 2 +- .../LK001UpdateFriendRequestStatusStorage.swift | 2 +- .../migrations/OWS110SortIdMigration.swift | 2 +- .../migrations/OWS111UDAttributesMigration.swift | 2 +- .../migrations/OWS112TypingIndicatorsMigration.swift | 2 +- .../OWS113MultiAttachmentMediaMessages.swift | 2 +- .../migrations/OWS114RemoveDynamicInteractions.swift | 2 +- SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift | 10 +++++----- SignalServiceKit/src/Loki/API/LokiAPI.swift | 6 +++--- SignalServiceKit/src/Loki/API/LokiDotNetAPI.swift | 4 ++-- .../Loki/API/Onion Requests/OnionRequestAPI.swift | 4 ++-- .../src/Loki/API/Open Groups/LokiPublicChatAPI.swift | 12 ++++++------ .../Loki/API/Open Groups/LokiPublicChatManager.swift | 4 ++-- .../Loki/API/Open Groups/LokiPublicChatPoller.swift | 4 ++-- SignalServiceKit/src/Loki/Database/Storage.swift | 8 ++++---- .../Friend Requests/FriendRequestExpirationJob.swift | 4 ++-- SignalServiceKit/src/Messages/UD/OWSUDManager.swift | 2 +- .../src/Network/MessageSenderJobQueue.swift | 12 ++++++------ SignalServiceKit/src/Util/JobQueue.swift | 4 ++-- 28 files changed, 60 insertions(+), 60 deletions(-) diff --git a/Signal/src/Jobs/SessionResetJob.swift b/Signal/src/Jobs/SessionResetJob.swift index 8cd368ad0..9cb4a2e1e 100644 --- a/Signal/src/Jobs/SessionResetJob.swift +++ b/Signal/src/Jobs/SessionResetJob.swift @@ -112,7 +112,7 @@ public class SessionResetOperation: OWSOperation, DurableOperation { * We don't want to delete the session. Ref: SignalServiceKit/Loki/Docs/SessionReset.md * ================ if firstAttempt { - self.dbConnection.readWrite { transaction in + try! Storage.writeSync { transaction in Logger.info("deleting sessions for recipient: \(self.recipientId)") self.primaryStorage.deleteAllSessions(forContact: self.recipientId, protocolContext: transaction) } @@ -127,7 +127,7 @@ public class SessionResetOperation: OWSOperation, DurableOperation { return self.messageSender.sendPromise(message: endSessionMessage) }.done { Logger.info("successfully sent EndSessionMessage.") - self.dbConnection.readWrite { transaction in + try! Storage.writeSync { transaction in // Archive the just-created session since the recipient should delete their corresponding // session upon receiving and decrypting our EndSession message. // Otherwise if we send another message before them, they wont have the session to decrypt it. @@ -160,7 +160,7 @@ public class SessionResetOperation: OWSOperation, DurableOperation { } override public func didSucceed() { - self.dbConnection.readWrite { transaction in + try! Storage.writeSync { transaction in self.durableOperationDelegate?.durableOperationDidSucceed(self, transaction: transaction) } } @@ -168,7 +168,7 @@ public class SessionResetOperation: OWSOperation, DurableOperation { override public func didReportError(_ error: Error) { Logger.debug("remainingRetries: \(self.remainingRetries)") - self.dbConnection.readWrite { transaction in + try! Storage.writeSync { transaction in self.durableOperationDelegate?.durableOperation(self, didReportError: error, transaction: transaction) } } @@ -192,7 +192,7 @@ public class SessionResetOperation: OWSOperation, DurableOperation { override public func didFail(error: Error) { Logger.error("failed to send EndSessionMessage with error: \(error.localizedDescription)") - self.dbConnection.readWrite { transaction in + try! Storage.writeSync { transaction in self.durableOperationDelegate?.durableOperation(self, didFailWithError: error, transaction: transaction) // Even though this is the failure handler - which means probably the recipient didn't receive the message diff --git a/Signal/src/Loki/Components/ConversationTitleView.swift b/Signal/src/Loki/Components/ConversationTitleView.swift index f1bd8d8ef..79f3f6d35 100644 --- a/Signal/src/Loki/Components/ConversationTitleView.swift +++ b/Signal/src/Loki/Components/ConversationTitleView.swift @@ -180,7 +180,7 @@ final class ConversationTitleView : UIView { if thread.groupModel.groupType == .closedGroup { userCount = GroupUtilities.getClosedGroupMemberCount(thread) } else if thread.groupModel.groupType == .openGroup { - storage.dbReadConnection.readWrite { transaction in + storage.dbReadConnection.read { transaction in if let publicChat = LokiDatabaseUtilities.getPublicChat(for: self.thread.uniqueId!, in: transaction) { userCount = storage.getUserCount(for: publicChat, in: transaction) } diff --git a/Signal/src/Loki/Shelved/LokiRSSFeedPoller.swift b/Signal/src/Loki/Shelved/LokiRSSFeedPoller.swift index f29e3a884..a0f15ea02 100644 --- a/Signal/src/Loki/Shelved/LokiRSSFeedPoller.swift +++ b/Signal/src/Loki/Shelved/LokiRSSFeedPoller.swift @@ -63,7 +63,7 @@ public final class LokiRSSFeedPoller : NSObject { envelope.setSource(NSLocalizedString("Loki", comment: "")) envelope.setSourceDevice(OWSDevicePrimaryDeviceId) envelope.setContent(try! content.build().serializedData()) - try! Storage.syncWrite { transaction in + try! Storage.writeSync { transaction in SSKEnvironment.shared.messageManager.throws_processEnvelope(try! envelope.build(), plaintextData: try! content.build().serializedData(), wasReceivedByUD: false, transaction: transaction, serverID: 0) } } diff --git a/Signal/src/Loki/View Controllers/DeviceLinkingModal.swift b/Signal/src/Loki/View Controllers/DeviceLinkingModal.swift index 5aa389ca1..46fb79ec4 100644 --- a/Signal/src/Loki/View Controllers/DeviceLinkingModal.swift +++ b/Signal/src/Loki/View Controllers/DeviceLinkingModal.swift @@ -186,7 +186,7 @@ final class DeviceLinkingModal : Modal, DeviceLinkingSessionDelegate { SSKEnvironment.shared.messageSender.send(linkingAuthorizationMessage, success: { let storage = OWSPrimaryStorage.shared() let slaveHexEncodedPublicKey = deviceLink.slave.hexEncodedPublicKey - try! Storage.syncWrite { transaction in + try! Storage.writeSync { transaction in let thread = TSContactThread.getOrCreateThread(withContactId: slaveHexEncodedPublicKey, transaction: transaction) thread.save(with: transaction) } @@ -196,7 +196,7 @@ final class DeviceLinkingModal : Modal, DeviceLinkingSessionDelegate { let _ = SSKEnvironment.shared.syncManager.syncAllContacts() } let _ = SSKEnvironment.shared.syncManager.syncAllOpenGroups() - try! Storage.syncWrite { transaction in + try! Storage.writeSync { transaction in storage.setFriendRequestStatus(.friends, for: slaveHexEncodedPublicKey, transaction: transaction) } DispatchQueue.main.async { @@ -251,7 +251,7 @@ final class DeviceLinkingModal : Modal, DeviceLinkingSessionDelegate { session.markLinkingRequestAsProcessed() // Only relevant in master mode delegate?.handleDeviceLinkingModalDismissed() // Only relevant in slave mode if let deviceLink = deviceLink { - try! Storage.syncWrite { transaction in + try! Storage.writeSync { transaction in OWSPrimaryStorage.shared().removePreKeyBundle(forContact: deviceLink.slave.hexEncodedPublicKey, transaction: transaction) } } diff --git a/Signal/src/Loki/View Controllers/DeviceLinksVC.swift b/Signal/src/Loki/View Controllers/DeviceLinksVC.swift index 85554b380..3f7960c03 100644 --- a/Signal/src/Loki/View Controllers/DeviceLinksVC.swift +++ b/Signal/src/Loki/View Controllers/DeviceLinksVC.swift @@ -146,14 +146,14 @@ final class DeviceLinksVC : BaseVC, UITableViewDataSource, UITableViewDelegate, let unlinkDeviceMessage = UnlinkDeviceMessage(thread: thread) SSKEnvironment.shared.messageSender.send(unlinkDeviceMessage, success: { let storage = OWSPrimaryStorage.shared() - try! Storage.syncWrite { transaction in + try! Storage.writeSync { transaction in storage.removePreKeyBundle(forContact: linkedDeviceHexEncodedPublicKey, transaction: transaction) storage.deleteAllSessions(forContact: linkedDeviceHexEncodedPublicKey, protocolContext: transaction) } }, failure: { _ in print("[Loki] Failed to send unlink device message.") let storage = OWSPrimaryStorage.shared() - try! Storage.syncWrite { transaction in + try! Storage.writeSync { transaction in storage.removePreKeyBundle(forContact: linkedDeviceHexEncodedPublicKey, transaction: transaction) storage.deleteAllSessions(forContact: linkedDeviceHexEncodedPublicKey, protocolContext: transaction) } diff --git a/Signal/src/Loki/View Controllers/HomeVC.swift b/Signal/src/Loki/View Controllers/HomeVC.swift index 28138f6c3..a8e502017 100644 --- a/Signal/src/Loki/View Controllers/HomeVC.swift +++ b/Signal/src/Loki/View Controllers/HomeVC.swift @@ -369,7 +369,7 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, UIScrol let alert = UIAlertController(title: NSLocalizedString("CONVERSATION_DELETE_CONFIRMATION_ALERT_TITLE", comment: ""), message: NSLocalizedString("CONVERSATION_DELETE_CONFIRMATION_ALERT_MESSAGE", comment: ""), preferredStyle: .alert) alert.addAction(UIAlertAction(title: NSLocalizedString("TXT_DELETE_TITLE", comment: ""), style: .destructive) { _ in guard let self = self else { return } - self.editingDatabaseConnection.readWrite { transaction in + try! Storage.writeSync { transaction in if let publicChat = publicChat { var messageIDs: Set = [] thread.enumerateInteractions(with: transaction) { interaction, _ in diff --git a/Signal/src/Loki/View Controllers/JoinPublicChatVC.swift b/Signal/src/Loki/View Controllers/JoinPublicChatVC.swift index 9b0ad0188..ae09f4cde 100644 --- a/Signal/src/Loki/View Controllers/JoinPublicChatVC.swift +++ b/Signal/src/Loki/View Controllers/JoinPublicChatVC.swift @@ -135,7 +135,7 @@ final class JoinPublicChatVC : BaseVC, UIPageViewControllerDataSource, UIPageVie let urlAsString = url.absoluteString let displayName = OWSProfileManager.shared().localProfileName() // TODO: Profile picture & profile key - try! Storage.syncWrite { transaction in + try! Storage.writeSync { transaction in transaction.removeObject(forKey: "\(urlAsString).\(channelID)", inCollection: LokiPublicChatAPI.lastMessageServerIDCollection) transaction.removeObject(forKey: "\(urlAsString).\(channelID)", inCollection: LokiPublicChatAPI.lastDeletionServerIDCollection) } diff --git a/Signal/src/Loki/View Controllers/NewClosedGroupVC.swift b/Signal/src/Loki/View Controllers/NewClosedGroupVC.swift index ad4f87698..4dbf6411b 100644 --- a/Signal/src/Loki/View Controllers/NewClosedGroupVC.swift +++ b/Signal/src/Loki/View Controllers/NewClosedGroupVC.swift @@ -158,7 +158,7 @@ final class NewClosedGroupVC : BaseVC, UITableViewDataSource, UITableViewDelegat let userHexEncodedPublicKey = getUserHexEncodedPublicKey() let storage = OWSPrimaryStorage.shared() var masterHexEncodedPublicKey = "" - storage.dbReadConnection.readWrite { transaction in + storage.dbReadConnection.read { transaction in masterHexEncodedPublicKey = storage.getMasterHexEncodedPublicKey(for: userHexEncodedPublicKey, in: transaction) ?? userHexEncodedPublicKey } let members = selectedContacts + [ masterHexEncodedPublicKey ] diff --git a/Signal/src/UserInterface/Notifications/AppNotifications.swift b/Signal/src/UserInterface/Notifications/AppNotifications.swift index 5572c7801..525e801f9 100644 --- a/Signal/src/UserInterface/Notifications/AppNotifications.swift +++ b/Signal/src/UserInterface/Notifications/AppNotifications.swift @@ -659,7 +659,7 @@ class NotificationActionHandler { } private func markAsRead(thread: TSThread) -> Promise { - return dbConnection.readWritePromise { transaction in + return Storage.write { transaction in thread.markAllAsRead(with: transaction) } } diff --git a/Signal/src/ViewControllers/ExperienceUpgradesPageViewController.swift b/Signal/src/ViewControllers/ExperienceUpgradesPageViewController.swift index fda60e0ab..9eba6c0f1 100644 --- a/Signal/src/ViewControllers/ExperienceUpgradesPageViewController.swift +++ b/Signal/src/ViewControllers/ExperienceUpgradesPageViewController.swift @@ -889,7 +889,7 @@ public class ExperienceUpgradesPageViewController: OWSViewController, UIPageView @objc public override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) { // Blocking write before dismiss, to be sure they're marked as complete // before HomeView.didAppear is re-fired. - self.editingDBConnection.readWrite { transaction in + try! Storage.writeSync { transaction in Logger.info("marking all upgrades as seen.") ExperienceUpgradeFinder.shared.markAllAsSeen(transaction: transaction) } diff --git a/SignalMessaging/Loki/Migrations/LK001UpdateFriendRequestStatusStorage.swift b/SignalMessaging/Loki/Migrations/LK001UpdateFriendRequestStatusStorage.swift index 4878ad16d..c4814a518 100644 --- a/SignalMessaging/Loki/Migrations/LK001UpdateFriendRequestStatusStorage.swift +++ b/SignalMessaging/Loki/Migrations/LK001UpdateFriendRequestStatusStorage.swift @@ -19,7 +19,7 @@ public class LK001UpdateFriendRequestStatusStorage : OWSDatabaseMigration { private func doMigrationAsync(completion: @escaping OWSDatabaseMigrationCompletion) { DispatchQueue.global().async { - self.dbReadWriteConnection().readWrite { transaction in + try! Storage.writeSync { transaction in var threads: [TSContactThread] = [] TSContactThread.enumerateCollectionObjects(with: transaction) { object, _ in guard let thread = object as? TSContactThread else { return } diff --git a/SignalMessaging/environment/migrations/OWS110SortIdMigration.swift b/SignalMessaging/environment/migrations/OWS110SortIdMigration.swift index 3d9df150c..a433860f1 100644 --- a/SignalMessaging/environment/migrations/OWS110SortIdMigration.swift +++ b/SignalMessaging/environment/migrations/OWS110SortIdMigration.swift @@ -25,7 +25,7 @@ public class OWS110SortIdMigration: OWSDatabaseMigration { private func doMigration(completion: @escaping OWSDatabaseMigrationCompletion) { // TODO batch this? - self.dbReadWriteConnection().readWrite { transaction in + try! Storage.writeSync { transaction in var archivedThreads: [TSThread] = [] diff --git a/SignalMessaging/environment/migrations/OWS111UDAttributesMigration.swift b/SignalMessaging/environment/migrations/OWS111UDAttributesMigration.swift index 6556cfe6c..631159ff8 100644 --- a/SignalMessaging/environment/migrations/OWS111UDAttributesMigration.swift +++ b/SignalMessaging/environment/migrations/OWS111UDAttributesMigration.swift @@ -35,7 +35,7 @@ public class OWS111UDAttributesMigration: OWSDatabaseMigration { private func doMigration() { tsAccountManager.updateAccountAttributes().retainUntilComplete() - self.dbReadWriteConnection().readWrite { transaction in + try! Storage.writeSync { transaction in self.save(with: transaction) } } diff --git a/SignalMessaging/environment/migrations/OWS112TypingIndicatorsMigration.swift b/SignalMessaging/environment/migrations/OWS112TypingIndicatorsMigration.swift index 026a3d663..671c5c3ae 100644 --- a/SignalMessaging/environment/migrations/OWS112TypingIndicatorsMigration.swift +++ b/SignalMessaging/environment/migrations/OWS112TypingIndicatorsMigration.swift @@ -39,7 +39,7 @@ public class OWS112TypingIndicatorsMigration: OWSDatabaseMigration { self.typingIndicators.setTypingIndicatorsEnabled(value: false) DispatchQueue.global().async { - self.dbReadWriteConnection().readWrite { transaction in + try! Storage.writeSync { transaction in self.save(with: transaction) } diff --git a/SignalMessaging/environment/migrations/OWS113MultiAttachmentMediaMessages.swift b/SignalMessaging/environment/migrations/OWS113MultiAttachmentMediaMessages.swift index 6d6cc288b..601a1d54d 100644 --- a/SignalMessaging/environment/migrations/OWS113MultiAttachmentMediaMessages.swift +++ b/SignalMessaging/environment/migrations/OWS113MultiAttachmentMediaMessages.swift @@ -53,7 +53,7 @@ public class OWS113MultiAttachmentMediaMessages: OWSDatabaseMigration { } } } - self.dbReadWriteConnection().readWrite { transaction in + try! Storage.writeSync { transaction in for (attachmentId, messageId) in legacyAttachments { autoreleasepool { guard let attachment = TSAttachment.fetch(uniqueId: attachmentId, transaction: transaction) else { diff --git a/SignalMessaging/environment/migrations/OWS114RemoveDynamicInteractions.swift b/SignalMessaging/environment/migrations/OWS114RemoveDynamicInteractions.swift index e7b462fd7..a953d4958 100644 --- a/SignalMessaging/environment/migrations/OWS114RemoveDynamicInteractions.swift +++ b/SignalMessaging/environment/migrations/OWS114RemoveDynamicInteractions.swift @@ -30,7 +30,7 @@ public class OWS114RemoveDynamicInteractions: OWSDatabaseMigration { private func doMigrationAsync(completion : @escaping OWSDatabaseMigrationCompletion) { DispatchQueue.global().async { - self.dbReadWriteConnection().readWrite { transaction in + try! Storage.writeSync { transaction in guard let dbView = TSDatabaseView.threadSpecialMessagesDatabaseView(transaction) as? YapDatabaseViewTransaction else { owsFailDebug("Couldn't load db view.") return diff --git a/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift b/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift index 800758a59..060c189a3 100644 --- a/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift +++ b/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift @@ -53,7 +53,7 @@ public extension LokiAPI { } }.done(on: DispatchQueue.global()) { snode in seal.fulfill(snode) - try! Storage.syncWrite { transaction in + try! Storage.writeSync { transaction in print("[Loki] Persisting snode pool to database.") storage.setSnodePool(LokiAPI.snodePool, in: transaction) } @@ -87,7 +87,7 @@ public extension LokiAPI { parseTargets(from: $0) }.get { swarm in swarmCache[hexEncodedPublicKey] = swarm - try! Storage.syncWrite { transaction in + try! Storage.writeSync { transaction in storage.setSwarm(swarm, for: hexEncodedPublicKey, in: transaction) } } @@ -101,7 +101,7 @@ public extension LokiAPI { internal static func dropSnodeFromSnodePool(_ target: LokiAPITarget) { LokiAPI.snodePool.remove(target) - try! Storage.syncWrite { transaction in + try! Storage.writeSync { transaction in storage.dropSnodeFromSnodePool(target, in: transaction) } } @@ -111,7 +111,7 @@ public extension LokiAPI { if var swarm = swarm, let index = swarm.firstIndex(of: target) { swarm.remove(at: index) LokiAPI.swarmCache[hexEncodedPublicKey] = swarm - try! Storage.syncWrite { transaction in + try! Storage.writeSync { transaction in storage.setSwarm(swarm, for: hexEncodedPublicKey, in: transaction) } } @@ -120,7 +120,7 @@ public extension LokiAPI { // MARK: Public API @objc public static func clearSnodePool() { snodePool.removeAll() - try! Storage.syncWrite { transaction in + try! Storage.writeSync { transaction in storage.clearSnodePool(in: transaction) } } diff --git a/SignalServiceKit/src/Loki/API/LokiAPI.swift b/SignalServiceKit/src/Loki/API/LokiAPI.swift index e8cdd58e9..5f6aff3e7 100644 --- a/SignalServiceKit/src/Loki/API/LokiAPI.swift +++ b/SignalServiceKit/src/Loki/API/LokiAPI.swift @@ -194,14 +194,14 @@ public final class LokiAPI : NSObject { var result: String? = nil // Uses a read/write connection because getting the last message hash value also removes expired messages as needed // TODO: This shouldn't be the case; a getter shouldn't have an unexpected side effect - try! Storage.syncWrite { transaction in + try! Storage.writeSync { transaction in result = storage.getLastMessageHash(forSnode: target.address, transaction: transaction) } return result } private static func setLastMessageHashValue(for target: LokiAPITarget, hashValue: String, expirationDate: UInt64) { - try! Storage.syncWrite { transaction in + try! Storage.writeSync { transaction in storage.setLastMessageHash(forSnode: target.address, hash: hashValue, expiresAt: expirationDate, transaction: transaction) } } @@ -218,7 +218,7 @@ public final class LokiAPI : NSObject { } private static func setReceivedMessageHashValues(to receivedMessageHashValues: Set) { - try! Storage.syncWrite { transaction in + try! Storage.writeSync { transaction in transaction.setObject(receivedMessageHashValues, forKey: receivedMessageHashValuesKey, inCollection: receivedMessageHashValuesCollection) } } diff --git a/SignalServiceKit/src/Loki/API/LokiDotNetAPI.swift b/SignalServiceKit/src/Loki/API/LokiDotNetAPI.swift index 22cc15947..5210cbc60 100644 --- a/SignalServiceKit/src/Loki/API/LokiDotNetAPI.swift +++ b/SignalServiceKit/src/Loki/API/LokiDotNetAPI.swift @@ -38,7 +38,7 @@ public class LokiDotNetAPI : NSObject { return Promise.value(token) } else { return requestNewAuthToken(for: server).then(on: DispatchQueue.global()) { submitAuthToken($0, for: server) }.map(on: DispatchQueue.global()) { token in - try! Storage.syncWrite { transaction in + try! Storage.writeSync { transaction in setAuthToken(for: server, to: token, in: transaction) } return token @@ -51,7 +51,7 @@ public class LokiDotNetAPI : NSObject { } public static func clearAuthToken(for server: String) { - try! Storage.syncWrite { transaction in + try! Storage.writeSync { transaction in transaction.removeObject(forKey: server, inCollection: authTokenCollection) } } diff --git a/SignalServiceKit/src/Loki/API/Onion Requests/OnionRequestAPI.swift b/SignalServiceKit/src/Loki/API/Onion Requests/OnionRequestAPI.swift index 9ed5fb6f7..9e07c9c9e 100644 --- a/SignalServiceKit/src/Loki/API/Onion Requests/OnionRequestAPI.swift +++ b/SignalServiceKit/src/Loki/API/Onion Requests/OnionRequestAPI.swift @@ -123,7 +123,7 @@ public enum OnionRequestAPI { } }.map(on: LokiAPI.workQueue) { paths in OnionRequestAPI.paths = paths - try! Storage.syncWrite { transaction in + try! Storage.writeSync { transaction in print("[Loki] Persisting onion request paths to database.") OWSPrimaryStorage.shared().setOnionRequestPaths(paths, in: transaction) } @@ -163,7 +163,7 @@ public enum OnionRequestAPI { private static func dropAllPaths() { paths.removeAll() - try! Storage.syncWrite { transaction in + try! Storage.writeSync { transaction in OWSPrimaryStorage.shared().clearOnionRequestPaths(in: transaction) } } diff --git a/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatAPI.swift b/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatAPI.swift index 815002664..a6a7b8794 100644 --- a/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatAPI.swift +++ b/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatAPI.swift @@ -37,13 +37,13 @@ public final class LokiPublicChatAPI : LokiDotNetAPI { } private static func setLastMessageServerID(for group: UInt64, on server: String, to newValue: UInt64) { - try! Storage.syncWrite { transaction in + try! Storage.writeSync { transaction in transaction.setObject(newValue, forKey: "\(server).\(group)", inCollection: lastMessageServerIDCollection) } } private static func removeLastMessageServerID(for group: UInt64, on server: String) { - try! Storage.syncWrite { transaction in + try! Storage.writeSync { transaction in transaction.removeObject(forKey: "\(server).\(group)", inCollection: lastMessageServerIDCollection) } } @@ -57,13 +57,13 @@ public final class LokiPublicChatAPI : LokiDotNetAPI { } private static func setLastDeletionServerID(for group: UInt64, on server: String, to newValue: UInt64) { - try! Storage.syncWrite { transaction in + try! Storage.writeSync { transaction in transaction.setObject(newValue, forKey: "\(server).\(group)", inCollection: lastDeletionServerIDCollection) } } private static func removeLastDeletionServerID(for group: UInt64, on server: String) { - try! Storage.syncWrite { transaction in + try! Storage.writeSync { transaction in transaction.removeObject(forKey: "\(server).\(group)", inCollection: lastDeletionServerIDCollection) } } @@ -271,7 +271,7 @@ public final class LokiPublicChatAPI : LokiDotNetAPI { print("[Loki] Couldn't parse display names for users: \(hexEncodedPublicKeys) from: \(rawResponse).") throw LokiDotNetAPIError.parsingFailed } - try! Storage.syncWrite { transaction in + try! Storage.writeSync { transaction in data.forEach { data in guard let user = data["user"] as? JSON, let hexEncodedPublicKey = user["username"] as? String, let rawDisplayName = user["name"] as? String else { return } let endIndex = hexEncodedPublicKey.endIndex @@ -355,7 +355,7 @@ public final class LokiPublicChatAPI : LokiDotNetAPI { throw LokiDotNetAPIError.parsingFailed } let storage = OWSPrimaryStorage.shared() - try! Storage.syncWrite { transaction in + try! Storage.writeSync { transaction in storage.setUserCount(memberCount, forPublicChatWithID: "\(server).\(channel)", in: transaction) } // TODO: Use this to update open group names as needed diff --git a/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatManager.swift b/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatManager.swift index a04e20975..098f0853b 100644 --- a/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatManager.swift +++ b/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatManager.swift @@ -71,7 +71,7 @@ public final class LokiPublicChatManager : NSObject { let model = TSGroupModel(title: chat.displayName, memberIds: [userHexEncodedPublicKey!, chat.server], image: nil, groupId: LKGroupUtilities.getEncodedOpenGroupIDAsData(chat.id), groupType: .openGroup, adminIds: []) // Store the group chat mapping - try! Storage.syncWrite { transaction in + try! Storage.writeSync { transaction in let thread = TSGroupThread.getOrCreateThread(with: model, transaction: transaction) // Save the group chat @@ -118,7 +118,7 @@ public final class LokiPublicChatManager : NSObject { } // Remove the chat from the db - try! Storage.syncWrite { transaction in + try! Storage.writeSync { transaction in LokiDatabaseUtilities.removePublicChat(for: threadId, in: transaction) } diff --git a/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatPoller.swift b/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatPoller.swift index 9182ce78d..3e977185f 100644 --- a/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatPoller.swift +++ b/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatPoller.swift @@ -163,7 +163,7 @@ public final class LokiPublicChatPoller : NSObject { envelope.setSource(senderHexEncodedPublicKey) envelope.setSourceDevice(OWSDevicePrimaryDeviceId) envelope.setContent(try! content.build().serializedData()) - try! Storage.syncWrite { transaction in + try! Storage.writeSync { transaction in transaction.setObject(senderDisplayName, forKey: senderHexEncodedPublicKey, inCollection: publicChat.id) let messageServerID = message.serverID SSKEnvironment.shared.messageManager.throws_processEnvelope(try! envelope.build(), plaintextData: try! content.build().serializedData(), wasReceivedByUD: false, transaction: transaction, serverID: messageServerID ?? 0) @@ -213,7 +213,7 @@ public final class LokiPublicChatPoller : NSObject { private func pollForDeletedMessages() { let publicChat = self.publicChat let _ = LokiPublicChatAPI.getDeletedMessageServerIDs(for: publicChat.channel, on: publicChat.server).done(on: DispatchQueue.global()) { deletedMessageServerIDs in - try! Storage.syncWrite { transaction in + try! Storage.writeSync { transaction in let deletedMessageIDs = deletedMessageServerIDs.compactMap { OWSPrimaryStorage.shared().getIDForMessage(withServerID: UInt($0), in: transaction) } deletedMessageIDs.forEach { messageID in TSMessage.fetch(uniqueId: messageID)?.remove(with: transaction) diff --git a/SignalServiceKit/src/Loki/Database/Storage.swift b/SignalServiceKit/src/Loki/Database/Storage.swift index bf467b705..cf6a5ad8c 100644 --- a/SignalServiceKit/src/Loki/Database/Storage.swift +++ b/SignalServiceKit/src/Loki/Database/Storage.swift @@ -47,13 +47,13 @@ public final class Storage : NSObject { } /// Blocks the calling thread until the write has finished. - @objc(syncWriteWithBlock:error:) - public static func objc_syncWrite(with block: @escaping (YapDatabaseReadWriteTransaction) -> Void) throws { - try syncWrite(with: block) + @objc(writeSyncWithBlock:error:) + public static func objc_writeSync(with block: @escaping (YapDatabaseReadWriteTransaction) -> Void) throws { + try writeSync(with: block) } /// Blocks the calling thread until the write has finished. - public static func syncWrite(with block: @escaping (YapDatabaseReadWriteTransaction) -> Void) throws { + public static func writeSync(with block: @escaping (YapDatabaseReadWriteTransaction) -> Void) throws { try write(with: block).wait() } } diff --git a/SignalServiceKit/src/Loki/Protocol/Friend Requests/FriendRequestExpirationJob.swift b/SignalServiceKit/src/Loki/Protocol/Friend Requests/FriendRequestExpirationJob.swift index aac8c007e..78fff1784 100644 --- a/SignalServiceKit/src/Loki/Protocol/Friend Requests/FriendRequestExpirationJob.swift +++ b/SignalServiceKit/src/Loki/Protocol/Friend Requests/FriendRequestExpirationJob.swift @@ -66,7 +66,7 @@ public final class FriendRequestExpirationJob : NSObject { expireMessages() var nextExpirationTimestamp: UInt64? = nil - databaseConnection.readWrite { transaction in + try! Storage.writeSync { transaction in nextExpirationTimestamp = self.messageFinder.nextExpirationTimestamp(with: transaction) } @@ -108,7 +108,7 @@ public final class FriendRequestExpirationJob : NSObject { guard let strongSelf = self else { return } - strongSelf.databaseConnection.readWrite { transaction in + try! Storage.writeSync { transaction in strongSelf.messageFinder.enumurateMessagesPendingExpiration(with: { message in guard message.thread is TSContactThread else { return } diff --git a/SignalServiceKit/src/Messages/UD/OWSUDManager.swift b/SignalServiceKit/src/Messages/UD/OWSUDManager.swift index 9285fb0b4..000769c99 100644 --- a/SignalServiceKit/src/Messages/UD/OWSUDManager.swift +++ b/SignalServiceKit/src/Messages/UD/OWSUDManager.swift @@ -241,7 +241,7 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager { } } - dbConnection.readWrite { (transaction) in + try! Storage.writeSync { (transaction) in let oldMode = self.unidentifiedAccessMode(forRecipientId: recipientId, isLocalNumber: isLocalNumber, transaction: transaction) transaction.setObject(mode.rawValue as Int, forKey: recipientId, inCollection: self.kUnidentifiedAccessCollection) diff --git a/SignalServiceKit/src/Network/MessageSenderJobQueue.swift b/SignalServiceKit/src/Network/MessageSenderJobQueue.swift index 33ebfd6bf..1ce758e63 100644 --- a/SignalServiceKit/src/Network/MessageSenderJobQueue.swift +++ b/SignalServiceKit/src/Network/MessageSenderJobQueue.swift @@ -51,11 +51,11 @@ public class MessageSenderJobQueue: NSObject, JobQueue { inMessage: mediaMessage, completionHandler: { error in if let error = error { - self.dbConnection.readWrite { transaction in + try! Storage.writeSync { transaction in mediaMessage.update(sendingError: error, transaction: transaction) } } else { - self.dbConnection.readWrite { transaction in + try! Storage.writeSync { transaction in self.add(message: mediaMessage, removeMessageAfterSending: isTemporaryAttachment, transaction: transaction) } } @@ -96,7 +96,7 @@ public class MessageSenderJobQueue: NSObject, JobQueue { /// Used when the user clears their database to cancel any outstanding jobs. @objc public func clearAllJobs() { - self.dbConnection.readWrite { transaction in + try! Storage.writeSync { transaction in let statuses: [SSKJobRecordStatus] = [ .unknown, .ready, .running, .permanentlyFailed ] var records: [SSKJobRecord] = [] statuses.forEach { @@ -196,7 +196,7 @@ public class MessageSenderOperation: OWSOperation, DurableOperation { } override public func didSucceed() { - self.dbConnection.readWrite { transaction in + try! Storage.writeSync { transaction in self.durableOperationDelegate?.durableOperationDidSucceed(self, transaction: transaction) if self.jobRecord.removeMessageAfterSending { self.message.remove(with: transaction) @@ -205,7 +205,7 @@ public class MessageSenderOperation: OWSOperation, DurableOperation { } override public func didReportError(_ error: Error) { - self.dbConnection.readWrite { transaction in + try! Storage.writeSync { transaction in self.durableOperationDelegate?.durableOperation(self, didReportError: error, transaction: transaction) } } @@ -227,7 +227,7 @@ public class MessageSenderOperation: OWSOperation, DurableOperation { } override public func didFail(error: Error) { - self.dbConnection.readWrite { transaction in + try! Storage.writeSync { transaction in self.durableOperationDelegate?.durableOperation(self, didFailWithError: error, transaction: transaction) self.message.update(sendingError: error, transaction: transaction) diff --git a/SignalServiceKit/src/Util/JobQueue.swift b/SignalServiceKit/src/Util/JobQueue.swift index f5ec89f8b..608001877 100644 --- a/SignalServiceKit/src/Util/JobQueue.swift +++ b/SignalServiceKit/src/Util/JobQueue.swift @@ -157,7 +157,7 @@ public extension JobQueue { return } - self.dbConnection.readWrite { transaction in + try! Storage.writeSync { transaction in guard let nextJob: JobRecordType = self.finder.getNextReady(label: self.jobRecordLabel, transaction: transaction) as? JobRecordType else { Logger.verbose("nothing left to enqueue") return @@ -197,7 +197,7 @@ public extension JobQueue { } public func restartOldJobs() { - self.dbConnection.readWrite { transaction in + try! Storage.writeSync { transaction in let runningRecords = self.finder.allRecords(label: self.jobRecordLabel, status: .running, transaction: transaction) Logger.info("marking old `running` JobRecords as ready: \(runningRecords.count)") for record in runningRecords { From 4f3544c1fc6ffc4cf8fbdbc5f0d68cd6d925cbbc Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Thu, 11 Jun 2020 13:25:48 +1000 Subject: [PATCH 11/19] Integrate transaction handling utility part 3 --- Signal/src/AppDelegate.m | 15 +- .../ConversationViewController.m | 77 +++++----- .../ConversationView/ConversationViewModel.m | 7 +- .../HomeView/HomeViewController.m | 8 +- .../ViewControllers/NewGroupViewController.m | 7 +- .../FingerprintViewController.m | 25 ++- .../OWSConversationSettingsViewController.m | 16 +- Signal/src/environment/SignalApp.m | 7 +- Signal/src/util/Backup/OWSBackup.m | 4 +- Signal/src/util/Backup/OWSBackupExportJob.m | 8 +- Signal/src/util/Backup/OWSBackupImportJob.m | 12 +- Signal/src/util/OWSOrphanDataCleaner.m | 8 +- Signal/src/util/Pastelog.m | 12 +- .../SelectThreadViewController.m | 4 +- .../SharingThreadPickerViewController.m | 5 +- SignalMessaging/contacts/OWSContactsManager.m | 8 +- SignalMessaging/contacts/OWSSyncManager.m | 4 +- SignalMessaging/environment/OWSSounds.m | 4 +- .../environment/VersionMigrations.m | 11 +- .../migrations/OWSDatabaseMigration.m | 4 +- .../migrations/OWSDatabaseMigrationRunner.m | 4 +- .../OWSResaveCollectionDBMigration.m | 5 +- SignalMessaging/profiles/OWSProfileManager.m | 14 +- SignalMessaging/profiles/OWSUserProfile.m | 12 +- SignalMessaging/utils/OWSPreferences.m | 5 +- SignalMessaging/utils/ThreadUtil.m | 44 +++--- .../src/Account/TSAccountManager.m | 18 +-- .../src/Contacts/ContactsUpdater.m | 4 +- .../src/Contacts/Threads/TSContactThread.m | 4 +- .../src/Contacts/Threads/TSGroupThread.m | 16 +- SignalServiceKit/src/Devices/OWSDevice.m | 22 ++- .../src/Devices/OWSRecordTranscriptJob.m | 15 +- .../Attachments/OWSAttachmentDownloads.m | 34 ++--- .../Messages/Attachments/TSAttachmentStream.m | 2 +- .../Messages/Interactions/TSOutgoingMessage.m | 6 +- .../src/Messages/OWSBatchMessageProcessor.m | 8 +- .../src/Messages/OWSDisappearingMessagesJob.m | 8 +- .../OWSFailedAttachmentDownloadsJob.m | 21 ++- .../src/Messages/OWSFailedMessagesJob.m | 33 ++-- .../src/Messages/OWSIdentityManager.m | 16 +- .../src/Messages/OWSIncompleteCallsJob.m | 4 +- .../src/Messages/OWSMessageDecrypter.m | 96 ++++++------ .../src/Messages/OWSMessageManager.m | 8 +- .../src/Messages/OWSMessageReceiver.m | 12 +- .../src/Messages/OWSMessageSender.m | 144 +++++++++--------- .../src/Messages/OWSOutgoingReceiptManager.m | 8 +- .../src/Messages/OWSReadReceiptManager.m | 12 +- SignalServiceKit/src/Messages/TSCall.m | 5 +- .../src/Network/WebSockets/OWSWebSocket.m | 11 +- .../src/Security/OWSRecipientIdentity.m | 4 +- .../src/Storage/OWSPrimaryStorage.m | 2 +- .../src/Storage/TSYapDatabaseObject.m | 17 ++- SignalServiceKit/src/Util/OWSAnalytics.m | 8 +- 53 files changed, 426 insertions(+), 442 deletions(-) diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index af44a40ec..101206a17 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -1254,10 +1254,9 @@ static NSTimeInterval launchStartedAt; if ([self.tsAccountManager isRegistered]) { OWSLogInfo(@"localNumber: %@", [self.tsAccountManager localNumber]); - [self.primaryStorage.newDatabaseConnection - readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { - [ExperienceUpgradeFinder.sharedManager markAllAsSeenWithTransaction:transaction]; - }]; + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [ExperienceUpgradeFinder.sharedManager markAllAsSeenWithTransaction:transaction]; + } error:nil]; // Start running the disappearing messages job in case the newly registered user // enables this feature @@ -1424,10 +1423,10 @@ static NSTimeInterval launchStartedAt; BOOL isChatSetUp = [NSUserDefaults.standardUserDefaults boolForKey:userDefaultsKey]; if (!isChatSetUp || !chat.isDeletable) { [LKPublicChatManager.shared addChatWithServer:chat.server channel:chat.channel name:chat.displayName]; - [OWSPrimaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { TSGroupThread *thread = [TSGroupThread threadWithGroupId:[LKGroupUtilities getEncodedOpenGroupIDAsData:chat.id] transaction:transaction]; if (thread != nil) { [OWSProfileManager.sharedManager addThreadToProfileWhitelist:thread]; } - }]; + } error:nil]; [NSUserDefaults.standardUserDefaults setBool:YES forKey:userDefaultsKey]; } } @@ -1466,9 +1465,9 @@ static NSTimeInterval launchStartedAt; if (!isFeedSetUp || !feed.isDeletable) { TSGroupModel *group = [[TSGroupModel alloc] initWithTitle:feed.displayName memberIds:@[ userHexEncodedPublicKey, feed.server ] image:nil groupId:[LKGroupUtilities getEncodedRSSFeedIDAsData:feed.id] groupType:rssFeed adminIds:@[ userHexEncodedPublicKey, feed.server ]]; __block TSGroupThread *thread; - [OWSPrimaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { thread = [TSGroupThread getOrCreateThreadWithGroupModel:group transaction:transaction]; - }]; + } error:nil]; [OWSProfileManager.sharedManager addThreadToProfileWhitelist:thread]; [NSUserDefaults.standardUserDefaults setBool:YES forKey:userDefaultsKey]; } diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m index 9af68a0cf..fdea04f58 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m @@ -1255,9 +1255,9 @@ typedef enum : NSUInteger { - (void)restoreSession { dispatch_async(dispatch_get_main_queue(), ^{ - [OWSPrimaryStorage.sharedManager.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [LKSessionManagementProtocol startSessionResetInThread:self.thread using:transaction]; - }]; + } error:nil]; }); } @@ -1926,10 +1926,9 @@ typedef enum : NSUInteger { accessibilityIdentifier:ACCESSIBILITY_IDENTIFIER_WITH_NAME(self, @"send_again") style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { - [self.editingDatabaseConnection - asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { - [self.messageSenderJobQueue addMessage:message transaction:transaction]; - }]; + [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [self.messageSenderJobQueue addMessage:message transaction:transaction]; + }]; }]; [actionSheet addAction:resendMessageAction]; @@ -1980,10 +1979,9 @@ typedef enum : NSUInteger { return; } TSContactThread *contactThread = (TSContactThread *)self.thread; - [self.editingDatabaseConnection - asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { - [self.sessionResetJobQueue addContactThread:contactThread transaction:transaction]; - }]; + [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [self.sessionResetJobQueue addContactThread:contactThread transaction:transaction]; + }]; }]; [alert addAction:resetSessionAction]; @@ -2358,12 +2356,11 @@ typedef enum : NSUInteger { OWSLogInfo(@"Blocking an unknown user."); [self.blockingManager addBlockedPhoneNumber:interaction.recipientId]; // Delete the offers. - [self.editingDatabaseConnection - readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - contactThread.hasDismissedOffers = YES; - [contactThread saveWithTransaction:transaction]; - [interaction removeWithTransaction:transaction]; - }]; + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + contactThread.hasDismissedOffers = YES; + [contactThread saveWithTransaction:transaction]; + [interaction removeWithTransaction:transaction]; + } error:nil]; }]; [actionSheet addAction:blockAction]; @@ -2387,11 +2384,11 @@ typedef enum : NSUInteger { editImmediately:YES]; // Delete the offers. - [self.editingDatabaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { contactThread.hasDismissedOffers = YES; [contactThread saveWithTransaction:transaction]; [interaction removeWithTransaction:transaction]; - }]; + } error:nil]; } - (void)tappedAddToProfileWhitelistOfferMessage:(OWSContactOffersInteraction *)interaction @@ -2405,11 +2402,11 @@ typedef enum : NSUInteger { [self presentAddThreadToProfileWhitelistWithSuccess:^() { // Delete the offers. - [self.editingDatabaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { contactThread.hasDismissedOffers = YES; [contactThread saveWithTransaction:transaction]; [interaction removeWithTransaction:transaction]; - }]; + } error:nil]; }]; } @@ -2583,18 +2580,16 @@ typedef enum : NSUInteger { success:^(NSArray *attachmentStreams) { OWSAssertDebug(attachmentStreams.count == 1); TSAttachmentStream *attachmentStream = attachmentStreams.firstObject; - [self.editingDatabaseConnection - readWriteWithBlock:^(YapDatabaseReadWriteTransaction *postSuccessTransaction) { - [message setQuotedMessageThumbnailAttachmentStream:attachmentStream]; - [message saveWithTransaction:postSuccessTransaction]; - }]; + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *postSuccessTransaction) { + [message setQuotedMessageThumbnailAttachmentStream:attachmentStream]; + [message saveWithTransaction:postSuccessTransaction]; + } error:nil]; } failure:^(NSError *error) { OWSLogWarn(@"Failed to redownload thumbnail with error: %@", error); - [self.editingDatabaseConnection - readWriteWithBlock:^(YapDatabaseReadWriteTransaction *postSuccessTransaction) { - [message touchWithTransaction:postSuccessTransaction]; - }]; + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *postSuccessTransaction) { + [message touchWithTransaction:postSuccessTransaction]; + } error:nil]; }]; }]; } @@ -2899,9 +2894,9 @@ typedef enum : NSUInteger { if ([self.thread isKindOfClass:TSContactThread.class] && [message isKindOfClass:LKFriendRequestMessage.class]) { NSString *recipientID = self.thread.contactIdentifier; OWSAssertIsOnMainThread(); - [OWSPrimaryStorage.sharedManager.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [LKFriendRequestProtocol setFriendRequestStatusToSendingIfNeededForHexEncodedPublicKey:recipientID transaction:transaction]; - }]; + } error:nil]; } } @@ -3716,7 +3711,7 @@ typedef enum : NSUInteger { __block TSGroupThread *groupThread; __block TSOutgoingMessage *message; - [self.editingDatabaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { groupThread = [TSGroupThread getOrCreateThreadWithGroupModel:newGroupModel transaction:transaction]; NSString *updateGroupInfo = @@ -3730,7 +3725,7 @@ typedef enum : NSUInteger { groupMetaMessage:TSGroupMetaMessageUpdate expiresInSeconds:expiresInSeconds]; [message updateWithCustomMessage:updateGroupInfo transaction:transaction]; - }]; + } error:nil]; [groupThread fireAvatarChangedNotification]; @@ -3800,7 +3795,7 @@ typedef enum : NSUInteger { __block TSThread *thread = _thread; __block NSString *currentDraft = [self.inputToolbar messageText]; - [self.editingDatabaseConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [thread setDraft:currentDraft transaction:transaction]; }]; } @@ -4501,17 +4496,17 @@ typedef enum : NSUInteger { - (void)acceptFriendRequest:(TSIncomingMessage *)friendRequest { if (self.thread.isGroupThread || self.thread.contactIdentifier == nil) { return; } - [OWSPrimaryStorage.sharedManager.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [LKFriendRequestProtocol acceptFriendRequestFromHexEncodedPublicKey:self.thread.contactIdentifier using:transaction]; - }]; + } error:nil]; } - (void)declineFriendRequest:(TSIncomingMessage *)friendRequest { if (self.thread.isGroupThread || self.thread.contactIdentifier == nil) { return; } - [OWSPrimaryStorage.sharedManager.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [LKFriendRequestProtocol declineFriendRequestFromHexEncodedPublicKey:self.thread.contactIdentifier using:transaction]; - }]; + } error:nil]; } #pragma mark - ConversationViewLayoutDelegate @@ -4610,7 +4605,7 @@ typedef enum : NSUInteger { [BenchManager completeEventWithEventId:@"fromSendUntil_toggleDefaultKeyboard"]; }); - [self.editingDatabaseConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [self.thread setDraft:@"" transaction:transaction]; }]; @@ -5452,13 +5447,13 @@ typedef enum : NSUInteger { } dispatch_async(dispatch_get_main_queue(), ^{ __block TSInteraction *targetInteraction; - [OWSPrimaryStorage.sharedManager.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [self.thread enumerateInteractionsWithTransaction:transaction usingBlock:^(TSInteraction *interaction, YapDatabaseReadTransaction *t) { if (interaction.timestamp == timestamp.unsignedLongLongValue) { targetInteraction = interaction; } }]; - }]; + } error:nil]; if (targetInteraction == nil || targetInteraction.interactionType != OWSInteractionType_OutgoingMessage) { return; } NSString *hexEncodedPublicKey = targetInteraction.thread.contactIdentifier; if (hexEncodedPublicKey == nil) { return; } diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewModel.m b/Signal/src/ViewControllers/ConversationView/ConversationViewModel.m index af1319725..9e699b2b3 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewModel.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewModel.m @@ -550,10 +550,9 @@ static const int kYapDatabaseRangeMaxLength = 25000; if (oldIndicatorItem) { // TODO ideally this would be happening within the *same* transaction that caused the unreadMessageIndicator // to be cleared. - [self.editingDatabaseConnection - asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { - [oldIndicatorItem.interaction touchWithTransaction:transaction]; - }]; + [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [oldIndicatorItem.interaction touchWithTransaction:transaction]; + }]; } if (self.hasClearedUnreadMessagesIndicator) { diff --git a/Signal/src/ViewControllers/HomeView/HomeViewController.m b/Signal/src/ViewControllers/HomeView/HomeViewController.m index 7997e23d0..166251b3c 100644 --- a/Signal/src/ViewControllers/HomeView/HomeViewController.m +++ b/Signal/src/ViewControllers/HomeView/HomeViewController.m @@ -1426,7 +1426,7 @@ typedef NS_ENUM(NSInteger, HomeViewControllerSection) { - (void)deleteThread:(TSThread *)thread { - [self.editingDbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { /* Loki: Orignal Code ===================== if ([thread isKindOfClass:[TSGroupThread class]]) { @@ -1440,7 +1440,7 @@ typedef NS_ENUM(NSInteger, HomeViewControllerSection) { // Loki: For now hard delete all groups [thread removeWithTransaction:transaction]; - }]; + } error:nil]; // Loki: Post notification [[NSNotificationCenter defaultCenter] postNotificationName:NSNotification.threadDeleted object:nil userInfo:@{ @"threadId": thread.uniqueId }]; @@ -1457,7 +1457,7 @@ typedef NS_ENUM(NSInteger, HomeViewControllerSection) { TSThread *thread = [self threadForIndexPath:indexPath]; - [self.editingDbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { switch (self.homeViewMode) { case HomeViewMode_Inbox: [thread archiveThreadWithTransaction:transaction]; @@ -1466,7 +1466,7 @@ typedef NS_ENUM(NSInteger, HomeViewControllerSection) { [thread unarchiveThreadWithTransaction:transaction]; break; } - }]; + } error:nil]; [self updateViewState]; } diff --git a/Signal/src/ViewControllers/NewGroupViewController.m b/Signal/src/ViewControllers/NewGroupViewController.m index 35332bda0..208f0b1d2 100644 --- a/Signal/src/ViewControllers/NewGroupViewController.m +++ b/Signal/src/ViewControllers/NewGroupViewController.m @@ -461,10 +461,9 @@ NS_ASSUME_NONNULL_BEGIN TSGroupModel *model = [self makeGroup]; __block TSGroupThread *thread; - [OWSPrimaryStorage.dbReadWriteConnection - readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { - thread = [TSGroupThread getOrCreateThreadWithGroupModel:model transaction:transaction]; - }]; + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + thread = [TSGroupThread getOrCreateThreadWithGroupModel:model transaction:transaction]; + } error:nil]; OWSAssertDebug(thread); [OWSProfileManager.sharedManager addThreadToProfileWhitelist:thread]; diff --git a/Signal/src/ViewControllers/ThreadSettings/FingerprintViewController.m b/Signal/src/ViewControllers/ThreadSettings/FingerprintViewController.m index ffb5500c7..2005efbc6 100644 --- a/Signal/src/ViewControllers/ThreadSettings/FingerprintViewController.m +++ b/Signal/src/ViewControllers/ThreadSettings/FingerprintViewController.m @@ -519,20 +519,19 @@ typedef void (^CustomLayoutBlock)(void); - (void)verifyUnverifyButtonTapped:(UIGestureRecognizer *)gestureRecognizer { if (gestureRecognizer.state == UIGestureRecognizerStateRecognized) { - [OWSPrimaryStorage.sharedManager.newDatabaseConnection - readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - BOOL isVerified = [[OWSIdentityManager sharedManager] verificationStateForRecipientId:self.recipientId - transaction:transaction] - == OWSVerificationStateVerified; + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + BOOL isVerified = [[OWSIdentityManager sharedManager] verificationStateForRecipientId:self.recipientId + transaction:transaction] + == OWSVerificationStateVerified; - OWSVerificationState newVerificationState - = (isVerified ? OWSVerificationStateDefault : OWSVerificationStateVerified); - [[OWSIdentityManager sharedManager] setVerificationState:newVerificationState - identityKey:self.identityKey - recipientId:self.recipientId - isUserInitiatedChange:YES - transaction:transaction]; - }]; + OWSVerificationState newVerificationState + = (isVerified ? OWSVerificationStateDefault : OWSVerificationStateVerified); + [[OWSIdentityManager sharedManager] setVerificationState:newVerificationState + identityKey:self.identityKey + recipientId:self.recipientId + isUserInitiatedChange:YES + transaction:transaction]; + } error:nil]; [self dismissViewControllerAnimated:YES completion:nil]; } diff --git a/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m b/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m index 792bf68cf..90801632c 100644 --- a/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m +++ b/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m @@ -1036,7 +1036,7 @@ const CGFloat kIconViewLength = 24; } if (self.disappearingMessagesConfiguration.dictionaryValueDidChange) { - [self.editingDatabaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { [self.disappearingMessagesConfiguration saveWithTransaction:transaction]; // MJK TODO - should be safe to remove this senderTimestamp OWSDisappearingConfigurationUpdateInfoMessage *infoMessage = @@ -1053,7 +1053,7 @@ const CGFloat kIconViewLength = 24; thread:self.thread]; [self.messageSenderJobQueue addMessage:message transaction:transaction]; - }]; + } error:nil]; } } @@ -1170,10 +1170,10 @@ const CGFloat kIconViewLength = 24; TSOutgoingMessage *message = [TSOutgoingMessage outgoingMessageInThread:gThread groupMetaMessage:TSGroupMetaMessageQuit expiresInSeconds:0]; - [self.editingDatabaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { [self.messageSenderJobQueue addMessage:message transaction:transaction]; [gThread leaveGroupWithTransaction:transaction]; - }]; + } error:nil]; [self.navigationController popViewControllerAnimated:YES]; } @@ -1389,9 +1389,9 @@ const CGFloat kIconViewLength = 24; - (void)setThreadMutedUntilDate:(nullable NSDate *)value { - [self.editingDatabaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction * _Nonnull transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction * _Nonnull transaction) { [self.thread updateWithMutedUntilDate:value transaction:transaction]; - }]; + } error:nil]; [self updateTableContents]; } @@ -1456,9 +1456,9 @@ const CGFloat kIconViewLength = 24; didPickConversationColor:(OWSConversationColor *_Nonnull)conversationColor { OWSLogDebug(@"picked color: %@", conversationColor.name); - [self.editingDatabaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { [self.thread updateConversationColorName:conversationColor.name transaction:transaction]; - }]; + } error:nil]; [self.contactsManager.avatarCache removeAllImages]; [self updateTableContents]; diff --git a/Signal/src/environment/SignalApp.m b/Signal/src/environment/SignalApp.m index 9bba0cdbf..7a7287904 100644 --- a/Signal/src/environment/SignalApp.m +++ b/Signal/src/environment/SignalApp.m @@ -62,10 +62,9 @@ NS_ASSUME_NONNULL_BEGIN animated:(BOOL)isAnimated { __block TSThread *thread = nil; - [OWSPrimaryStorage.dbReadWriteConnection - readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { - thread = [TSContactThread getOrCreateThreadWithContactId:recipientId transaction:transaction]; - }]; + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + thread = [TSContactThread getOrCreateThreadWithContactId:recipientId transaction:transaction]; + } error:nil]; [self presentConversationForThread:thread action:action animated:(BOOL)isAnimated]; } diff --git a/Signal/src/util/Backup/OWSBackup.m b/Signal/src/util/Backup/OWSBackup.m index 02f242281..5fd3c932d 100644 --- a/Signal/src/util/Backup/OWSBackup.m +++ b/Signal/src/util/Backup/OWSBackup.m @@ -867,10 +867,10 @@ NSError *OWSBackupErrorWithDescription(NSString *description) return [AnyPromise promiseWithValue:error]; } - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { // This should overwrite the attachment pointer with an attachment stream. [stream saveWithTransaction:transaction]; - }]; + } error:nil]; return [AnyPromise promiseWithValue:@(1)]; } diff --git a/Signal/src/util/Backup/OWSBackupExportJob.m b/Signal/src/util/Backup/OWSBackupExportJob.m index dd85d9f70..dfff21b97 100644 --- a/Signal/src/util/Backup/OWSBackupExportJob.m +++ b/Signal/src/util/Backup/OWSBackupExportJob.m @@ -864,9 +864,9 @@ NS_ASSUME_NONNULL_BEGIN backupFragment.relativeFilePath = attachmentExport.relativeFilePath; backupFragment.attachmentId = attachmentExport.attachmentId; backupFragment.uncompressedDataLength = exportItem.uncompressedDataLength; - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [backupFragment saveWithTransaction:transaction]; - }]; + } error:nil]; OWSLogVerbose(@"saved attachment: %@ as %@", attachmentExport.attachmentFilePath, @@ -1102,7 +1102,7 @@ NS_ASSUME_NONNULL_BEGIN // After every successful backup export, we can (and should) cull metadata // for any backup fragment (i.e. CloudKit record) that wasn't involved in // the latest backup export. - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { NSArray *allRecordNames = [transaction allKeysInCollection:[OWSBackupFragment collection]]; NSMutableSet *obsoleteRecordNames = [NSMutableSet new]; @@ -1110,7 +1110,7 @@ NS_ASSUME_NONNULL_BEGIN [obsoleteRecordNames minusSet:activeRecordNames]; [transaction removeObjectsForKeys:obsoleteRecordNames.allObjects inCollection:[OWSBackupFragment collection]]; - }]; + } error:nil]; } - (AnyPromise *)cleanUpCloudWithActiveRecordNames:(NSSet *)activeRecordNames diff --git a/Signal/src/util/Backup/OWSBackupImportJob.m b/Signal/src/util/Backup/OWSBackupImportJob.m index 8b9d6a15d..145ae74e7 100644 --- a/Signal/src/util/Backup/OWSBackupImportJob.m +++ b/Signal/src/util/Backup/OWSBackupImportJob.m @@ -157,11 +157,11 @@ NSString *const kOWSBackup_ImportDatabaseKeySpec = @"kOWSBackup_ImportDatabaseKe [allItems addObjectsFromArray:self.attachmentsItems]; // Record metadata for all items, so that we can re-use them in incremental backups after the restore. - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { for (OWSBackupFragment *item in allItems) { [item saveWithTransaction:transaction]; } - }]; + } error:nil]; return [self downloadFilesFromCloud:blockingItems] .thenInBackground(^{ @@ -390,7 +390,7 @@ NSString *const kOWSBackup_ImportDatabaseKeySpec = @"kOWSBackup_ImportDatabaseKe } __block NSUInteger count = 0; - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { for (OWSBackupFragment *item in self.attachmentsItems) { if (self.isComplete) { return; @@ -428,7 +428,7 @@ NSString *const kOWSBackup_ImportDatabaseKeySpec = @"kOWSBackup_ImportDatabaseKe @"Indicates that the backup import data is being restored.") progress:@(count / (CGFloat)self.attachmentsItems.count)]; } - }]; + } error:nil]; OWSLogError(@"enqueued lazy restore of %zd files.", count); @@ -456,7 +456,7 @@ NSString *const kOWSBackup_ImportDatabaseKeySpec = @"kOWSBackup_ImportDatabaseKe NSMutableDictionary *restoredEntityCounts = [NSMutableDictionary new]; __block unsigned long long copiedEntities = 0; __block BOOL aborted = NO; - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { for (NSString *collection in collectionsToRestore) { if ([collection isEqualToString:[OWSDatabaseMigration collection]]) { // It's okay if there are existing migrations; we'll clear those @@ -585,7 +585,7 @@ NSString *const kOWSBackup_ImportDatabaseKeySpec = @"kOWSBackup_ImportDatabaseKe } } } - }]; + } error:nil]; if (aborted) { return [AnyPromise promiseWithValue:OWSBackupErrorWithDescription(@"Backup import failed.")]; diff --git a/Signal/src/util/OWSOrphanDataCleaner.m b/Signal/src/util/OWSOrphanDataCleaner.m index f901f7524..b89ad9499 100644 --- a/Signal/src/util/OWSOrphanDataCleaner.m +++ b/Signal/src/util/OWSOrphanDataCleaner.m @@ -525,14 +525,14 @@ typedef void (^OrphanDataBlock)(OWSOrphanData *); success:^{ OWSLogInfo(@"Completed orphan data cleanup."); - [databaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [transaction setObject:AppVersion.sharedInstance.currentAppVersion forKey:OWSOrphanDataCleaner_LastCleaningVersionKey inCollection:OWSOrphanDataCleaner_Collection]; [transaction setDate:[NSDate new] forKey:OWSOrphanDataCleaner_LastCleaningDateKey inCollection:OWSOrphanDataCleaner_Collection]; - }]; + } error:nil]; if (completion) { completion(); @@ -613,7 +613,7 @@ typedef void (^OrphanDataBlock)(OWSOrphanData *); NSDate *appLaunchTime = CurrentAppContext().appLaunchTime; NSTimeInterval thresholdTimestamp = appLaunchTime.timeIntervalSince1970 - kMinimumOrphanAgeSeconds; NSDate *thresholdDate = [NSDate dateWithTimeIntervalSince1970:thresholdTimestamp]; - [databaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { NSUInteger interactionsRemoved = 0; for (NSString *interactionId in orphanData.interactionIds) { if (!self.isMainAppAndActive) { @@ -674,7 +674,7 @@ typedef void (^OrphanDataBlock)(OWSOrphanData *); [attachmentStream removeWithTransaction:transaction]; } OWSLogInfo(@"Deleted orphan attachments: %zu", attachmentsRemoved); - }]; + } error:nil]; if (shouldAbort) { return nil; diff --git a/Signal/src/util/Pastelog.m b/Signal/src/util/Pastelog.m index f6b76ec5c..49ec63dd5 100644 --- a/Signal/src/util/Pastelog.m +++ b/Signal/src/util/Pastelog.m @@ -596,16 +596,16 @@ typedef void (^DebugLogUploadFailure)(DebugLogUploader *uploader, NSError *error DispatchMainThreadSafe(^{ __block TSThread *thread = nil; - [OWSPrimaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { thread = [TSContactThread getOrCreateThreadWithContactId:recipientId transaction:transaction]; - }]; - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + } error:nil]; + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { [ThreadUtil enqueueMessageWithText:url.absoluteString inThread:thread quotedReplyModel:nil linkPreviewDraft:nil transaction:transaction]; - }]; + } error:nil]; }); // Also copy to pasteboard. @@ -624,13 +624,13 @@ typedef void (^DebugLogUploadFailure)(DebugLogUploader *uploader, NSError *error }]; DispatchMainThreadSafe(^{ if (thread) { - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { [ThreadUtil enqueueMessageWithText:url.absoluteString inThread:thread quotedReplyModel:nil linkPreviewDraft:nil transaction:transaction]; - }]; + } error:nil]; } else { [Pastelog showFailureAlertWithMessage:@"Could not find last thread."]; } diff --git a/SignalMessaging/ViewControllers/SelectThreadViewController.m b/SignalMessaging/ViewControllers/SelectThreadViewController.m index 8e3da9243..489d64c7a 100644 --- a/SignalMessaging/ViewControllers/SelectThreadViewController.m +++ b/SignalMessaging/ViewControllers/SelectThreadViewController.m @@ -341,9 +341,9 @@ NS_ASSUME_NONNULL_BEGIN } __block TSThread *thread = nil; - [OWSPrimaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { thread = [TSContactThread getOrCreateThreadWithContactId:signalAccount.recipientId transaction:transaction]; - }]; + } error:nil]; OWSAssertDebug(thread); [self.selectThreadViewDelegate threadWasSelected:thread]; diff --git a/SignalMessaging/ViewControllers/SharingThreadPickerViewController.m b/SignalMessaging/ViewControllers/SharingThreadPickerViewController.m index e0645912a..ec484e7d6 100644 --- a/SignalMessaging/ViewControllers/SharingThreadPickerViewController.m +++ b/SignalMessaging/ViewControllers/SharingThreadPickerViewController.m @@ -375,6 +375,9 @@ typedef void (^SendMessageBlock)(SendCompletionBlock completion); OWSAssertIsOnMainThread(); // TODO - in line with QuotedReply and other message attachments, saving should happen as part of sending // preparation rather than duplicated here and in the SAE + + // TODO: <-------- + [self.dbReadWriteConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { if (contactShare.avatarImage) { @@ -552,7 +555,7 @@ typedef void (^SendMessageBlock)(SendCompletionBlock completion); OWSLogDebug(@"Confirming identity for recipient: %@", recipientId); - [self.dbReadWriteConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { OWSVerificationState verificationState = [[OWSIdentityManager sharedManager] verificationStateForRecipientId:recipientId transaction:transaction]; switch (verificationState) { diff --git a/SignalMessaging/contacts/OWSContactsManager.m b/SignalMessaging/contacts/OWSContactsManager.m index 15c17fb92..bea437087 100644 --- a/SignalMessaging/contacts/OWSContactsManager.m +++ b/SignalMessaging/contacts/OWSContactsManager.m @@ -340,7 +340,7 @@ NSString *const OWSContactsManagerKeyNextFullIntersectionDate = @"OWSContactsMan OWSAssertDebug(recipientIdsForIntersection.count > 0); dispatch_async(self.serialQueue, ^{ - [self.dbReadConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [transaction setObject:recipientIdsForIntersection forKey:OWSContactsManagerKeyLastKnownContactPhoneNumbers inCollection:OWSContactsManagerCollection]; @@ -354,7 +354,7 @@ NSString *const OWSContactsManagerKeyNextFullIntersectionDate = @"OWSContactsMan forKey:OWSContactsManagerKeyNextFullIntersectionDate inCollection:OWSContactsManagerCollection]; } - }]; + } error:nil]; }); } @@ -522,7 +522,7 @@ NSString *const OWSContactsManagerKeyNextFullIntersectionDate = @"OWSContactsMan } // Update cached SignalAccounts on disk - [self.dbWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { OWSLogInfo(@"Saving %lu SignalAccounts", (unsigned long)accountsToSave.count); for (SignalAccount *signalAccount in accountsToSave) { OWSLogVerbose(@"Saving SignalAccount: %@", signalAccount); @@ -553,7 +553,7 @@ NSString *const OWSContactsManagerKeyNextFullIntersectionDate = @"OWSContactsMan [signalAccounts sortUsingComparator:self.signalAccountComparator]; } } - }]; + } error:nil]; dispatch_async(dispatch_get_main_queue(), ^{ [self updateSignalAccounts:signalAccounts]; diff --git a/SignalMessaging/contacts/OWSSyncManager.m b/SignalMessaging/contacts/OWSSyncManager.m index 636cb31ce..2eeb3c827 100644 --- a/SignalMessaging/contacts/OWSSyncManager.m +++ b/SignalMessaging/contacts/OWSSyncManager.m @@ -252,9 +252,9 @@ NSString *const kSyncManagerLastContactSyncKey = @"kTSStorageManagerOWSSyncManag showTypingIndicators:showTypingIndicators sendLinkPreviews:sendLinkPreviews]; - [self.editingDatabaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { [self.messageSenderJobQueue addMessage:syncConfigurationMessage transaction:transaction]; - }]; + } error:nil]; } #pragma mark - Local Sync diff --git a/SignalMessaging/environment/OWSSounds.m b/SignalMessaging/environment/OWSSounds.m index fb9bb7594..5be0d1fac 100644 --- a/SignalMessaging/environment/OWSSounds.m +++ b/SignalMessaging/environment/OWSSounds.m @@ -292,9 +292,9 @@ NSString *const kOWSSoundsStorageGlobalNotificationKey = @"kOWSSoundsStorageGlob - (void)setGlobalNotificationSound:(OWSSound)sound { - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { [self setGlobalNotificationSound:sound transaction:transaction]; - }]; + } error:nil]; } + (void)setGlobalNotificationSound:(OWSSound)sound transaction:(YapDatabaseReadWriteTransaction *)transaction diff --git a/SignalMessaging/environment/VersionMigrations.m b/SignalMessaging/environment/VersionMigrations.m index d1f7412ba..c81e76932 100644 --- a/SignalMessaging/environment/VersionMigrations.m +++ b/SignalMessaging/environment/VersionMigrations.m @@ -156,10 +156,9 @@ NS_ASSUME_NONNULL_BEGIN NSError *deleteError; if ([fm removeItemAtPath:bloomFilterPath error:&deleteError]) { OWSLogInfo(@"Successfully removed bloom filter cache."); - [OWSPrimaryStorage.dbReadWriteConnection - readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { - [transaction removeAllObjectsInCollection:@"TSRecipient"]; - }]; + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [transaction removeAllObjectsInCollection:@"TSRecipient"]; + } error:nil]; OWSLogInfo(@"Removed all TSRecipient records - will be replaced by SignalRecipients at next address sync."); } else { OWSLogError(@"Failed to remove bloom filter cache with error: %@", deleteError.localizedDescription); @@ -174,7 +173,7 @@ NS_ASSUME_NONNULL_BEGIN // Versions less than or equal to 1.2.0 didn't store public chat mappings + (void)updatePublicChatMapping { - [OWSPrimaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction * _Nonnull transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction * _Nonnull transaction) { for (LKPublicChat *chat in LKPublicChatAPI.defaultChats) { TSGroupThread *thread = [TSGroupThread threadWithGroupId:[LKGroupUtilities getEncodedOpenGroupIDAsData:chat.id] transaction:transaction]; if (thread != nil) { @@ -203,7 +202,7 @@ NS_ASSUME_NONNULL_BEGIN [thread saveWithTransaction:transaction]; } } - }]; + } error:nil]; } @end diff --git a/SignalMessaging/environment/migrations/OWSDatabaseMigration.m b/SignalMessaging/environment/migrations/OWSDatabaseMigration.m index 1ce139f3e..27dcb3f15 100644 --- a/SignalMessaging/environment/migrations/OWSDatabaseMigration.m +++ b/SignalMessaging/environment/migrations/OWSDatabaseMigration.m @@ -5,6 +5,7 @@ #import "OWSDatabaseMigration.h" #import #import +#import NS_ASSUME_NONNULL_BEGIN @@ -70,8 +71,7 @@ NS_ASSUME_NONNULL_BEGIN OWSDatabaseConnection *dbConnection = (OWSDatabaseConnection *)self.primaryStorage.newDatabaseConnection; - [dbConnection - asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { [self runUpWithTransaction:transaction]; } completionBlock:^{ diff --git a/SignalMessaging/environment/migrations/OWSDatabaseMigrationRunner.m b/SignalMessaging/environment/migrations/OWSDatabaseMigrationRunner.m index d6e920217..3f80dd3e0 100644 --- a/SignalMessaging/environment/migrations/OWSDatabaseMigrationRunner.m +++ b/SignalMessaging/environment/migrations/OWSDatabaseMigrationRunner.m @@ -78,7 +78,7 @@ NS_ASSUME_NONNULL_BEGIN [knownMigrationIds addObject:migration.uniqueId]; } - [self.primaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { NSArray *savedMigrationIds = [transaction allKeysInCollection:OWSDatabaseMigration.collection]; NSMutableSet *unknownMigrationIds = [NSMutableSet new]; @@ -89,7 +89,7 @@ NS_ASSUME_NONNULL_BEGIN OWSLogInfo(@"Culling unknown migration: %@", unknownMigrationId); [transaction removeObjectForKey:unknownMigrationId inCollection:OWSDatabaseMigration.collection]; } - }]; + } error:nil]; } // Run migrations serially to: diff --git a/SignalMessaging/environment/migrations/OWSResaveCollectionDBMigration.m b/SignalMessaging/environment/migrations/OWSResaveCollectionDBMigration.m index 9e20917fc..796b68f35 100644 --- a/SignalMessaging/environment/migrations/OWSResaveCollectionDBMigration.m +++ b/SignalMessaging/environment/migrations/OWSResaveCollectionDBMigration.m @@ -5,6 +5,7 @@ #import "OWSResaveCollectionDBMigration.h" #import #import +#import NS_ASSUME_NONNULL_BEGIN @@ -20,7 +21,7 @@ NS_ASSUME_NONNULL_BEGIN OWSAssertDebug(completion); NSMutableArray *recordIds = [NSMutableArray new]; - [dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { [recordIds addObjectsFromArray:[transaction allKeysInCollection:collection]]; OWSLogInfo(@"Migrating %lu records from: %@.", (unsigned long)recordIds.count, collection); } @@ -52,7 +53,7 @@ NS_ASSUME_NONNULL_BEGIN return; } - [dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { const int kBatchSize = 1000; for (int i = 0; i < kBatchSize && recordIds.count > 0; i++) { NSString *messageId = [recordIds lastObject]; diff --git a/SignalMessaging/profiles/OWSProfileManager.m b/SignalMessaging/profiles/OWSProfileManager.m index 41e545a7d..6351c3ea7 100644 --- a/SignalMessaging/profiles/OWSProfileManager.m +++ b/SignalMessaging/profiles/OWSProfileManager.m @@ -695,7 +695,7 @@ typedef void (^ProfileManagerFailureBlock)(NSError *error); // Remove blocked users and groups from profile whitelist. // // This will always succeed. - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [transaction removeObjectsForKeys:intersectingRecipientIds.allObjects inCollection:kOWSProfileManager_UserWhitelistCollection]; for (NSData *groupId in intersectingGroupIds) { @@ -703,7 +703,7 @@ typedef void (^ProfileManagerFailureBlock)(NSError *error); [transaction removeObjectForKey:groupIdKey inCollection:kOWSProfileManager_GroupWhitelistCollection]; } - }]; + } error:nil]; return @(1); }); @@ -750,7 +750,7 @@ typedef void (^ProfileManagerFailureBlock)(NSError *error); { OWSLogWarn(@"Clearing the profile whitelist."); - [self.dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [transaction removeAllObjectsInCollection:kOWSProfileManager_UserWhitelistCollection]; [transaction removeAllObjectsInCollection:kOWSProfileManager_GroupWhitelistCollection]; OWSAssertDebug(0 == [transaction numberOfKeysInCollection:kOWSProfileManager_UserWhitelistCollection]); @@ -795,7 +795,7 @@ typedef void (^ProfileManagerFailureBlock)(NSError *error); OWSAssertDebug(recipientIds); NSMutableSet *newRecipientIds = [NSMutableSet new]; - [self.dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { for (NSString *recipientId in recipientIds) { NSNumber *_Nullable oldValue = [transaction objectForKey:recipientId inCollection:kOWSProfileManager_UserWhitelistCollection]; @@ -849,7 +849,7 @@ typedef void (^ProfileManagerFailureBlock)(NSError *error); NSString *groupIdKey = [self groupKeyForGroupId:groupId]; __block BOOL didChange = NO; - [self.dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { NSNumber *_Nullable oldValue = [transaction objectForKey:groupIdKey inCollection:kOWSProfileManager_GroupWhitelistCollection]; if (oldValue && oldValue.boolValue) { @@ -1451,9 +1451,9 @@ typedef void (^ProfileManagerFailureBlock)(NSError *error); [[OWSProfileKeyMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp] inThread:thread]; [OWSProfileManager.sharedManager addThreadToProfileWhitelist:thread]; - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { [self.messageSenderJobQueue addMessage:message transaction:transaction]; - }]; + } error:nil]; } #pragma mark - Notifications diff --git a/SignalMessaging/profiles/OWSUserProfile.m b/SignalMessaging/profiles/OWSUserProfile.m index 745a78e3d..1cef30919 100644 --- a/SignalMessaging/profiles/OWSUserProfile.m +++ b/SignalMessaging/profiles/OWSUserProfile.m @@ -55,9 +55,9 @@ NSString *const kLocalProfileUniqueId = @"kLocalProfileUniqueId"; dbConnection:(YapDatabaseConnection *)dbConnection { __block OWSUserProfile *userProfile; - [dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { userProfile = [OWSUserProfile getOrBuildUserProfileForRecipientId:recipientId transaction:transaction]; - }]; + } error:nil]; return userProfile; } @@ -187,9 +187,9 @@ NSString *const kLocalProfileUniqueId = @"kLocalProfileUniqueId"; dbConnection:(YapDatabaseConnection *)dbConnection completion:(nullable OWSUserProfileCompletion)completion { - [dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [self applyChanges:changeBlock functionName:functionName transaction:transaction completion:completion]; - }]; + } error:nil]; } - (void)applyChanges:(void (^)(id))changeBlock @@ -369,9 +369,9 @@ NSString *const kLocalProfileUniqueId = @"kLocalProfileUniqueId"; dbConnection:(YapDatabaseConnection *)dbConnection completion:(nullable OWSUserProfileCompletion)completion { - [dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [self updateWithProfileKey:profileKey transaction:transaction completion:completion]; - }]; + } error:nil]; } - (void)updateWithProfileKey:(OWSAES256Key *)profileKey diff --git a/SignalMessaging/utils/OWSPreferences.m b/SignalMessaging/utils/OWSPreferences.m index 32753f223..d8622f870 100644 --- a/SignalMessaging/utils/OWSPreferences.m +++ b/SignalMessaging/utils/OWSPreferences.m @@ -11,6 +11,7 @@ #import #import #import +#import NS_ASSUME_NONNULL_BEGIN @@ -87,9 +88,9 @@ NSString *const OWSPreferencesKeySystemCallLogEnabled = @"OWSPreferencesKeySyste - (void)setValueForKey:(NSString *)key toValue:(nullable id)value { - [OWSPrimaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [self setValueForKey:key toValue:value transaction:transaction]; - }]; + } error:nil]; } - (void)setValueForKey:(NSString *)key diff --git a/SignalMessaging/utils/ThreadUtil.m b/SignalMessaging/utils/ThreadUtil.m index 590431783..ac720a1d7 100644 --- a/SignalMessaging/utils/ThreadUtil.m +++ b/SignalMessaging/utils/ThreadUtil.m @@ -87,7 +87,7 @@ typedef void (^BuildOutgoingMessageCompletionBlock)(TSOutgoingMessage *savedMess + (void)enqueueDeviceLinkMessage:(LKDeviceLinkMessage *)message { - [self.dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [self.messageSenderJobQueue addMessage:message transaction:transaction]; }]; } @@ -203,6 +203,9 @@ typedef void (^BuildOutgoingMessageCompletionBlock)(TSOutgoingMessage *savedMess block:^(void (^benchmarkCompletion)(void)) { // To avoid blocking the send flow, we dispatch an async write from within this read // transaction + + // TODO: <------- + [self.dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull writeTransaction) { [message saveWithTransaction:writeTransaction]; @@ -251,7 +254,7 @@ typedef void (^BuildOutgoingMessageCompletionBlock)(TSOutgoingMessage *savedMess contactShare:contactShare linkPreview:nil]; - [self.dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { [message saveWithTransaction:transaction]; [self.messageSenderJobQueue addMessage:message transaction:transaction]; }]; @@ -266,7 +269,7 @@ typedef void (^BuildOutgoingMessageCompletionBlock)(TSOutgoingMessage *savedMess TSOutgoingMessage *message = [TSOutgoingMessage outgoingMessageInThread:thread groupMetaMessage:TSGroupMetaMessageQuit expiresInSeconds:0]; - [self.dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { [self.messageSenderJobQueue addMessage:message transaction:transaction]; }]; } @@ -701,25 +704,24 @@ typedef void (^BuildOutgoingMessageCompletionBlock)(TSOutgoingMessage *savedMess { OWSLogInfo(@""); - [OWSPrimaryStorage.sharedManager.newDatabaseConnection - readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - [self removeAllObjectsInCollection:[TSThread collection] - class:[TSThread class] + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [self removeAllObjectsInCollection:[TSThread collection] + class:[TSThread class] + transaction:transaction]; + [self removeAllObjectsInCollection:[TSInteraction collection] + class:[TSInteraction class] + transaction:transaction]; + [self removeAllObjectsInCollection:[TSAttachment collection] + class:[TSAttachment class] + transaction:transaction]; + @try { + [self removeAllObjectsInCollection:[SignalRecipient collection] + class:[SignalRecipient class] transaction:transaction]; - [self removeAllObjectsInCollection:[TSInteraction collection] - class:[TSInteraction class] - transaction:transaction]; - [self removeAllObjectsInCollection:[TSAttachment collection] - class:[TSAttachment class] - transaction:transaction]; - @try { - [self removeAllObjectsInCollection:[SignalRecipient collection] - class:[SignalRecipient class] - transaction:transaction]; - } @catch (NSException *exception) { - // Do nothing - } - }]; + } @catch (NSException *exception) { + // Do nothing + } + }]; [TSAttachmentStream deleteAttachments]; } diff --git a/SignalServiceKit/src/Account/TSAccountManager.m b/SignalServiceKit/src/Account/TSAccountManager.m index fec933853..85af560d1 100644 --- a/SignalServiceKit/src/Account/TSAccountManager.m +++ b/SignalServiceKit/src/Account/TSAccountManager.m @@ -251,9 +251,9 @@ NSString *const TSAccountManager_NeedsAccountAttributesUpdateKey = @"TSAccountMa - (uint32_t)getOrGenerateRegistrationId { __block uint32_t result; - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { result = [self getOrGenerateRegistrationId:transaction]; - }]; + } error:nil]; return result; } @@ -523,11 +523,11 @@ NSString *const TSAccountManager_NeedsAccountAttributesUpdateKey = @"TSAccountMa - (void)storeServerAuthToken:(NSString *)authToken { - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [transaction setObject:authToken forKey:TSAccountManager_ServerAuthToken inCollection:TSAccountManager_UserAccountCollection]; - }]; + } error:nil]; } + (void)unregisterTextSecureWithSuccess:(void (^)(void))success failure:(void (^)(NSError *error))failureBlock @@ -599,7 +599,7 @@ NSString *const TSAccountManager_NeedsAccountAttributesUpdateKey = @"TSAccountMa self.cachedIsDeregistered = @(isDeregistered); } - [self.dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [transaction setObject:@(isDeregistered) forKey:TSAccountManager_IsDeregisteredKey inCollection:TSAccountManager_UserAccountCollection]; @@ -623,7 +623,7 @@ NSString *const TSAccountManager_NeedsAccountAttributesUpdateKey = @"TSAccountMa _cachedLocalNumber = nil; _phoneNumberAwaitingVerification = nil; _cachedIsDeregistered = nil; - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [transaction removeAllObjectsInCollection:TSAccountManager_UserAccountCollection]; [[OWSPrimaryStorage sharedManager] resetSessionStore:transaction]; @@ -631,7 +631,7 @@ NSString *const TSAccountManager_NeedsAccountAttributesUpdateKey = @"TSAccountMa [transaction setObject:localNumber forKey:TSAccountManager_ReregisteringPhoneNumberKey inCollection:TSAccountManager_UserAccountCollection]; - }]; + } error:nil]; [self postRegistrationStateDidChangeNotification]; @@ -723,7 +723,7 @@ NSString *const TSAccountManager_NeedsAccountAttributesUpdateKey = @"TSAccountMa } AnyPromise *promise = [self performUpdateAccountAttributes]; promise = promise.then(^(id value) { - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { // Clear the update request unless a new update has been requested // while this update was in flight. NSDate *_Nullable latestUpdateRequestDate = @@ -733,7 +733,7 @@ NSString *const TSAccountManager_NeedsAccountAttributesUpdateKey = @"TSAccountMa [transaction removeObjectForKey:TSAccountManager_NeedsAccountAttributesUpdateKey inCollection:TSAccountManager_UserAccountCollection]; } - }]; + } error:nil]; }); return promise; } diff --git a/SignalServiceKit/src/Contacts/ContactsUpdater.m b/SignalServiceKit/src/Contacts/ContactsUpdater.m index 077240acb..93871eebe 100644 --- a/SignalServiceKit/src/Contacts/ContactsUpdater.m +++ b/SignalServiceKit/src/Contacts/ContactsUpdater.m @@ -96,7 +96,7 @@ NS_ASSUME_NONNULL_BEGIN NSSet *registeredRecipientIds = operation.registeredRecipientIds; NSMutableSet *recipients = [NSMutableSet new]; - [OWSPrimaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { for (NSString *recipientId in recipientIdsToLookup) { if ([registeredRecipientIds containsObject:recipientId]) { SignalRecipient *recipient = @@ -106,7 +106,7 @@ NS_ASSUME_NONNULL_BEGIN [SignalRecipient markRecipientAsUnregistered:recipientId transaction:transaction]; } } - }]; + } error:nil]; dispatch_async(dispatch_get_main_queue(), ^{ success([recipients copy]); diff --git a/SignalServiceKit/src/Contacts/Threads/TSContactThread.m b/SignalServiceKit/src/Contacts/Threads/TSContactThread.m index 88075abc5..29942f244 100644 --- a/SignalServiceKit/src/Contacts/Threads/TSContactThread.m +++ b/SignalServiceKit/src/Contacts/Threads/TSContactThread.m @@ -53,9 +53,9 @@ NSString *const TSContactThreadPrefix = @"c"; OWSAssertDebug(contactId.length > 0); __block TSContactThread *thread; - [[self dbReadWriteConnection] readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { thread = [self getOrCreateThreadWithContactId:contactId transaction:transaction]; - }]; + } error:nil]; return thread; } diff --git a/SignalServiceKit/src/Contacts/Threads/TSGroupThread.m b/SignalServiceKit/src/Contacts/Threads/TSGroupThread.m index 0de01ae3d..0dd5c92d4 100644 --- a/SignalServiceKit/src/Contacts/Threads/TSGroupThread.m +++ b/SignalServiceKit/src/Contacts/Threads/TSGroupThread.m @@ -89,9 +89,9 @@ NSString *const TSGroupThread_NotificationKey_UniqueId = @"TSGroupThread_Notific OWSAssertDebug(groupId.length > 0); __block TSGroupThread *thread; - [[self dbReadWriteConnection] readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { thread = [self getOrCreateThreadWithGroupId:groupId groupType:groupType transaction:transaction]; - }]; + } error:nil]; return thread; } @@ -117,9 +117,9 @@ NSString *const TSGroupThread_NotificationKey_UniqueId = @"TSGroupThread_Notific OWSAssertDebug(groupModel.groupId.length > 0); __block TSGroupThread *thread; - [[self dbReadWriteConnection] readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { thread = [self getOrCreateThreadWithGroupModel:groupModel transaction:transaction]; - }]; + } error:nil]; return thread; } @@ -242,9 +242,9 @@ NSString *const TSGroupThread_NotificationKey_UniqueId = @"TSGroupThread_Notific - (void)leaveGroupWithSneakyTransaction { - [self.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { [self leaveGroupWithTransaction:transaction]; - }]; + } error:nil]; } - (void)leaveGroupWithTransaction:(YapDatabaseReadWriteTransaction *)transaction @@ -272,9 +272,9 @@ NSString *const TSGroupThread_NotificationKey_UniqueId = @"TSGroupThread_Notific - (void)updateAvatarWithAttachmentStream:(TSAttachmentStream *)attachmentStream { - [self.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [self updateAvatarWithAttachmentStream:attachmentStream transaction:transaction]; - }]; + } error:nil]; } - (void)updateAvatarWithAttachmentStream:(TSAttachmentStream *)attachmentStream diff --git a/SignalServiceKit/src/Devices/OWSDevice.m b/SignalServiceKit/src/Devices/OWSDevice.m index 4b13b5e51..f38049231 100644 --- a/SignalServiceKit/src/Devices/OWSDevice.m +++ b/SignalServiceKit/src/Devices/OWSDevice.m @@ -66,23 +66,21 @@ NSString *const kOWSPrimaryStorage_MayHaveLinkedDevices = @"kTSStorageManager_Ma - (void)clearMayHaveLinkedDevices { // Note that we write async to avoid opening transactions within transactions. - [OWSPrimaryStorage.sharedManager.newDatabaseConnection - asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { - [transaction setObject:@(NO) - forKey:kOWSPrimaryStorage_MayHaveLinkedDevices - inCollection:kOWSPrimaryStorage_OWSDeviceCollection]; - }]; + [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [transaction setObject:@(NO) + forKey:kOWSPrimaryStorage_MayHaveLinkedDevices + inCollection:kOWSPrimaryStorage_OWSDeviceCollection]; + }]; } - (void)setMayHaveLinkedDevices { // Note that we write async to avoid opening transactions within transactions. - [OWSPrimaryStorage.sharedManager.newDatabaseConnection - asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { - [transaction setObject:@(YES) - forKey:kOWSPrimaryStorage_MayHaveLinkedDevices - inCollection:kOWSPrimaryStorage_OWSDeviceCollection]; - }]; + [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [transaction setObject:@(YES) + forKey:kOWSPrimaryStorage_MayHaveLinkedDevices + inCollection:kOWSPrimaryStorage_OWSDeviceCollection]; + }]; } - (BOOL)hasReceivedSyncMessageInLastSeconds:(NSTimeInterval)intervalSeconds diff --git a/SignalServiceKit/src/Devices/OWSRecordTranscriptJob.m b/SignalServiceKit/src/Devices/OWSRecordTranscriptJob.m index f6e7a702e..35ae6e23c 100644 --- a/SignalServiceKit/src/Devices/OWSRecordTranscriptJob.m +++ b/SignalServiceKit/src/Devices/OWSRecordTranscriptJob.m @@ -130,14 +130,13 @@ NS_ASSUME_NONNULL_BEGIN success:^(NSArray *attachmentStreams) { OWSAssertDebug(attachmentStreams.count == 1); TSAttachmentStream *attachmentStream = attachmentStreams.firstObject; - [self.primaryStorage.newDatabaseConnection - readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - [outgoingMessage setQuotedMessageThumbnailAttachmentStream:attachmentStream]; - [outgoingMessage saveWithTransaction:transaction]; - if (serverID != 0) { - [OWSPrimaryStorage.sharedManager setIDForMessageWithServerID:serverID to:outgoingMessage.uniqueId in:transaction]; - } - }]; + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [outgoingMessage setQuotedMessageThumbnailAttachmentStream:attachmentStream]; + [outgoingMessage saveWithTransaction:transaction]; + if (serverID != 0) { + [OWSPrimaryStorage.sharedManager setIDForMessageWithServerID:serverID to:outgoingMessage.uniqueId in:transaction]; + } + } error:nil]; } failure:^(NSError *error) { OWSLogWarn(@"failed to fetch thumbnail for transcript: %lu with error: %@", diff --git a/SignalServiceKit/src/Messages/Attachments/OWSAttachmentDownloads.m b/SignalServiceKit/src/Messages/Attachments/OWSAttachmentDownloads.m index 834540112..6f1cbb573 100644 --- a/SignalServiceKit/src/Messages/Attachments/OWSAttachmentDownloads.m +++ b/SignalServiceKit/src/Messages/Attachments/OWSAttachmentDownloads.m @@ -287,27 +287,26 @@ typedef void (^AttachmentDownloadFailure)(NSError *error); self.downloadingJobMap[job.attachmentPointer.uniqueId] = job; } - [self.primaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { job.attachmentPointer.state = TSAttachmentPointerStateDownloading; [job.attachmentPointer saveWithTransaction:transaction]; if (job.message) { [job.message touchWithTransaction:transaction]; } - }]; + } error:nil]; [self retrieveAttachmentForJob:job success:^(TSAttachmentStream *attachmentStream) { OWSLogVerbose(@"Attachment download succeeded."); - [self.primaryStorage.dbReadWriteConnection - readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - [attachmentStream saveWithTransaction:transaction]; + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [attachmentStream saveWithTransaction:transaction]; - if (job.message) { - [job.message touchWithTransaction:transaction]; - } - }]; + if (job.message) { + [job.message touchWithTransaction:transaction]; + } + } error:nil]; job.success(attachmentStream); @@ -320,16 +319,15 @@ typedef void (^AttachmentDownloadFailure)(NSError *error); failure:^(NSError *error) { OWSLogError(@"Attachment download failed with error: %@", error); - [self.primaryStorage.dbReadWriteConnection - readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - job.attachmentPointer.mostRecentFailureLocalizedText = error.localizedDescription; - job.attachmentPointer.state = TSAttachmentPointerStateFailed; - [job.attachmentPointer saveWithTransaction:transaction]; + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + job.attachmentPointer.mostRecentFailureLocalizedText = error.localizedDescription; + job.attachmentPointer.state = TSAttachmentPointerStateFailed; + [job.attachmentPointer saveWithTransaction:transaction]; - if (job.message) { - [job.message touchWithTransaction:transaction]; - } - }]; + if (job.message) { + [job.message touchWithTransaction:transaction]; + } + } error:nil]; @synchronized(self) { [self.downloadingJobMap removeObjectForKey:job.attachmentPointer.uniqueId]; diff --git a/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m b/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m index eb59975a8..40e4b9d2f 100644 --- a/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m +++ b/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m @@ -545,7 +545,7 @@ typedef void (^OWSLoadedThumbnailSuccess)(OWSLoadedThumbnail *loadedThumbnail); { OWSAssertDebug(changeBlock); - [self.dbReadWriteConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { NSString *collection = [TSAttachmentStream collection]; TSAttachmentStream *latestInstance = [transaction objectForKey:self.uniqueId inCollection:collection]; if (!latestInstance) { diff --git a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m index 71de3d801..90e5d6929 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m @@ -389,7 +389,7 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt if (attachmentIds.count < 1) { return; } - [self.dbReadWriteConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { for (NSString *attachmentId in attachmentIds) { // We need to fetch each attachment, since [TSAttachment removeWithTransaction:] does important work. TSAttachment *_Nullable attachment = @@ -672,9 +672,9 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt - (void)updateWithCustomMessage:(NSString *)customMessage { - [self.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [self updateWithCustomMessage:customMessage transaction:transaction]; - }]; + } error:nil]; } - (void)saveIsCalculatingProofOfWork:(BOOL)isCalculatingPoW withTransaction:(YapDatabaseReadWriteTransaction *)transaction diff --git a/SignalServiceKit/src/Messages/OWSBatchMessageProcessor.m b/SignalServiceKit/src/Messages/OWSBatchMessageProcessor.m index 5ace580ae..1a36551ca 100644 --- a/SignalServiceKit/src/Messages/OWSBatchMessageProcessor.m +++ b/SignalServiceKit/src/Messages/OWSBatchMessageProcessor.m @@ -168,9 +168,9 @@ NSString *const OWSMessageContentJobFinderExtensionGroup = @"OWSMessageContentJo - (void)removeJobsWithIds:(NSArray *)uniqueIds { - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { [transaction removeObjectsForKeys:uniqueIds inCollection:[OWSMessageContentJob collection]]; - }]; + } error:nil]; } + (YapDatabaseView *)databaseExtension @@ -418,7 +418,7 @@ NSString *const OWSMessageContentJobFinderExtensionGroup = @"OWSMessageContentJo AssertOnDispatchQueue(self.serialQueue); NSMutableArray *processedJobs = [NSMutableArray new]; - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { for (OWSMessageContentJob *job in jobs) { void (^reportFailure)(YapDatabaseReadWriteTransaction *transaction) = ^( @@ -453,7 +453,7 @@ NSString *const OWSMessageContentJobFinderExtensionGroup = @"OWSMessageContentJo break; } } - }]; + } error:nil]; return processedJobs; } diff --git a/SignalServiceKit/src/Messages/OWSDisappearingMessagesJob.m b/SignalServiceKit/src/Messages/OWSDisappearingMessagesJob.m index 3a6e6da19..ea845e659 100644 --- a/SignalServiceKit/src/Messages/OWSDisappearingMessagesJob.m +++ b/SignalServiceKit/src/Messages/OWSDisappearingMessagesJob.m @@ -126,7 +126,7 @@ void AssertIsOnDisappearingMessagesQueue() OWSBackgroundTask *_Nullable backgroundTask = [OWSBackgroundTask backgroundTaskWithLabelStr:__PRETTY_FUNCTION__]; __block NSUInteger expirationCount = 0; - [self.databaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { [self.disappearingMessagesFinder enumerateExpiredMessagesWithBlock:^(TSMessage *message) { // sanity check if (message.expiresAt > now) { @@ -139,7 +139,7 @@ void AssertIsOnDisappearingMessagesQueue() expirationCount++; } transaction:transaction]; - }]; + } error:nil]; OWSLogDebug(@"Removed %lu expired messages", (unsigned long)expirationCount); @@ -266,9 +266,9 @@ void AssertIsOnDisappearingMessagesQueue() dispatch_async(OWSDisappearingMessagesJob.serialQueue, ^{ // Theoretically this shouldn't be necessary, but there was a race condition when receiving a backlog // of messages across timer changes which could cause a disappearing message's timer to never be started. - [self.databaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { [self cleanupMessagesWhichFailedToStartExpiringWithTransaction:transaction]; - }]; + } error:nil]; [self runLoop]; }); diff --git a/SignalServiceKit/src/Messages/OWSFailedAttachmentDownloadsJob.m b/SignalServiceKit/src/Messages/OWSFailedAttachmentDownloadsJob.m index d13287880..a26b7dfc0 100644 --- a/SignalServiceKit/src/Messages/OWSFailedAttachmentDownloadsJob.m +++ b/SignalServiceKit/src/Messages/OWSFailedAttachmentDownloadsJob.m @@ -77,18 +77,17 @@ static NSString *const OWSFailedAttachmentDownloadsJobAttachmentStateIndex = @"i - (void)run { __block uint count = 0; - [[self.primaryStorage newDatabaseConnection] - readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { - [self enumerateAttemptingOutAttachmentsWithBlock:^(TSAttachmentPointer *attachment) { - // sanity check - if (attachment.state != TSAttachmentPointerStateFailed) { - attachment.state = TSAttachmentPointerStateFailed; - [attachment saveWithTransaction:transaction]; - count++; - } + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [self enumerateAttemptingOutAttachmentsWithBlock:^(TSAttachmentPointer *attachment) { + // sanity check + if (attachment.state != TSAttachmentPointerStateFailed) { + attachment.state = TSAttachmentPointerStateFailed; + [attachment saveWithTransaction:transaction]; + count++; } - transaction:transaction]; - }]; + } + transaction:transaction]; + } error:nil]; OWSLogDebug(@"Marked %u attachments as unsent", count); } diff --git a/SignalServiceKit/src/Messages/OWSFailedMessagesJob.m b/SignalServiceKit/src/Messages/OWSFailedMessagesJob.m index f4cdb066b..678f0c93b 100644 --- a/SignalServiceKit/src/Messages/OWSFailedMessagesJob.m +++ b/SignalServiceKit/src/Messages/OWSFailedMessagesJob.m @@ -79,24 +79,23 @@ static NSString *const OWSFailedMessagesJobMessageStateIndex = @"index_outoing_m { __block uint count = 0; - [[self.primaryStorage newDatabaseConnection] - readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { - [self enumerateAttemptingOutMessagesWithBlock:^(TSOutgoingMessage *message) { - // sanity check - OWSAssertDebug(message.messageState == TSOutgoingMessageStateSending); - if (message.messageState != TSOutgoingMessageStateSending) { - OWSLogError(@"Refusing to mark as unsent message with state: %d", (int)message.messageState); - return; - } - - OWSLogDebug(@"marking message as unsent: %@", message.uniqueId); - [message updateWithAllSendingRecipientsMarkedAsFailedWithTansaction:transaction]; - OWSAssertDebug(message.messageState == TSOutgoingMessageStateFailed); - - count++; + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [self enumerateAttemptingOutMessagesWithBlock:^(TSOutgoingMessage *message) { + // sanity check + OWSAssertDebug(message.messageState == TSOutgoingMessageStateSending); + if (message.messageState != TSOutgoingMessageStateSending) { + OWSLogError(@"Refusing to mark as unsent message with state: %d", (int)message.messageState); + return; } - transaction:transaction]; - }]; + + OWSLogDebug(@"marking message as unsent: %@", message.uniqueId); + [message updateWithAllSendingRecipientsMarkedAsFailedWithTansaction:transaction]; + OWSAssertDebug(message.messageState == TSOutgoingMessageStateFailed); + + count++; + } + transaction:transaction]; + } error:nil]; OWSLogDebug(@"Marked %u messages as unsent", count); } diff --git a/SignalServiceKit/src/Messages/OWSIdentityManager.m b/SignalServiceKit/src/Messages/OWSIdentityManager.m index 1341dfd8b..910f8c874 100644 --- a/SignalServiceKit/src/Messages/OWSIdentityManager.m +++ b/SignalServiceKit/src/Messages/OWSIdentityManager.m @@ -206,9 +206,9 @@ NSString *const kNSNotificationName_IdentityStateDidChange = @"kNSNotificationNa OWSAssertDebug(recipientId.length > 0); __block BOOL result; - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { result = [self saveRemoteIdentity:identityKey recipientId:recipientId protocolContext:transaction]; - }]; + } error:nil]; return result; } @@ -294,13 +294,13 @@ NSString *const kNSNotificationName_IdentityStateDidChange = @"kNSNotificationNa OWSAssertDebug(identityKey.length == kStoredIdentityKeyLength); OWSAssertDebug(recipientId.length > 0); - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { [self setVerificationState:verificationState identityKey:identityKey recipientId:recipientId isUserInitiatedChange:isUserInitiatedChange transaction:transaction]; - }]; + } error:nil]; } - (void)setVerificationState:(OWSVerificationState)verificationState @@ -663,10 +663,10 @@ NSString *const kNSNotificationName_IdentityStateDidChange = @"kNSNotificationNa OWSLogInfo(@"Successfully sent verification state sync message"); // Record that this verification state was successfully synced. - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [self clearSyncMessageForRecipientId:message.verificationForRecipientId transaction:transaction]; - }]; + } error:nil]; } failure:^(NSError *error) { OWSLogError(@"Failed to send verification state sync message with error: %@", error); @@ -678,9 +678,9 @@ NSString *const kNSNotificationName_IdentityStateDidChange = @"kNSNotificationNa OWSLogInfo(@"Removing retries for syncing verification state, since user is no longer registered: %@", message.verificationForRecipientId); // Otherwise this will fail forever. - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [self clearSyncMessageForRecipientId:message.verificationForRecipientId transaction:transaction]; - }]; + } error:nil]; } }]; } diff --git a/SignalServiceKit/src/Messages/OWSIncompleteCallsJob.m b/SignalServiceKit/src/Messages/OWSIncompleteCallsJob.m index 7fbde2a85..855076044 100644 --- a/SignalServiceKit/src/Messages/OWSIncompleteCallsJob.m +++ b/SignalServiceKit/src/Messages/OWSIncompleteCallsJob.m @@ -83,7 +83,7 @@ static NSString *const OWSIncompleteCallsJobCallTypeIndex = @"index_calls_on_cal OWSAssertDebug(CurrentAppContext().appLaunchTime); uint64_t cutoffTimestamp = [NSDate ows_millisecondsSince1970ForDate:CurrentAppContext().appLaunchTime]; - [[self.primaryStorage newDatabaseConnection] readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [self enumerateIncompleteCallsWithBlock:^(TSCall *call) { if (call.timestamp <= cutoffTimestamp) { @@ -106,7 +106,7 @@ static NSString *const OWSIncompleteCallsJobCallTypeIndex = @"index_calls_on_cal count++; } transaction:transaction]; - }]; + } error:nil]; OWSLogInfo(@"Marked %u calls as missed", count); } diff --git a/SignalServiceKit/src/Messages/OWSMessageDecrypter.m b/SignalServiceKit/src/Messages/OWSMessageDecrypter.m index cbf8f3024..0ba7046a7 100644 --- a/SignalServiceKit/src/Messages/OWSMessageDecrypter.m +++ b/SignalServiceKit/src/Messages/OWSMessageDecrypter.m @@ -216,7 +216,7 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes switch (envelope.type) { case SSKProtoEnvelopeTypeFriendRequest: { - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [self decryptFriendRequestMessage:envelope envelopeData:envelopeData successBlock:^(OWSMessageDecryptResult *result) { @@ -229,7 +229,7 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes error); failureBlock(); }]; - }]; + } error:nil]; // Return to avoid double-acknowledging return; } @@ -271,7 +271,7 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes case SSKProtoEnvelopeTypeReceipt: case SSKProtoEnvelopeTypeKeyExchange: case SSKProtoEnvelopeTypeUnknown: { - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { OWSMessageDecryptResult *result = [OWSMessageDecryptResult resultWithEnvelopeData:envelopeData plaintextData:nil @@ -279,7 +279,7 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes sourceDevice:envelope.sourceDevice isUDMessage:NO]; successBlock(result, transaction); - }]; + } error:nil]; // Return to avoid double-acknowledging. return; } @@ -307,12 +307,11 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes OWSFailDebug(@"Received an invalid envelope: %@.", exception.debugDescription); OWSProdFail([OWSAnalyticsEvents messageManagerErrorInvalidProtocolMessage]); - [[self.primaryStorage newDatabaseConnection] - readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - TSErrorMessage *errorMessage = [TSErrorMessage corruptedMessageInUnknownThread]; - [SSKEnvironment.shared.notificationsManager notifyUserForThreadlessErrorMessage:errorMessage - transaction:transaction]; - }]; + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + TSErrorMessage *errorMessage = [TSErrorMessage corruptedMessageInUnknownThread]; + [SSKEnvironment.shared.notificationsManager notifyUserForThreadlessErrorMessage:errorMessage + transaction:transaction]; + } error:nil]; } failureBlock(); @@ -422,43 +421,42 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes return failureBlock(error); } - [self.dbConnection - asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - @try { - id cipherMessage = cipherMessageBlock(encryptedData); - LKSessionCipher *cipher = [[LKSessionCipher alloc] - initWithSessionResetImplementation:self.sessionResetImplementation - sessionStore:self.primaryStorage - preKeyStore:self.primaryStorage - signedPreKeyStore:self.primaryStorage - identityKeyStore:self.identityManager - recipientID:recipientId - deviceID:deviceId]; + [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + @try { + id cipherMessage = cipherMessageBlock(encryptedData); + LKSessionCipher *cipher = [[LKSessionCipher alloc] + initWithSessionResetImplementation:self.sessionResetImplementation + sessionStore:self.primaryStorage + preKeyStore:self.primaryStorage + signedPreKeyStore:self.primaryStorage + identityKeyStore:self.identityManager + recipientID:recipientId + deviceID:deviceId]; - // plaintextData may be nil for some envelope types. - NSError *error = nil; - NSData *_Nullable decryptedData = [cipher decrypt:cipherMessage protocolContext:transaction error:&error]; - // Throw if we got an error - SCKRaiseIfExceptionWrapperError(error); - NSData *_Nullable plaintextData = decryptedData != nil ? [decryptedData removePadding] : nil; - - OWSMessageDecryptResult *result = [OWSMessageDecryptResult resultWithEnvelopeData:envelopeData - plaintextData:plaintextData - source:envelope.source - sourceDevice:envelope.sourceDevice - isUDMessage:NO]; - successBlock(result, transaction); - } @catch (NSException *exception) { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - [self processException:exception envelope:envelope]; - NSString *errorDescription = [NSString - stringWithFormat:@"Exception while decrypting %@: %@.", cipherTypeName, exception.description]; - OWSLogError(@"%@", errorDescription); - NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeFailedToDecryptMessage, errorDescription); - failureBlock(error); - }); - } - }]; + // plaintextData may be nil for some envelope types. + NSError *error = nil; + NSData *_Nullable decryptedData = [cipher decrypt:cipherMessage protocolContext:transaction error:&error]; + // Throw if we got an error + SCKRaiseIfExceptionWrapperError(error); + NSData *_Nullable plaintextData = decryptedData != nil ? [decryptedData removePadding] : nil; + + OWSMessageDecryptResult *result = [OWSMessageDecryptResult resultWithEnvelopeData:envelopeData + plaintextData:plaintextData + source:envelope.source + sourceDevice:envelope.sourceDevice + isUDMessage:NO]; + successBlock(result, transaction); + } @catch (NSException *exception) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + [self processException:exception envelope:envelope]; + NSString *errorDescription = [NSString + stringWithFormat:@"Exception while decrypting %@: %@.", cipherTypeName, exception.description]; + OWSLogError(@"%@", errorDescription); + NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeFailedToDecryptMessage, errorDescription); + failureBlock(error); + }); + } + }]; } - (void)decryptUnidentifiedSender:(SSKProtoEnvelope *)envelope @@ -486,7 +484,7 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes NSString *localRecipientId = self.tsAccountManager.localNumber; uint32_t localDeviceId = OWSDevicePrimaryDeviceId; - [self.dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { NSError *cipherError; SMKSecretSessionCipher *_Nullable cipher = [[SMKSecretSessionCipher alloc] initWithSessionResetImplementation:self.sessionResetImplementation @@ -635,7 +633,7 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes OWSLogError( @"Got exception: %@ of type: %@ with reason: %@", exception.description, exception.name, exception.reason); - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { TSErrorMessage *errorMessage; if (envelope.source.length == 0) { @@ -676,7 +674,7 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes [LKSessionManagementProtocol handleDecryptionError:errorMessage.errorType forHexEncodedPublicKey:envelope.source using:transaction]; [self notifyUserForErrorMessage:errorMessage envelope:envelope transaction:transaction]; } - }]; + } error:nil]; } - (void)notifyUserForErrorMessage:(TSErrorMessage *)errorMessage diff --git a/SignalServiceKit/src/Messages/OWSMessageManager.m b/SignalServiceKit/src/Messages/OWSMessageManager.m index f1e81f159..119b25125 100644 --- a/SignalServiceKit/src/Messages/OWSMessageManager.m +++ b/SignalServiceKit/src/Messages/OWSMessageManager.m @@ -938,7 +938,7 @@ NS_ASSUME_NONNULL_BEGIN attachmentHandler:^(NSArray *attachmentStreams) { OWSAssertDebug(attachmentStreams.count == 1); TSAttachmentStream *attachmentStream = attachmentStreams.firstObject; - [self.dbConnection readWriteWithBlock:^( + [LKStorage writeSyncWithBlock:^( YapDatabaseReadWriteTransaction *transaction) { TSGroupThread *_Nullable groupThread = [TSGroupThread threadWithGroupId:dataMessage.group.id @@ -950,7 +950,7 @@ NS_ASSUME_NONNULL_BEGIN [groupThread updateAvatarWithAttachmentStream:attachmentStream transaction:transaction]; - }]; + } error:nil]; } transaction:transaction ]; @@ -1636,7 +1636,7 @@ NS_ASSUME_NONNULL_BEGIN // * Failures don't interfere with successes. [self.attachmentDownloads downloadAttachmentPointer:attachmentPointer success:^(NSArray *attachmentStreams) { - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { TSAttachmentStream *_Nullable attachmentStream = attachmentStreams.firstObject; OWSAssertDebug(attachmentStream); if (attachmentStream && incomingMessage.quotedMessage.thumbnailAttachmentPointerId.length > 0 && @@ -1649,7 +1649,7 @@ NS_ASSUME_NONNULL_BEGIN // since the attachment might be a contact avatar, etc. [incomingMessage touchWithTransaction:transaction]; } - }]; + } error:nil]; } failure:^(NSError *error) { OWSLogWarn(@"Failed to download attachment for message: %lu with error: %@.", diff --git a/SignalServiceKit/src/Messages/OWSMessageReceiver.m b/SignalServiceKit/src/Messages/OWSMessageReceiver.m index 553055f15..760a0abb2 100644 --- a/SignalServiceKit/src/Messages/OWSMessageReceiver.m +++ b/SignalServiceKit/src/Messages/OWSMessageReceiver.m @@ -136,17 +136,17 @@ NSString *const OWSMessageDecryptJobFinderExtensionGroup = @"OWSMessageProcessin - (void)addJobForEnvelopeData:(NSData *)envelopeData { - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { OWSMessageDecryptJob *job = [[OWSMessageDecryptJob alloc] initWithEnvelopeData:envelopeData]; [job saveWithTransaction:transaction]; - }]; + } error:nil]; } - (void)removeJobWithId:(NSString *)uniqueId { - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { [transaction removeObjectForKey:uniqueId inCollection:[OWSMessageDecryptJob collection]]; - }]; + } error:nil]; } + (YapDatabaseView *)databaseExtension @@ -375,11 +375,11 @@ NSString *const OWSMessageDecryptJobFinderExtensionGroup = @"OWSMessageProcessin if (!envelope) { OWSFailDebug(@"Couldn't parse proto."); - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { TSErrorMessage *errorMessage = [TSErrorMessage corruptedMessageInUnknownThread]; [SSKEnvironment.shared.notificationsManager notifyUserForThreadlessErrorMessage:errorMessage transaction:transaction]; - }]; + } error:nil]; dispatch_async(self.serialQueue, ^{ completion(NO); diff --git a/SignalServiceKit/src/Messages/OWSMessageSender.m b/SignalServiceKit/src/Messages/OWSMessageSender.m index a97455404..95547d963 100644 --- a/SignalServiceKit/src/Messages/OWSMessageSender.m +++ b/SignalServiceKit/src/Messages/OWSMessageSender.m @@ -366,11 +366,11 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; } if ([LKFriendRequestProtocol shouldUpdateFriendRequestStatusFromMessage:message]) { - [self.primaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { // Loki: Optimistically update friend request status when we can. This is used for // e.g. preventing AFRs from being sent twice on a contact sync. [LKFriendRequestProtocol setFriendRequestStatusToSendingIfNeededForHexEncodedPublicKey:message.thread.contactIdentifier transaction:transaction]; - }]; + } error:nil]; } dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ @@ -388,10 +388,10 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; // // So we're using YDB behavior to ensure this invariant, which is a bit // unorthodox. - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [allAttachmentIds addObjectsFromArray:[OutgoingMessagePreparer prepareMessageForSending:message transaction:transaction]]; - }]; + } error:nil]; NSOperationQueue *sendingQueue = [self sendingQueueForMessage:message]; OWSSendMessageOperation *sendMessageOperation = @@ -610,11 +610,9 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; }]; if ([LKMultiDeviceProtocol isMultiDeviceRequiredForMessage:message]) { // Avoid the write transaction if possible - dispatch_async(dispatch_get_main_queue(), ^{ - [self.primaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - [LKMultiDeviceProtocol sendMessageToDestinationAndLinkedDevices:messageSend in:transaction]; - }]; - }); + [self.primaryStorage.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { + [LKMultiDeviceProtocol sendMessageToDestinationAndLinkedDevices:messageSend in:transaction]; + }]; } else { [self sendMessage:messageSend]; } @@ -717,12 +715,12 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; NSMutableSet *obsoleteRecipientIds = [NSMutableSet setWithArray:message.sendingRecipientIds]; [obsoleteRecipientIds minusSet:[NSSet setWithArray:recipientIds]]; if (obsoleteRecipientIds.count > 0) { - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { for (NSString *recipientId in obsoleteRecipientIds) { // Mark this recipient as "skipped". [message updateWithSkippedRecipient:recipientId transaction:transaction]; } - }]; + } error:nil]; } if (recipientIds.count < 1) { @@ -806,7 +804,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; message:(TSOutgoingMessage *)message thread:(TSThread *)thread { - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { if (thread.isGroupThread) { // Mark as "skipped" group members who no longer have signal accounts. [message updateWithSkippedRecipient:recipient.recipientId transaction:transaction]; @@ -824,7 +822,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; // TODO: Should we deleteAllSessionsForContact here? // If so, we'll need to avoid doing a prekey fetch every // time we try to send a message to an unregistered user. - }]; + } error:nil]; } - (nullable NSArray *)deviceMessagesForMessageSend:(OWSMessageSend *)messageSend @@ -1053,9 +1051,9 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; dispatch_async([OWSDispatch sendingQueue], ^{ // This emulates the completion logic of an actual successful send (see below). - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [message updateWithSkippedRecipient:messageSend.localNumber transaction:transaction]; - }]; + } error:nil]; messageSend.success(); }); @@ -1170,10 +1168,10 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; message.actualSenderHexEncodedPublicKey = userHexEncodedPublicKey; [[LKPublicChatAPI sendMessage:groupMessage toGroup:publicChat.channel onServer:publicChat.server] .thenOn(OWSDispatch.sendingQueue, ^(LKGroupMessage *groupMessage) { - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [message saveOpenGroupServerMessageID:groupMessage.serverID in:transaction]; [self.primaryStorage setIDForMessageWithServerID:groupMessage.serverID to:message.uniqueId in:transaction]; - }]; + } error:nil]; [self messageSendDidSucceed:messageSend deviceMessages:deviceMessages wasSentByUD:messageSend.isUDSend wasSentByWebsocket:false]; }) .catchOn(OWSDispatch.sendingQueue, ^(NSError *error) { @@ -1204,7 +1202,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; BOOL isPing = ((NSNumber *)signalMessageInfo[@"isPing"]).boolValue; LKSignalMessage *signalMessage = [[LKSignalMessage alloc] initWithType:type timestamp:timestamp senderID:senderID senderDeviceID:senderDeviceID content:content recipientID:recipientID ttl:ttl isPing:isPing]; BOOL shouldUpdateFriendRequestStatus = [LKFriendRequestProtocol shouldUpdateFriendRequestStatusFromMessage:message]; - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { if (!message.skipSave) { // Update the PoW calculation status [message saveIsCalculatingProofOfWork:YES withTransaction:transaction]; @@ -1212,11 +1210,11 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; if (shouldUpdateFriendRequestStatus) { [LKFriendRequestProtocol setFriendRequestStatusToSendingIfNeededForHexEncodedPublicKey:recipientID transaction:transaction]; } - }]; + } error:nil]; // Convenience void (^onP2PSuccess)() = ^() { message.isP2P = YES; }; void (^handleError)(NSError *error) = ^(NSError *error) { - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { if (!message.skipSave) { // Update the PoW calculation status [message saveIsCalculatingProofOfWork:NO withTransaction:transaction]; @@ -1224,7 +1222,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; if (shouldUpdateFriendRequestStatus) { [LKFriendRequestProtocol setFriendRequestStatusToFailedIfNeededForHexEncodedPublicKey:recipientID transaction:transaction]; } - }]; + } error:nil]; // Handle the error failedMessageSend(error); }; @@ -1242,7 +1240,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; [NSNotificationCenter.defaultCenter postNotificationName:NSNotification.messageSent object:[[NSNumber alloc] initWithUnsignedLongLong:signalMessage.timestamp]]; isSuccess = YES; if (shouldUpdateFriendRequestStatus) { - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { if (!message.skipSave) { // Update the message NSTimeInterval expirationInterval = 72 * kHourInterval; @@ -1250,7 +1248,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; [message saveFriendRequestExpiresAt:[NSDate ows_millisecondsSince1970ForDate:expirationDate] withTransaction:transaction]; } [LKFriendRequestProtocol setFriendRequestStatusToSentIfNeededForHexEncodedPublicKey:recipientID transaction:transaction]; - }]; + } error:nil]; } // Invoke the completion handler [self messageSendDidSucceed:messageSend deviceMessages:deviceMessages wasSentByUD:messageSend.isUDSend wasSentByWebsocket:false]; @@ -1295,7 +1293,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; } dispatch_async([OWSDispatch sendingQueue], ^{ - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [messageSend.message updateWithSentRecipient:messageSend.recipient.uniqueId wasSentByUD:wasSentByUD transaction:transaction]; @@ -1303,7 +1301,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; // If we've just delivered a message to a user, we know they // have a valid Signal account. [SignalRecipient markRecipientAsRegisteredAndGet:recipient.recipientId transaction:transaction]; - }]; + } error:nil]; messageSend.success(); }); @@ -1465,29 +1463,28 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; } } - [self.dbConnection - readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - if (extraDevices.count < 1 && missingDevices.count < 1) { - OWSProdFail([OWSAnalyticsEvents messageSenderErrorNoMissingOrExtraDevices]); + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + if (extraDevices.count < 1 && missingDevices.count < 1) { + OWSProdFail([OWSAnalyticsEvents messageSenderErrorNoMissingOrExtraDevices]); + } + + [recipient updateRegisteredRecipientWithDevicesToAdd:missingDevices + devicesToRemove:extraDevices + transaction:transaction]; + + if (extraDevices && extraDevices.count > 0) { + OWSLogInfo(@"Deleting sessions for extra devices: %@", extraDevices); + for (NSNumber *extraDeviceId in extraDevices) { + [self.primaryStorage deleteSessionForContact:recipient.uniqueId + deviceId:extraDeviceId.intValue + protocolContext:transaction]; } + } - [recipient updateRegisteredRecipientWithDevicesToAdd:missingDevices - devicesToRemove:extraDevices - transaction:transaction]; - - if (extraDevices && extraDevices.count > 0) { - OWSLogInfo(@"Deleting sessions for extra devices: %@", extraDevices); - for (NSNumber *extraDeviceId in extraDevices) { - [self.primaryStorage deleteSessionForContact:recipient.uniqueId - deviceId:extraDeviceId.intValue - protocolContext:transaction]; - } - } - - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - completionHandler(); - }); - }]; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + completionHandler(); + }); + } error:nil]; } - (void)handleMessageSentLocally:(TSOutgoingMessage *)message @@ -1499,21 +1496,21 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; // Loki: Take into account multi device BOOL isNoteToSelf = [LKSessionMetaProtocol isThreadNoteToSelf:message.thread]; if (isNoteToSelf && !([message isKindOfClass:LKDeviceLinkMessage.class])) { - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { for (NSString *recipientId in message.sendingRecipientIds) { [message updateWithReadRecipientId:recipientId readTimestamp:message.timestamp transaction:transaction]; } - }]; + } error:nil]; } successParam(); }; - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [[OWSDisappearingMessagesJob sharedJob] startAnyExpirationForMessage:message expirationStartedAt:[NSDate ows_millisecondTimeStamp] transaction:transaction]; - }]; + } error:nil]; if (!message.shouldSyncTranscript) { return success(); @@ -1529,9 +1526,9 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; sendSyncTranscriptForMessage:message isRecipientUpdate:isRecipientUpdate success:^{ - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [message updateWithHasSyncedTranscript:YES transaction:transaction]; - }]; + } error:nil]; success(); } @@ -1563,9 +1560,9 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; NSString *recipientId = otherDevice ?: currentDevice; __block SignalRecipient *recipient; - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { recipient = [SignalRecipient markRecipientAsRegisteredAndGet:recipientId transaction:transaction]; - }]; + } error:nil]; SMKSenderCertificate *senderCertificate = [self.udManager getSenderCertificate]; OWSUDAccess *recipientUDAccess = nil; @@ -1636,17 +1633,16 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; __block NSDictionary *_Nullable messageDict; __block NSException *encryptionException; - [self.dbConnection - readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - @try { - messageDict = [self throws_encryptedMessageForMessageSend:messageSend - recipientID:recipientID - plainText:plainText - transaction:transaction]; - } @catch (NSException *exception) { - encryptionException = exception; - } - }]; + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + @try { + messageDict = [self throws_encryptedMessageForMessageSend:messageSend + recipientID:recipientID + plainText:plainText + transaction:transaction]; + } @catch (NSException *exception) { + encryptionException = exception; + } + } error:nil]; if (encryptionException) { OWSLogInfo(@"Exception during encryption: %@.", encryptionException); @@ -1660,11 +1656,11 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; } } @catch (NSException *exception) { if ([exception.name isEqualToString:OWSMessageSenderInvalidDeviceException]) { - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [recipient updateRegisteredRecipientWithDevicesToAdd:nil devicesToRemove:@[ @(OWSDevicePrimaryDeviceId) ] transaction:transaction]; - }]; + } error:nil]; } else { @throw exception; } @@ -1684,9 +1680,9 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; OWSAssertDebug(recipientID.length > 0); __block BOOL hasSession; - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { hasSession = [storage containsSession:recipientID deviceId:[deviceId intValue] protocolContext:transaction]; - }]; + } error:nil]; if (hasSession) { return YES; } @@ -1747,7 +1743,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; identityKeyStore:self.identityManager recipientId:recipientID deviceId:[deviceId intValue]]; - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { @try { [builder throws_processPrekeyBundle:bundle protocolContext:transaction]; @@ -1756,7 +1752,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; } @catch (NSException *caughtException) { exception = caughtException; } - }]; + } error:nil]; if (exception) { if ([exception.name isEqualToString:UntrustedIdentityKeyException]) { OWSRaiseExceptionWithUserInfo(UntrustedIdentityKeyException, @@ -2009,7 +2005,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; return; } - [self.dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { for (NSUInteger i = 0; i < [devices count]; i++) { int deviceNumber = [devices[i] intValue]; [[OWSPrimaryStorage sharedManager] deleteSessionForContact:identifier @@ -2115,7 +2111,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; [attachmentStreams addObject:attachmentStream]; } - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { for (TSAttachmentStream *attachmentStream in attachmentStreams) { [outgoingMessage.attachmentIds addObject:attachmentStream.uniqueId]; if (attachmentStream.sourceFilename) { @@ -2126,7 +2122,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; for (TSAttachmentStream *attachmentStream in attachmentStreams) { [attachmentStream saveWithTransaction:transaction]; } - }]; + } error:nil]; completionHandler(nil); }); diff --git a/SignalServiceKit/src/Messages/OWSOutgoingReceiptManager.m b/SignalServiceKit/src/Messages/OWSOutgoingReceiptManager.m index e7a61a1d0..e97341350 100644 --- a/SignalServiceKit/src/Messages/OWSOutgoingReceiptManager.m +++ b/SignalServiceKit/src/Messages/OWSOutgoingReceiptManager.m @@ -249,14 +249,14 @@ NSString *const kOutgoingReadReceiptManagerCollection = @"kOutgoingReadReceiptMa return; } dispatch_async(self.serialQueue, ^{ - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { NSSet *_Nullable oldTimestamps = [transaction objectForKey:recipientId inCollection:collection]; NSMutableSet *newTimestamps = (oldTimestamps ? [oldTimestamps mutableCopy] : [NSMutableSet new]); [newTimestamps addObject:@(timestamp)]; [transaction setObject:newTimestamps forKey:recipientId inCollection:collection]; - }]; + } error:nil]; [self process]; }); @@ -276,7 +276,7 @@ NSString *const kOutgoingReadReceiptManagerCollection = @"kOutgoingReadReceiptMa return; } dispatch_async(self.serialQueue, ^{ - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { NSSet *_Nullable oldTimestamps = [transaction objectForKey:recipientId inCollection:collection]; NSMutableSet *newTimestamps = (oldTimestamps ? [oldTimestamps mutableCopy] : [NSMutableSet new]); @@ -287,7 +287,7 @@ NSString *const kOutgoingReadReceiptManagerCollection = @"kOutgoingReadReceiptMa } else { [transaction removeObjectForKey:recipientId inCollection:collection]; } - }]; + } error:nil]; }); } diff --git a/SignalServiceKit/src/Messages/OWSReadReceiptManager.m b/SignalServiceKit/src/Messages/OWSReadReceiptManager.m index b38c0c005..2970a25fc 100644 --- a/SignalServiceKit/src/Messages/OWSReadReceiptManager.m +++ b/SignalServiceKit/src/Messages/OWSReadReceiptManager.m @@ -217,9 +217,9 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE OWSReadReceiptsForLinkedDevicesMessage *message = [[OWSReadReceiptsForLinkedDevicesMessage alloc] initWithReadReceipts:readReceiptsForLinkedDevices]; - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { [self.messageSenderJobQueue addMessage:message transaction:transaction]; - }]; + } error:nil]; } BOOL didWork = readReceiptsForLinkedDevices.count > 0; @@ -250,13 +250,13 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE OWSAssertDebug(thread); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [self markAsReadBeforeSortId:sortId thread:thread readTimestamp:[NSDate ows_millisecondTimeStamp] wasLocal:YES transaction:transaction]; - }]; + } error:nil]; }); } @@ -315,7 +315,7 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE } dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { for (NSNumber *nsSentTimestamp in sentTimestamps) { UInt64 sentTimestamp = [nsSentTimestamp unsignedLongLongValue]; @@ -343,7 +343,7 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE transaction:transaction]; } } - }]; + } error:nil]; }); } diff --git a/SignalServiceKit/src/Messages/TSCall.m b/SignalServiceKit/src/Messages/TSCall.m index f6c2cba18..e7e0118cb 100644 --- a/SignalServiceKit/src/Messages/TSCall.m +++ b/SignalServiceKit/src/Messages/TSCall.m @@ -6,6 +6,7 @@ #import "TSContactThread.h" #import #import +#import NS_ASSUME_NONNULL_BEGIN @@ -152,9 +153,9 @@ NSUInteger TSCallCurrentSchemaVersion = 1; - (void)updateCallType:(RPRecentCallType)callType { - [self.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [self updateCallType:callType transaction:transaction]; - }]; + } error:nil]; } - (void)updateCallType:(RPRecentCallType)callType transaction:(YapDatabaseReadWriteTransaction *)transaction diff --git a/SignalServiceKit/src/Network/WebSockets/OWSWebSocket.m b/SignalServiceKit/src/Network/WebSockets/OWSWebSocket.m index 1c2fe8be5..7c1ee95ed 100644 --- a/SignalServiceKit/src/Network/WebSockets/OWSWebSocket.m +++ b/SignalServiceKit/src/Network/WebSockets/OWSWebSocket.m @@ -795,12 +795,11 @@ NSString *const kNSNotification_OWSWebSocketStateDidChange = @"kNSNotification_O } if (!success) { - [[self.primaryStorage newDatabaseConnection] - readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - TSErrorMessage *errorMessage = [TSErrorMessage corruptedMessageInUnknownThread]; - [self.notificationsManager notifyUserForThreadlessErrorMessage:errorMessage - transaction:transaction]; - }]; + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + TSErrorMessage *errorMessage = [TSErrorMessage corruptedMessageInUnknownThread]; + [self.notificationsManager notifyUserForThreadlessErrorMessage:errorMessage + transaction:transaction]; + } error:nil]; } dispatch_async(dispatch_get_main_queue(), ^{ diff --git a/SignalServiceKit/src/Security/OWSRecipientIdentity.m b/SignalServiceKit/src/Security/OWSRecipientIdentity.m index 5ac081722..a1ed4bed7 100644 --- a/SignalServiceKit/src/Security/OWSRecipientIdentity.m +++ b/SignalServiceKit/src/Security/OWSRecipientIdentity.m @@ -149,7 +149,7 @@ SSKProtoVerified *_Nullable BuildVerifiedProtoWithRecipientId(NSString *destinat { changeBlock(self); - [[self class].dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { OWSRecipientIdentity *latest = [[self class] fetchObjectWithUniqueID:self.uniqueId transaction:transaction]; if (latest == nil) { [self saveWithTransaction:transaction]; @@ -158,7 +158,7 @@ SSKProtoVerified *_Nullable BuildVerifiedProtoWithRecipientId(NSString *destinat changeBlock(latest); [latest saveWithTransaction:transaction]; - }]; + } error:nil]; } #pragma mark - debug diff --git a/SignalServiceKit/src/Storage/OWSPrimaryStorage.m b/SignalServiceKit/src/Storage/OWSPrimaryStorage.m index 8f7d42a73..c681cb926 100644 --- a/SignalServiceKit/src/Storage/OWSPrimaryStorage.m +++ b/SignalServiceKit/src/Storage/OWSPrimaryStorage.m @@ -452,7 +452,7 @@ void VerifyRegistrationsForPrimaryStorage(OWSStorage *storage) // made in another process (e.g. the SAE) from showing up in other processes. // There's a simple workaround: a trivial write to the database flushes changes // made from other processes. - [self.dbReadWriteConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [transaction setObject:[NSUUID UUID].UUIDString forKey:@"conversation_view_noop_mod" inCollection:@"temp"]; }]; } diff --git a/SignalServiceKit/src/Storage/TSYapDatabaseObject.m b/SignalServiceKit/src/Storage/TSYapDatabaseObject.m index 9d7d300b2..897818e1f 100644 --- a/SignalServiceKit/src/Storage/TSYapDatabaseObject.m +++ b/SignalServiceKit/src/Storage/TSYapDatabaseObject.m @@ -45,13 +45,14 @@ NS_ASSUME_NONNULL_BEGIN - (void)save { - [[self dbReadWriteConnection] readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [self saveWithTransaction:transaction]; - }]; + } error:nil]; } - (void)saveAsyncWithCompletionBlock:(void (^_Nullable)(void))completionBlock { + // TODO: <-------- [[self dbReadWriteConnection] asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { [self saveWithTransaction:transaction]; } @@ -65,9 +66,9 @@ NS_ASSUME_NONNULL_BEGIN - (void)touch { - [[self dbReadWriteConnection] readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [self touchWithTransaction:transaction]; - }]; + } error:nil]; } - (void)removeWithTransaction:(YapDatabaseReadWriteTransaction *)transaction @@ -77,9 +78,9 @@ NS_ASSUME_NONNULL_BEGIN - (void)remove { - [[self dbReadWriteConnection] readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [self removeWithTransaction:transaction]; - }]; + } error:nil]; } - (YapDatabaseConnection *)dbReadConnection @@ -181,9 +182,9 @@ NS_ASSUME_NONNULL_BEGIN + (void)removeAllObjectsInCollection { - [[self dbReadWriteConnection] readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [transaction removeAllObjectsInCollection:[self collection]]; - }]; + } error:nil]; } + (nullable instancetype)fetchObjectWithUniqueID:(NSString *)uniqueID diff --git a/SignalServiceKit/src/Util/OWSAnalytics.m b/SignalServiceKit/src/Util/OWSAnalytics.m index 29a300bdc..ac70dc735 100755 --- a/SignalServiceKit/src/Util/OWSAnalytics.m +++ b/SignalServiceKit/src/Util/OWSAnalytics.m @@ -187,10 +187,10 @@ NSString *NSStringForOWSAnalyticsSeverity(OWSAnalyticsSeverity severity) dispatch_async(self.serialQueue, ^{ self.hasRequestInFlight = NO; - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { // Remove from queue. [transaction removeObjectForKey:eventKey inCollection:kOWSAnalytics_EventsCollection]; - }]; + } error:nil]; // Wait a second between network requests / retries. dispatch_after( @@ -323,7 +323,7 @@ NSString *NSStringForOWSAnalyticsSeverity(OWSAnalyticsSeverity severity) [self sendEvent:eventDictionary eventKey:eventKey isCritical:YES]; } else { // Add to queue. - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { const int kMaxQueuedEvents = 5000; if ([transaction numberOfKeysInCollection:kOWSAnalytics_EventsCollection] > kMaxQueuedEvents) { OWSLogError(@"Event queue overflow."); @@ -331,7 +331,7 @@ NSString *NSStringForOWSAnalyticsSeverity(OWSAnalyticsSeverity severity) } [transaction setObject:eventDictionary forKey:eventKey inCollection:kOWSAnalytics_EventsCollection]; - }]; + } error:nil]; [self tryToSyncEvents]; } From 4105f17c028c35dcb5a771e6664bf3f13c756b8b Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Thu, 11 Jun 2020 14:19:04 +1000 Subject: [PATCH 12/19] Fix build --- Signal/src/util/OWSOrphanDataCleaner.m | 1 + .../SharingThreadPickerViewController.m | 33 +++++++-------- .../migrations/OWSDatabaseMigration.m | 14 +++---- .../OWSResaveCollectionDBMigration.m | 31 +++++++------- SignalMessaging/profiles/OWSProfileManager.m | 41 ++++++++++--------- SignalMessaging/utils/ThreadUtil.m | 38 ++++++++--------- .../src/Loki/Database/Storage.swift | 22 +++++++--- .../src/Messages/OWSDisappearingMessagesJob.m | 1 + .../OWSFailedAttachmentDownloadsJob.m | 1 + .../src/Messages/OWSFailedMessagesJob.m | 1 + .../src/Messages/OWSIncompleteCallsJob.m | 1 + .../src/Storage/TSYapDatabaseObject.m | 7 ++-- SignalServiceKit/src/Util/OWSAnalytics.m | 1 + 13 files changed, 101 insertions(+), 91 deletions(-) diff --git a/Signal/src/util/OWSOrphanDataCleaner.m b/Signal/src/util/OWSOrphanDataCleaner.m index b89ad9499..afcf8069d 100644 --- a/Signal/src/util/OWSOrphanDataCleaner.m +++ b/Signal/src/util/OWSOrphanDataCleaner.m @@ -18,6 +18,7 @@ #import #import #import +#import #import NS_ASSUME_NONNULL_BEGIN diff --git a/SignalMessaging/ViewControllers/SharingThreadPickerViewController.m b/SignalMessaging/ViewControllers/SharingThreadPickerViewController.m index ec484e7d6..32c0a00bb 100644 --- a/SignalMessaging/ViewControllers/SharingThreadPickerViewController.m +++ b/SignalMessaging/ViewControllers/SharingThreadPickerViewController.m @@ -376,25 +376,22 @@ typedef void (^SendMessageBlock)(SendCompletionBlock completion); // TODO - in line with QuotedReply and other message attachments, saving should happen as part of sending // preparation rather than duplicated here and in the SAE - // TODO: <-------- - - [self.dbReadWriteConnection - asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { - if (contactShare.avatarImage) { - [contactShare.dbRecord saveAvatarImage:contactShare.avatarImage transaction:transaction]; - } + [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + if (contactShare.avatarImage) { + [contactShare.dbRecord saveAvatarImage:contactShare.avatarImage transaction:transaction]; } - completionBlock:^{ - __block TSOutgoingMessage *outgoingMessage = nil; - outgoingMessage = [ThreadUtil sendMessageNonDurablyWithContactShare:contactShare.dbRecord - inThread:self.thread - messageSender:self.messageSender - completion:^(NSError *_Nullable error) { - sendCompletion(error, outgoingMessage); - }]; - // This is necessary to show progress. - self.outgoingMessage = outgoingMessage; - }]; + } + completion:^{ + __block TSOutgoingMessage *outgoingMessage = nil; + outgoingMessage = [ThreadUtil sendMessageNonDurablyWithContactShare:contactShare.dbRecord + inThread:self.thread + messageSender:self.messageSender + completion:^(NSError *_Nullable error) { + sendCompletion(error, outgoingMessage); + }]; + // This is necessary to show progress. + self.outgoingMessage = outgoingMessage; + }]; } diff --git a/SignalMessaging/environment/migrations/OWSDatabaseMigration.m b/SignalMessaging/environment/migrations/OWSDatabaseMigration.m index 27dcb3f15..04997bda7 100644 --- a/SignalMessaging/environment/migrations/OWSDatabaseMigration.m +++ b/SignalMessaging/environment/migrations/OWSDatabaseMigration.m @@ -72,14 +72,14 @@ NS_ASSUME_NONNULL_BEGIN OWSDatabaseConnection *dbConnection = (OWSDatabaseConnection *)self.primaryStorage.newDatabaseConnection; [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { - [self runUpWithTransaction:transaction]; - } - completionBlock:^{ - OWSLogInfo(@"Completed migration %@", self.uniqueId); - [self save]; + [self runUpWithTransaction:transaction]; + } + completion:^{ + OWSLogInfo(@"Completed migration %@", self.uniqueId); + [self save]; - completion(); - }]; + completion(); + }]; } #pragma mark - Database Connections diff --git a/SignalMessaging/environment/migrations/OWSResaveCollectionDBMigration.m b/SignalMessaging/environment/migrations/OWSResaveCollectionDBMigration.m index 796b68f35..ee0db59d3 100644 --- a/SignalMessaging/environment/migrations/OWSResaveCollectionDBMigration.m +++ b/SignalMessaging/environment/migrations/OWSResaveCollectionDBMigration.m @@ -25,14 +25,13 @@ NS_ASSUME_NONNULL_BEGIN [recordIds addObjectsFromArray:[transaction allKeysInCollection:collection]]; OWSLogInfo(@"Migrating %lu records from: %@.", (unsigned long)recordIds.count, collection); } - completionQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) - completionBlock:^{ - [self resaveBatch:recordIds - collection:collection - filter:filter - dbConnection:dbConnection - completion:completion]; - }]; + completion:^{ + [self resaveBatch:recordIds + collection:collection + filter:filter + dbConnection:dbConnection + completion:completion]; + }]; } - (void)resaveBatch:(NSMutableArray *)recordIds @@ -66,14 +65,14 @@ NS_ASSUME_NONNULL_BEGIN [entity saveWithTransaction:transaction]; } } - completionBlock:^{ - // Process the next batch. - [self resaveBatch:recordIds - collection:collection - filter:filter - dbConnection:dbConnection - completion:completion]; - }]; + completion:^{ + // Process the next batch. + [self resaveBatch:recordIds + collection:collection + filter:filter + dbConnection:dbConnection + completion:completion]; + }]; } @end diff --git a/SignalMessaging/profiles/OWSProfileManager.m b/SignalMessaging/profiles/OWSProfileManager.m index 6351c3ea7..d473b0ef2 100644 --- a/SignalMessaging/profiles/OWSProfileManager.m +++ b/SignalMessaging/profiles/OWSProfileManager.m @@ -31,6 +31,7 @@ #import #import #import +#import NS_ASSUME_NONNULL_BEGIN @@ -813,16 +814,16 @@ typedef void (^ProfileManagerFailureBlock)(NSError *error); [newRecipientIds addObject:recipientId]; } } - completionBlock:^{ - for (NSString *recipientId in newRecipientIds) { - [[NSNotificationCenter defaultCenter] - postNotificationNameAsync:kNSNotificationName_ProfileWhitelistDidChange - object:nil - userInfo:@{ - kNSNotificationKey_ProfileRecipientId : recipientId, - }]; - } - }]; + completion:^{ + for (NSString *recipientId in newRecipientIds) { + [[NSNotificationCenter defaultCenter] + postNotificationNameAsync:kNSNotificationName_ProfileWhitelistDidChange + object:nil + userInfo:@{ + kNSNotificationKey_ProfileRecipientId : recipientId, + }]; + } + }]; } - (BOOL)isUserInProfileWhitelist:(NSString *)recipientId @@ -859,16 +860,16 @@ typedef void (^ProfileManagerFailureBlock)(NSError *error); didChange = YES; } } - completionBlock:^{ - if (didChange) { - [[NSNotificationCenter defaultCenter] - postNotificationNameAsync:kNSNotificationName_ProfileWhitelistDidChange - object:nil - userInfo:@{ - kNSNotificationKey_ProfileGroupId : groupId, - }]; - } - }]; + completion:^{ + if (didChange) { + [[NSNotificationCenter defaultCenter] + postNotificationNameAsync:kNSNotificationName_ProfileWhitelistDidChange + object:nil + userInfo:@{ + kNSNotificationKey_ProfileGroupId : groupId, + }]; + } + }]; } - (void)addThreadToProfileWhitelist:(TSThread *)thread diff --git a/SignalMessaging/utils/ThreadUtil.m b/SignalMessaging/utils/ThreadUtil.m index ac720a1d7..6981efd44 100644 --- a/SignalMessaging/utils/ThreadUtil.m +++ b/SignalMessaging/utils/ThreadUtil.m @@ -26,6 +26,7 @@ #import #import #import +#import NS_ASSUME_NONNULL_BEGIN @@ -203,28 +204,23 @@ typedef void (^BuildOutgoingMessageCompletionBlock)(TSOutgoingMessage *savedMess block:^(void (^benchmarkCompletion)(void)) { // To avoid blocking the send flow, we dispatch an async write from within this read // transaction + [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull writeTransaction) { + [message saveWithTransaction:writeTransaction]; - // TODO: <------- - - [self.dbConnection - asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull writeTransaction) { - [message saveWithTransaction:writeTransaction]; - - OWSLinkPreview *_Nullable linkPreview = - [self linkPreviewForLinkPreviewDraft:linkPreviewDraft - transaction:writeTransaction]; - if (linkPreview) { - [message updateWithLinkPreview:linkPreview transaction:writeTransaction]; - } - - NSMutableArray *attachmentInfos = [NSMutableArray new]; - for (SignalAttachment *attachment in attachments) { - OWSOutgoingAttachmentInfo *attachmentInfo = [attachment buildOutgoingAttachmentInfoWithMessage:message]; - [attachmentInfos addObject:attachmentInfo]; - } - completionBlock(message, attachmentInfos, writeTransaction); + OWSLinkPreview *_Nullable linkPreview = + [self linkPreviewForLinkPreviewDraft:linkPreviewDraft + transaction:writeTransaction]; + if (linkPreview) { + [message updateWithLinkPreview:linkPreview transaction:writeTransaction]; } - completionBlock:benchmarkCompletion]; + + NSMutableArray *attachmentInfos = [NSMutableArray new]; + for (SignalAttachment *attachment in attachments) { + OWSOutgoingAttachmentInfo *attachmentInfo = [attachment buildOutgoingAttachmentInfoWithMessage:message]; + [attachmentInfos addObject:attachmentInfo]; + } + completionBlock(message, attachmentInfos, writeTransaction); + } completion:benchmarkCompletion]; }]; return message; @@ -721,7 +717,7 @@ typedef void (^BuildOutgoingMessageCompletionBlock)(TSOutgoingMessage *savedMess } @catch (NSException *exception) { // Do nothing } - }]; + } error:nil]; [TSAttachmentStream deleteAttachments]; } diff --git a/SignalServiceKit/src/Loki/Database/Storage.swift b/SignalServiceKit/src/Loki/Database/Storage.swift index cf6a5ad8c..6dcd71800 100644 --- a/SignalServiceKit/src/Loki/Database/Storage.swift +++ b/SignalServiceKit/src/Loki/Database/Storage.swift @@ -32,27 +32,39 @@ public final class Storage : NSObject { // • There can only be a single write transaction per database at any one time, so all write transactions must use `OWSPrimaryStorage`'s `dbReadWriteConnection`. // • Executing a write transaction from within a write transaction causes a deadlock and must be avoided. + @discardableResult @objc(writeWithBlock:) public static func objc_write(with block: @escaping (YapDatabaseReadWriteTransaction) -> Void) -> AnyPromise { return AnyPromise.from(write(with: block)) } + @discardableResult public static func write(with block: @escaping (YapDatabaseReadWriteTransaction) -> Void) -> Promise { + return write(with: block) { } + } + + @discardableResult + @objc(writeWithBlock:completion:) + public static func objc_write(with block: @escaping (YapDatabaseReadWriteTransaction) -> Void, completion: @escaping () -> Void) -> AnyPromise { + return AnyPromise.from(write(with: block, completion: completion)) + } + + @discardableResult + public static func write(with block: @escaping (YapDatabaseReadWriteTransaction) -> Void, completion: @escaping () -> Void) -> Promise { let (promise, seal) = Promise.pending() serialQueue.async { // TODO: There are cases where this isn't necessary owsStorage.dbReadWriteConnection.readWrite(block) + DispatchQueue.main.async { + completion() + } seal.fulfill(()) } return promise } /// Blocks the calling thread until the write has finished. + @discardableResult @objc(writeSyncWithBlock:error:) - public static func objc_writeSync(with block: @escaping (YapDatabaseReadWriteTransaction) -> Void) throws { - try writeSync(with: block) - } - - /// Blocks the calling thread until the write has finished. public static func writeSync(with block: @escaping (YapDatabaseReadWriteTransaction) -> Void) throws { try write(with: block).wait() } diff --git a/SignalServiceKit/src/Messages/OWSDisappearingMessagesJob.m b/SignalServiceKit/src/Messages/OWSDisappearingMessagesJob.m index ea845e659..d3c0794f6 100644 --- a/SignalServiceKit/src/Messages/OWSDisappearingMessagesJob.m +++ b/SignalServiceKit/src/Messages/OWSDisappearingMessagesJob.m @@ -17,6 +17,7 @@ #import "TSMessage.h" #import "TSThread.h" #import +#import NS_ASSUME_NONNULL_BEGIN diff --git a/SignalServiceKit/src/Messages/OWSFailedAttachmentDownloadsJob.m b/SignalServiceKit/src/Messages/OWSFailedAttachmentDownloadsJob.m index a26b7dfc0..202ee51a6 100644 --- a/SignalServiceKit/src/Messages/OWSFailedAttachmentDownloadsJob.m +++ b/SignalServiceKit/src/Messages/OWSFailedAttachmentDownloadsJob.m @@ -8,6 +8,7 @@ #import #import #import +#import NS_ASSUME_NONNULL_BEGIN diff --git a/SignalServiceKit/src/Messages/OWSFailedMessagesJob.m b/SignalServiceKit/src/Messages/OWSFailedMessagesJob.m index 678f0c93b..be2e799d9 100644 --- a/SignalServiceKit/src/Messages/OWSFailedMessagesJob.m +++ b/SignalServiceKit/src/Messages/OWSFailedMessagesJob.m @@ -9,6 +9,7 @@ #import #import #import +#import NS_ASSUME_NONNULL_BEGIN diff --git a/SignalServiceKit/src/Messages/OWSIncompleteCallsJob.m b/SignalServiceKit/src/Messages/OWSIncompleteCallsJob.m index 855076044..de35ef4a6 100644 --- a/SignalServiceKit/src/Messages/OWSIncompleteCallsJob.m +++ b/SignalServiceKit/src/Messages/OWSIncompleteCallsJob.m @@ -10,6 +10,7 @@ #import #import #import +#import NS_ASSUME_NONNULL_BEGIN diff --git a/SignalServiceKit/src/Storage/TSYapDatabaseObject.m b/SignalServiceKit/src/Storage/TSYapDatabaseObject.m index 897818e1f..013853160 100644 --- a/SignalServiceKit/src/Storage/TSYapDatabaseObject.m +++ b/SignalServiceKit/src/Storage/TSYapDatabaseObject.m @@ -6,6 +6,7 @@ #import "OWSPrimaryStorage.h" #import "SSKEnvironment.h" #import +#import NS_ASSUME_NONNULL_BEGIN @@ -52,11 +53,9 @@ NS_ASSUME_NONNULL_BEGIN - (void)saveAsyncWithCompletionBlock:(void (^_Nullable)(void))completionBlock { - // TODO: <-------- - [[self dbReadWriteConnection] asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { [self saveWithTransaction:transaction]; - } - completionBlock:completionBlock]; + } completion:completionBlock]; } - (void)touchWithTransaction:(YapDatabaseReadWriteTransaction *)transaction diff --git a/SignalServiceKit/src/Util/OWSAnalytics.m b/SignalServiceKit/src/Util/OWSAnalytics.m index ac70dc735..28694f221 100755 --- a/SignalServiceKit/src/Util/OWSAnalytics.m +++ b/SignalServiceKit/src/Util/OWSAnalytics.m @@ -13,6 +13,7 @@ #import #import #import +#import NS_ASSUME_NONNULL_BEGIN From 67a482bbd7f9a1cfcc726d657f38aeb40ef233b6 Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Thu, 11 Jun 2020 14:37:03 +1000 Subject: [PATCH 13/19] Remove TODO --- SignalServiceKit/src/Loki/Database/Storage.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SignalServiceKit/src/Loki/Database/Storage.swift b/SignalServiceKit/src/Loki/Database/Storage.swift index 6dcd71800..71547d998 100644 --- a/SignalServiceKit/src/Loki/Database/Storage.swift +++ b/SignalServiceKit/src/Loki/Database/Storage.swift @@ -52,7 +52,7 @@ public final class Storage : NSObject { @discardableResult public static func write(with block: @escaping (YapDatabaseReadWriteTransaction) -> Void, completion: @escaping () -> Void) -> Promise { let (promise, seal) = Promise.pending() - serialQueue.async { // TODO: There are cases where this isn't necessary + serialQueue.async { owsStorage.dbReadWriteConnection.readWrite(block) DispatchQueue.main.async { completion() From 146329627f0b2d31b00617018282bddd87642b6c Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Thu, 11 Jun 2020 14:41:19 +1000 Subject: [PATCH 14/19] Clean --- SignalServiceKit/src/Loki/Database/Storage.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SignalServiceKit/src/Loki/Database/Storage.swift b/SignalServiceKit/src/Loki/Database/Storage.swift index 71547d998..65a9e019b 100644 --- a/SignalServiceKit/src/Loki/Database/Storage.swift +++ b/SignalServiceKit/src/Loki/Database/Storage.swift @@ -35,7 +35,7 @@ public final class Storage : NSObject { @discardableResult @objc(writeWithBlock:) public static func objc_write(with block: @escaping (YapDatabaseReadWriteTransaction) -> Void) -> AnyPromise { - return AnyPromise.from(write(with: block)) + return AnyPromise.from(write(with: block) { }) } @discardableResult @@ -66,6 +66,6 @@ public final class Storage : NSObject { @discardableResult @objc(writeSyncWithBlock:error:) public static func writeSync(with block: @escaping (YapDatabaseReadWriteTransaction) -> Void) throws { - try write(with: block).wait() + try write(with: block, completion: { }).wait() } } From 1f5c5aadd9fe3e0ebe8151477500230830cac489 Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Fri, 12 Jun 2020 13:57:30 +1000 Subject: [PATCH 15/19] sync profile updating to slave device --- SignalMessaging/profiles/OWSProfileManager.m | 14 ++++++++++++-- .../Sync Messages/SyncMessagesProtocol.swift | 19 ++++++++++++++++++- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/SignalMessaging/profiles/OWSProfileManager.m b/SignalMessaging/profiles/OWSProfileManager.m index 41e545a7d..6bd6d431f 100644 --- a/SignalMessaging/profiles/OWSProfileManager.m +++ b/SignalMessaging/profiles/OWSProfileManager.m @@ -238,7 +238,8 @@ typedef void (^ProfileManagerFailureBlock)(NSError *error); // Ensure that the success and failure blocks are called on the main thread. void (^failureBlock)(NSError *) = ^(NSError *error) { OWSLogError(@"Updating service with profile failed."); - + + /* // We use a "self-only" contact sync to indicate to desktop // that we've changed our profile and that it should do a // profile fetch for "self". @@ -248,6 +249,10 @@ typedef void (^ProfileManagerFailureBlock)(NSError *error); if (requiresSync) { [[self.syncManager syncLocalContact] retainUntilComplete]; } + */ + if (requiresSync) { + [LKSyncMessagesProtocol syncProfileUpdate]; + } dispatch_async(dispatch_get_main_queue(), ^{ failureBlockParameter(error); @@ -255,13 +260,18 @@ typedef void (^ProfileManagerFailureBlock)(NSError *error); }; void (^successBlock)(void) = ^{ OWSLogInfo(@"Successfully updated service with profile."); - + + /* // We use a "self-only" contact sync to indicate to desktop // that we've changed our profile and that it should do a // profile fetch for "self". if (requiresSync) { [[self.syncManager syncLocalContact] retainUntilComplete]; } + */ + if (requiresSync) { + [LKSyncMessagesProtocol syncProfileUpdate]; + } dispatch_async(dispatch_get_main_queue(), ^{ successBlockParameter(); diff --git a/SignalServiceKit/src/Loki/Protocol/Sync Messages/SyncMessagesProtocol.swift b/SignalServiceKit/src/Loki/Protocol/Sync Messages/SyncMessagesProtocol.swift index 5574c8463..b500a6cfa 100644 --- a/SignalServiceKit/src/Loki/Protocol/Sync Messages/SyncMessagesProtocol.swift +++ b/SignalServiceKit/src/Loki/Protocol/Sync Messages/SyncMessagesProtocol.swift @@ -23,6 +23,22 @@ public final class SyncMessagesProtocol : NSObject { // FIXME: We added this check to avoid a crash, but we should really figure out why that crash was happening in the first place return !UserDefaults.standard[.hasLaunchedOnce] } + + @objc(syncProfileUpdate) + public static func syncProfileUpdate() { + storage.dbReadWriteConnection.readWrite{ transaction in + let userHexEncodedPublicKey = getUserHexEncodedPublicKey() + let linkedDevices = LokiDatabaseUtilities.getLinkedDeviceHexEncodedPublicKeys(for: userHexEncodedPublicKey, in: transaction) + for hexEncodedPublicKey in linkedDevices { + guard hexEncodedPublicKey != userHexEncodedPublicKey else { continue } + let thread = TSContactThread.getOrCreateThread(withContactId: hexEncodedPublicKey, transaction: transaction) + let syncMessage = OWSOutgoingSyncMessage.init(in: thread, messageBody: "", attachmentId: nil) + syncMessage.save(with: transaction) + let messageSenderJobQueue = SSKEnvironment.shared.messageSenderJobQueue + messageSenderJobQueue.add(message: syncMessage, transaction: transaction) + } + } + } @objc(syncContactWithHexEncodedPublicKey:in:) public static func syncContact(_ hexEncodedPublicKey: String, in transaction: YapDatabaseReadTransaction) -> AnyPromise { @@ -166,9 +182,10 @@ public final class SyncMessagesProtocol : NSObject { let parser = ContactParser(data: data) let hexEncodedPublicKeys = parser.parseHexEncodedPublicKeys() let userHexEncodedPublicKey = getUserHexEncodedPublicKey() + let linkedDevices = LokiDatabaseUtilities.getLinkedDeviceHexEncodedPublicKeys(for: userHexEncodedPublicKey, in: transaction) // Try to establish sessions for hexEncodedPublicKey in hexEncodedPublicKeys { - guard hexEncodedPublicKey != userHexEncodedPublicKey else { continue } // Skip self + guard !linkedDevices.contains(hexEncodedPublicKey) else { continue } // Skip self and linked devices // We don't update the friend request status; that's done in OWSMessageSender.sendMessage(_:) let friendRequestStatus = storage.getFriendRequestStatus(for: hexEncodedPublicKey, transaction: transaction) switch friendRequestStatus { From 326056c53df2c11b0f23e3cb3862f22fb15bce4e Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Fri, 12 Jun 2020 12:24:17 +1000 Subject: [PATCH 16/19] Fix async database transaction handling --- SignalServiceKit/src/Loki/Database/Storage.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SignalServiceKit/src/Loki/Database/Storage.swift b/SignalServiceKit/src/Loki/Database/Storage.swift index 65a9e019b..79496ab84 100644 --- a/SignalServiceKit/src/Loki/Database/Storage.swift +++ b/SignalServiceKit/src/Loki/Database/Storage.swift @@ -53,9 +53,9 @@ public final class Storage : NSObject { public static func write(with block: @escaping (YapDatabaseReadWriteTransaction) -> Void, completion: @escaping () -> Void) -> Promise { let (promise, seal) = Promise.pending() serialQueue.async { - owsStorage.dbReadWriteConnection.readWrite(block) - DispatchQueue.main.async { - completion() + owsStorage.dbReadWriteConnection.readWrite { transaction in + transaction.addCompletionQueue(DispatchQueue.main, completionBlock: completion) + block(transaction) } seal.fulfill(()) } From b4d4522e99697fe286c1f07e041c3c3025aec76f Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Mon, 15 Jun 2020 13:10:46 +1000 Subject: [PATCH 17/19] Clean --- SignalMessaging/profiles/OWSProfileManager.m | 4 ++-- .../Sync Messages/SyncMessagesProtocol.swift | 16 ++++++++-------- .../Messages/Interactions/TSOutgoingMessage.m | 7 ++++--- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/SignalMessaging/profiles/OWSProfileManager.m b/SignalMessaging/profiles/OWSProfileManager.m index ad681ebd4..d9308c977 100644 --- a/SignalMessaging/profiles/OWSProfileManager.m +++ b/SignalMessaging/profiles/OWSProfileManager.m @@ -252,7 +252,7 @@ typedef void (^ProfileManagerFailureBlock)(NSError *error); } */ if (requiresSync) { - [LKSyncMessagesProtocol syncProfileUpdate]; + [LKSyncMessagesProtocol syncProfile]; } dispatch_async(dispatch_get_main_queue(), ^{ @@ -271,7 +271,7 @@ typedef void (^ProfileManagerFailureBlock)(NSError *error); } */ if (requiresSync) { - [LKSyncMessagesProtocol syncProfileUpdate]; + [LKSyncMessagesProtocol syncProfile]; } dispatch_async(dispatch_get_main_queue(), ^{ diff --git a/SignalServiceKit/src/Loki/Protocol/Sync Messages/SyncMessagesProtocol.swift b/SignalServiceKit/src/Loki/Protocol/Sync Messages/SyncMessagesProtocol.swift index b500a6cfa..00d3bc37c 100644 --- a/SignalServiceKit/src/Loki/Protocol/Sync Messages/SyncMessagesProtocol.swift +++ b/SignalServiceKit/src/Loki/Protocol/Sync Messages/SyncMessagesProtocol.swift @@ -24,14 +24,14 @@ public final class SyncMessagesProtocol : NSObject { return !UserDefaults.standard[.hasLaunchedOnce] } - @objc(syncProfileUpdate) - public static func syncProfileUpdate() { - storage.dbReadWriteConnection.readWrite{ transaction in - let userHexEncodedPublicKey = getUserHexEncodedPublicKey() - let linkedDevices = LokiDatabaseUtilities.getLinkedDeviceHexEncodedPublicKeys(for: userHexEncodedPublicKey, in: transaction) - for hexEncodedPublicKey in linkedDevices { - guard hexEncodedPublicKey != userHexEncodedPublicKey else { continue } - let thread = TSContactThread.getOrCreateThread(withContactId: hexEncodedPublicKey, transaction: transaction) + @objc(syncProfile) + public static func syncProfile() { + try! Storage.writeSync { transaction in + let userPublicKey = getUserHexEncodedPublicKey() + let linkedDevices = LokiDatabaseUtilities.getLinkedDeviceHexEncodedPublicKeys(for: userPublicKey, in: transaction) + for publicKey in linkedDevices { + guard publicKey != userPublicKey else { continue } + let thread = TSContactThread.getOrCreateThread(withContactId: publicKey, transaction: transaction) let syncMessage = OWSOutgoingSyncMessage.init(in: thread, messageBody: "", attachmentId: nil) syncMessage.save(with: transaction) let messageSenderJobQueue = SSKEnvironment.shared.messageSenderJobQueue diff --git a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m index 3bdab9362..8e8c1b077 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m @@ -1126,8 +1126,9 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt - (SSKProtoContentBuilder *)prepareCustomContentBuilder:(SignalRecipient *)recipient { SSKProtoDataMessage *_Nullable dataMessage = [self buildDataMessage:recipient.recipientId]; + if (!dataMessage) { - OWSFailDebug(@"could not build protobuf"); + OWSFailDebug(@"Couldn't build protobuf."); return nil; } @@ -1140,11 +1141,11 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt - (nullable NSData *)buildPlainTextData:(SignalRecipient *)recipient { SSKProtoContentBuilder *contentBuilder = [self prepareCustomContentBuilder:recipient]; + NSError *error; - NSData *_Nullable contentData = [contentBuilder buildSerializedDataAndReturnError:&error]; if (error || !contentData) { - OWSFailDebug(@"could not serialize protobuf: %@", error); + OWSFailDebug(@"Couldn't serialize protobuf due to error: %@.", error); return nil; } From 5e40221936065a6972fcd73e628a9a4510981d65 Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Mon, 15 Jun 2020 13:36:45 +1000 Subject: [PATCH 18/19] Clean --- .../Loki/Components/ConversationCell.swift | 15 +-- .../View Controllers/JoinPublicChatVC.swift | 10 +- .../OWSConversationSettingsViewController.m | 6 +- .../Components/ProfilePictureView.swift | 7 +- .../API/Open Groups/LokiPublicChatAPI.swift | 99 +++++++++---------- .../Open Groups/LokiPublicChatPoller.swift | 4 +- .../Database/OWSPrimaryStorage+Loki.swift | 6 +- .../Sync Messages/SyncMessagesProtocol.swift | 13 +-- 8 files changed, 75 insertions(+), 85 deletions(-) diff --git a/Signal/src/Loki/Components/ConversationCell.swift b/Signal/src/Loki/Components/ConversationCell.swift index 2b75f5850..43f4f1246 100644 --- a/Signal/src/Loki/Components/ConversationCell.swift +++ b/Signal/src/Loki/Components/ConversationCell.swift @@ -141,20 +141,15 @@ final class ConversationCell : UITableViewCell { profilePictureView.hexEncodedPublicKey = "" profilePictureView.isRSSFeed = true } else { - if let groupAvatarImage = (threadViewModel.threadRecord as? TSGroupThread)?.groupModel.groupImage { - profilePictureView.groupAvatarImage = groupAvatarImage + if let openGroupProfilePicture = (threadViewModel.threadRecord as! TSGroupThread).groupModel.groupImage { + profilePictureView.openGroupProfilePicture = openGroupProfilePicture } else { - profilePictureView.groupAvatarImage = nil + profilePictureView.openGroupProfilePicture = nil var users = MentionsManager.userPublicKeyCache[threadViewModel.threadRecord.uniqueId!] ?? [] users.remove(getUserHexEncodedPublicKey()) let randomUsers = users.sorted().prefix(2) // Sort to provide a level of stability - if !randomUsers.isEmpty { - profilePictureView.hexEncodedPublicKey = randomUsers[0] - profilePictureView.additionalHexEncodedPublicKey = randomUsers.count >= 2 ? randomUsers[1] : "" - } else { - profilePictureView.hexEncodedPublicKey = "" - profilePictureView.additionalHexEncodedPublicKey = "" - } + profilePictureView.hexEncodedPublicKey = randomUsers.count >= 1 ? randomUsers[0] : "" + profilePictureView.additionalHexEncodedPublicKey = randomUsers.count >= 2 ? randomUsers[1] : "" } profilePictureView.isRSSFeed = (threadViewModel.threadRecord as? TSGroupThread)?.isRSSFeed ?? false } diff --git a/Signal/src/Loki/View Controllers/JoinPublicChatVC.swift b/Signal/src/Loki/View Controllers/JoinPublicChatVC.swift index dac0f08f1..616e317cb 100644 --- a/Signal/src/Loki/View Controllers/JoinPublicChatVC.swift +++ b/Signal/src/Loki/View Controllers/JoinPublicChatVC.swift @@ -133,11 +133,11 @@ final class JoinPublicChatVC : BaseVC, UIPageViewControllerDataSource, UIPageVie isJoining = true let channelID: UInt64 = 1 let urlAsString = url.absoluteString - let userHexEncodedPublicKey = UserDefaults.standard[.masterHexEncodedPublicKey] ?? getUserHexEncodedPublicKey() - let displayName = OWSProfileManager.shared().profileNameForRecipient(withID: userHexEncodedPublicKey) - let profilePictureURL = OWSProfileManager.shared().profilePictureURL() - let profileKey = OWSProfileManager.shared().localProfileKey().keyData - // TODO: Profile picture & profile key + let userPublicKey = UserDefaults.standard[.masterHexEncodedPublicKey] ?? getUserHexEncodedPublicKey() + let profileManager = OWSProfileManager.shared() + let displayName = profileManager.profileNameForRecipient(withID: userPublicKey) + let profilePictureURL = profileManager.profilePictureURL() + let profileKey = profileManager.localProfileKey().keyData try! Storage.writeSync { transaction in transaction.removeObject(forKey: "\(urlAsString).\(channelID)", inCollection: LokiPublicChatAPI.lastMessageServerIDCollection) transaction.removeObject(forKey: "\(urlAsString).\(channelID)", inCollection: LokiPublicChatAPI.lastDeletionServerIDCollection) diff --git a/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m b/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m index ea5450f9b..b9269b9c7 100644 --- a/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m +++ b/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m @@ -957,9 +957,9 @@ const CGFloat kIconViewLength = 24; [stackView setLayoutMarginsRelativeArrangement:YES]; if (self.isGroupThread) { - TSGroupThread* groupThread = (TSGroupThread*)self.thread; - if (groupThread.isPublicChat && groupThread.groupModel.groupImage != nil) { - profilePictureView.groupAvatarImage = groupThread.groupModel.groupImage; + TSGroupThread* groupThread = (TSGroupThread *)self.thread; + if (groupThread.isPublicChat && groupThread.groupModel.groupImage != nil && ![groupThread.groupModel.groupName isEqual:@"Session Public Chat"]) { + profilePictureView.openGroupProfilePicture = groupThread.groupModel.groupImage; profilePictureView.isRSSFeed = false; } else { profilePictureView.hexEncodedPublicKey = @""; diff --git a/SignalMessaging/Loki/Redesign/Components/ProfilePictureView.swift b/SignalMessaging/Loki/Redesign/Components/ProfilePictureView.swift index 6aacb8f21..056db58aa 100644 --- a/SignalMessaging/Loki/Redesign/Components/ProfilePictureView.swift +++ b/SignalMessaging/Loki/Redesign/Components/ProfilePictureView.swift @@ -7,7 +7,7 @@ public final class ProfilePictureView : UIView { @objc public var isRSSFeed = false @objc public var hexEncodedPublicKey: String! @objc public var additionalHexEncodedPublicKey: String? - @objc public var groupAvatarImage: UIImage? + @objc public var openGroupProfilePicture: UIImage? // MARK: Components private lazy var imageView = getImageView() @@ -62,9 +62,8 @@ public final class ProfilePictureView : UIView { additionalImageView.isHidden = true additionalImageView.image = nil } - guard hexEncodedPublicKey != nil || groupAvatarImage != nil else { return } // Can happen in rare cases - - imageView.image = isRSSFeed ? nil : groupAvatarImage != nil ? groupAvatarImage! : getProfilePicture(of: size, for: hexEncodedPublicKey) + guard hexEncodedPublicKey != nil || openGroupProfilePicture != nil else { return } + imageView.image = isRSSFeed ? nil : (openGroupProfilePicture ?? getProfilePicture(of: size, for: hexEncodedPublicKey)) imageView.backgroundColor = isRSSFeed ? UIColor(rgbHex: 0x353535) : UIColor(rgbHex: 0xD8D8D8) // UIColor(rgbHex: 0xD8D8D8) = Colors.unimportant imageView.layer.cornerRadius = size / 2 imageView.contentMode = isRSSFeed ? .center : .scaleAspectFit diff --git a/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatAPI.swift b/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatAPI.swift index 663e90708..9a73dda57 100644 --- a/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatAPI.swift +++ b/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatAPI.swift @@ -19,8 +19,8 @@ public final class LokiPublicChatAPI : LokiDotNetAPI { // MARK: Convenience private static var userDisplayName: String { - let userHexEncodedPublicKey = UserDefaults.standard[.masterHexEncodedPublicKey] ?? getUserHexEncodedPublicKey() - return SSKEnvironment.shared.profileManager.profileNameForRecipient(withID: userHexEncodedPublicKey) ?? "Anonymous" + let userPublicKey = UserDefaults.standard[.masterHexEncodedPublicKey] ?? getUserHexEncodedPublicKey() + return SSKEnvironment.shared.profileManager.profileNameForRecipient(withID: userPublicKey) ?? "Anonymous" } // MARK: Database @@ -331,6 +331,51 @@ public final class LokiPublicChatAPI : LokiDotNetAPI { } } + static func updateProfileIfNeeded(for channel: UInt64, on server: String, from info: LokiPublicChatInfo) { + let storage = OWSPrimaryStorage.shared() + let publicChatID = "\(server).\(channel)" + try! Storage.writeSync { transaction in + // Update user count + storage.setUserCount(info.memberCount, forPublicChatWithID: publicChatID, in: transaction) + let groupThread = TSGroupThread.getOrCreateThread(withGroupId: publicChatID.data(using: .utf8)!, groupType: .openGroup, transaction: transaction) + // Update display name if needed + let groupModel = groupThread.groupModel + if groupModel.groupName != info.displayName { + let newGroupModel = TSGroupModel(title: info.displayName, memberIds: groupModel.groupMemberIds, image: groupModel.groupImage, groupId: groupModel.groupId, groupType: groupModel.groupType, adminIds: groupModel.groupAdminIds) + groupThread.groupModel = newGroupModel + groupThread.save(with: transaction) + } + // Download and update profile picture if needed + let oldProfilePictureURL = storage.getProfilePictureURL(forPublicChatWithID: publicChatID, in: transaction) + if oldProfilePictureURL != info.profilePictureURL || groupModel.groupImage == nil { + storage.setProfilePictureURL(info.profilePictureURL, forPublicChatWithID: publicChatID, in: transaction) + if let avatarURL = info.profilePictureURL { + let configuration = URLSessionConfiguration.default + let manager = AFURLSessionManager.init(sessionConfiguration: configuration) + let url = URL(string: "\(server)\(avatarURL)")! + let request = URLRequest(url: url) + let task = manager.downloadTask(with: request, progress: nil, + destination: { (targetPath: URL, response: URLResponse) -> URL in + let tempFilePath = URL(fileURLWithPath: OWSTemporaryDirectoryAccessibleAfterFirstAuth()).appendingPathComponent(UUID().uuidString) + return tempFilePath + }, + completionHandler: { (response: URLResponse, filePath: URL?, error: Error?) in + if let error = error { + print("[Loki] Couldn't download profile picture for public chat channel with ID: \(channel) on server: \(server).") + return + } + if let filePath = filePath, let avatarData = try? Data.init(contentsOf: filePath) { + let attachmentStream = TSAttachmentStream(contentType: OWSMimeTypeImageJpeg, byteCount: UInt32(avatarData.count), sourceFilename: nil, caption: nil, albumMessageId: nil) + try! attachmentStream.write(avatarData) + groupThread.updateAvatar(with: attachmentStream) + } + }) + task.resume() + } + } + } + } + // MARK: Joining & Leaving @objc(getInfoForChannelWithID:onServer:) public static func objc_getInfo(for channel: UInt64, on server: String) -> AnyPromise { @@ -361,60 +406,12 @@ public final class LokiPublicChatAPI : LokiDotNetAPI { storage.setUserCount(memberCount, forPublicChatWithID: "\(server).\(channel)", in: transaction) } let publicChatInfo = LokiPublicChatInfo(displayName: displayName, profilePictureURL: profilePictureURL, memberCount: memberCount) - updateOpenGroupProfileIfNeeded(for: channel, on: server, with: publicChatInfo) + updateProfileIfNeeded(for: channel, on: server, from: publicChatInfo) return publicChatInfo } }.handlingInvalidAuthTokenIfNeeded(for: server) } } - - static func updateOpenGroupProfileIfNeeded(for channel: UInt64, on server: String, with info: LokiPublicChatInfo) { - let storage = OWSPrimaryStorage.shared() - let publicChatID = "\(server).\(channel)" - storage.dbReadWriteConnection.readWrite { transaction in - //Save user count - storage.setUserCount(info.memberCount, forPublicChatWithID: publicChatID, in: transaction) - - let groupThread = TSGroupThread.getOrCreateThread(withGroupId: publicChatID.data(using: .utf8)!, groupType: .openGroup, transaction: transaction) - - //Update display name if needed - let groupModel = groupThread.groupModel - if groupModel.groupName != info.displayName { - let newGroupModel = TSGroupModel.init(title: info.displayName, memberIds: groupModel.groupMemberIds, image: groupModel.groupImage, groupId: groupModel.groupId, groupType: groupModel.groupType, adminIds: groupModel.groupAdminIds) - groupThread.groupModel = newGroupModel - groupThread.save(with: transaction) - } - - //Download and update profile picture if needed - let oldAvatarURL = storage.getAvatarURL(forPublicChatWithID: publicChatID, in: transaction) - if oldAvatarURL != info.profilePictureURL || groupModel.groupImage == nil { - storage.setAvatarURL(info.profilePictureURL, forPublicChatWithID: publicChatID, in: transaction) - if let avatarURL = info.profilePictureURL { - let configuration = URLSessionConfiguration.default - let manager = AFURLSessionManager.init(sessionConfiguration: configuration) - let url = URL(string: "\(server)\(avatarURL)")! - let request = URLRequest(url: url) - let task = manager.downloadTask(with: request, progress: nil, - destination: {(targetPath: URL, response: URLResponse) -> URL in - let tempFilePath = URL(fileURLWithPath: OWSTemporaryDirectoryAccessibleAfterFirstAuth()).appendingPathComponent(UUID().uuidString) - return tempFilePath - }, - completionHandler: { (response: URLResponse, filePath: URL?, error: Error?) in - if let error = error { - print("[Loki] Couldn't download profile picture for public chat channel with ID: \(channel) on server: \(server)") - return - } - if let path = filePath, let avatarData = try? Data.init(contentsOf: path) { - let attachmentStream = TSAttachmentStream.init(contentType: OWSMimeTypeImageJpeg, byteCount: UInt32(avatarData.count), sourceFilename: nil, caption: nil, albumMessageId: nil) - try! attachmentStream.write(avatarData) - groupThread.updateAvatar(with: attachmentStream) - } - }) - task.resume() - } - } - } - } public static func join(_ channel: UInt64, on server: String) -> Promise { return attempt(maxRetryCount: maxRetryCount, recoveringOn: DispatchQueue.global()) { diff --git a/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatPoller.swift b/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatPoller.swift index 0b26fd4c7..ffe86c3b0 100644 --- a/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatPoller.swift +++ b/SignalServiceKit/src/Loki/API/Open Groups/LokiPublicChatPoller.swift @@ -150,7 +150,9 @@ public final class LokiPublicChatPoller : NSObject { if !wasSentByCurrentUser { content.setDataMessage(try! dataMessage.build()) } else { - SyncMessagesProtocol.addForceSyncMessageTimestamp(message.timestamp, from: senderHexEncodedPublicKey) + // The line below is necessary to make it so that when a user sends a message in an open group and then + // deletes and re-joins the open group without closing the app in between, the message isn't ignored. + SyncMessagesProtocol.dropFromSyncMessageTimestampCache(message.timestamp, for: senderHexEncodedPublicKey) let syncMessageSentBuilder = SSKProtoSyncMessageSent.builder() syncMessageSentBuilder.setMessage(try! dataMessage.build()) syncMessageSentBuilder.setDestination(userHexEncodedPublicKey) diff --git a/SignalServiceKit/src/Loki/Database/OWSPrimaryStorage+Loki.swift b/SignalServiceKit/src/Loki/Database/OWSPrimaryStorage+Loki.swift index e867f8b18..060aeac66 100644 --- a/SignalServiceKit/src/Loki/Database/OWSPrimaryStorage+Loki.swift +++ b/SignalServiceKit/src/Loki/Database/OWSPrimaryStorage+Loki.swift @@ -140,11 +140,11 @@ public extension OWSPrimaryStorage { transaction.setObject(userCount, forKey: publicChatID, inCollection: Storage.openGroupUserCountCollection) } - public func getAvatarURL(forPublicChatWithID publicChatID: String, in transaction: YapDatabaseReadTransaction) -> String? { + public func getProfilePictureURL(forPublicChatWithID publicChatID: String, in transaction: YapDatabaseReadTransaction) -> String? { return transaction.object(forKey: publicChatID, inCollection: Storage.openGroupProfilePictureURLCollection) as? String } - public func setAvatarURL(_ avatarURL: String?, forPublicChatWithID publicChatID: String, in transaction: YapDatabaseReadWriteTransaction) { - transaction.setObject(avatarURL, forKey: publicChatID, inCollection: Storage.openGroupProfilePictureURLCollection) + public func setProfilePictureURL(_ profilePictureURL: String?, forPublicChatWithID publicChatID: String, in transaction: YapDatabaseReadWriteTransaction) { + transaction.setObject(profilePictureURL, forKey: publicChatID, inCollection: Storage.openGroupProfilePictureURLCollection) } } diff --git a/SignalServiceKit/src/Loki/Protocol/Sync Messages/SyncMessagesProtocol.swift b/SignalServiceKit/src/Loki/Protocol/Sync Messages/SyncMessagesProtocol.swift index e174cbb2a..87f47c2a7 100644 --- a/SignalServiceKit/src/Loki/Protocol/Sync Messages/SyncMessagesProtocol.swift +++ b/SignalServiceKit/src/Loki/Protocol/Sync Messages/SyncMessagesProtocol.swift @@ -112,13 +112,10 @@ public final class SyncMessagesProtocol : NSObject { let hexEncodedPublicKey = envelope.source! return LokiDatabaseUtilities.isUserLinkedDevice(hexEncodedPublicKey, transaction: transaction) } - - @objc(addForceSyncMessageTimestamp:from:) - public static func addForceSyncMessageTimestamp(_ timestamp: UInt64, from hexEncodedPublicKey: String) { + + public static func dropFromSyncMessageTimestampCache(_ timestamp: UInt64, for hexEncodedPublicKey: String) { var timestamps: Set = syncMessageTimestamps[hexEncodedPublicKey] ?? [] - if timestamps.contains(timestamp) { - timestamps.remove(timestamp) - } + if timestamps.contains(timestamp) { timestamps.remove(timestamp) } syncMessageTimestamps[hexEncodedPublicKey] = timestamps } @@ -254,8 +251,8 @@ public final class SyncMessagesProtocol : NSObject { for openGroup in groups { let openGroupManager = LokiPublicChatManager.shared guard openGroupManager.getChat(server: openGroup.url, channel: openGroup.channel) == nil else { return } - let userHexEncodedPublicKey = UserDefaults.standard[.masterHexEncodedPublicKey] ?? getUserHexEncodedPublicKey() - let displayName = SSKEnvironment.shared.profileManager.profileNameForRecipient(withID: userHexEncodedPublicKey) + let userPublicKey = UserDefaults.standard[.masterHexEncodedPublicKey] ?? getUserHexEncodedPublicKey() + let displayName = SSKEnvironment.shared.profileManager.profileNameForRecipient(withID: userPublicKey) LokiPublicChatAPI.setDisplayName(to: displayName, on: openGroup.url) openGroupManager.addChat(server: openGroup.url, channel: openGroup.channel) } From b87ab79c5b2d209e20f2265b9d9cc9de059dbc6d Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Mon, 15 Jun 2020 13:50:56 +1000 Subject: [PATCH 19/19] Debug --- Signal/src/Loki/Components/ConversationCell.swift | 5 +++-- Signal/src/Models/MessageActions.swift | 6 +++--- .../ThreadSettings/OWSConversationSettingsViewController.m | 2 +- .../Loki/Redesign/Components/ProfilePictureView.swift | 1 + 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Signal/src/Loki/Components/ConversationCell.swift b/Signal/src/Loki/Components/ConversationCell.swift index 43f4f1246..f31c8ba2f 100644 --- a/Signal/src/Loki/Components/ConversationCell.swift +++ b/Signal/src/Loki/Components/ConversationCell.swift @@ -134,17 +134,18 @@ final class ConversationCell : UITableViewCell { // MARK: Updating private func update() { + AssertIsOnMainThread() MentionsManager.populateUserPublicKeyCacheIfNeeded(for: threadViewModel.threadRecord.uniqueId!) // FIXME: This is a terrible place to do this unreadMessagesIndicatorView.alpha = threadViewModel.hasUnreadMessages ? 1 : 0.0001 // Setting the alpha to exactly 0 causes an issue on iOS 12 + profilePictureView.openGroupProfilePicture = nil if threadViewModel.isGroupThread { - if threadViewModel.name == "Session Public Chat" { + if threadViewModel.name == "Loki Public Chat" { profilePictureView.hexEncodedPublicKey = "" profilePictureView.isRSSFeed = true } else { if let openGroupProfilePicture = (threadViewModel.threadRecord as! TSGroupThread).groupModel.groupImage { profilePictureView.openGroupProfilePicture = openGroupProfilePicture } else { - profilePictureView.openGroupProfilePicture = nil var users = MentionsManager.userPublicKeyCache[threadViewModel.threadRecord.uniqueId!] ?? [] users.remove(getUserHexEncodedPublicKey()) let randomUsers = users.sorted().prefix(2) // Sort to provide a level of stability diff --git a/Signal/src/Models/MessageActions.swift b/Signal/src/Models/MessageActions.swift index 5d99a6c91..70883b76e 100644 --- a/Signal/src/Models/MessageActions.swift +++ b/Signal/src/Models/MessageActions.swift @@ -115,7 +115,7 @@ class ConversationViewItemActions: NSObject { actions.append(deleteAction) } - if isGroup && conversationViewItem.interaction.thread.name() == "Session Public Chat" { + if isGroup && conversationViewItem.interaction.thread.name() == "Loki Public Chat" { let reportAction = MessageActionBuilder.report(conversationViewItem, delegate: delegate) actions.append(reportAction) } @@ -159,7 +159,7 @@ class ConversationViewItemActions: NSObject { actions.append(deleteAction) } - if isGroup && conversationViewItem.interaction.thread.name() == "Session Public Chat" { + if isGroup && conversationViewItem.interaction.thread.name() == "Loki Public Chat" { let reportAction = MessageActionBuilder.report(conversationViewItem, delegate: delegate) actions.append(reportAction) } @@ -192,7 +192,7 @@ class ConversationViewItemActions: NSObject { actions.append(deleteAction) } - if isGroup && conversationViewItem.interaction.thread.name() == "Session Public Chat" { + if isGroup && conversationViewItem.interaction.thread.name() == "Loki Public Chat" { let reportAction = MessageActionBuilder.report(conversationViewItem, delegate: delegate) actions.append(reportAction) } diff --git a/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m b/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m index b9269b9c7..bc3ffd057 100644 --- a/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m +++ b/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m @@ -958,7 +958,7 @@ const CGFloat kIconViewLength = 24; if (self.isGroupThread) { TSGroupThread* groupThread = (TSGroupThread *)self.thread; - if (groupThread.isPublicChat && groupThread.groupModel.groupImage != nil && ![groupThread.groupModel.groupName isEqual:@"Session Public Chat"]) { + if (groupThread.isPublicChat && groupThread.groupModel.groupImage != nil && ![groupThread.groupModel.groupName isEqual:@"Loki Public Chat"]) { profilePictureView.openGroupProfilePicture = groupThread.groupModel.groupImage; profilePictureView.isRSSFeed = false; } else { diff --git a/SignalMessaging/Loki/Redesign/Components/ProfilePictureView.swift b/SignalMessaging/Loki/Redesign/Components/ProfilePictureView.swift index 056db58aa..3f5e90bd9 100644 --- a/SignalMessaging/Loki/Redesign/Components/ProfilePictureView.swift +++ b/SignalMessaging/Loki/Redesign/Components/ProfilePictureView.swift @@ -44,6 +44,7 @@ public final class ProfilePictureView : UIView { // MARK: Updating @objc public func update() { + AssertIsOnMainThread() func getProfilePicture(of size: CGFloat, for hexEncodedPublicKey: String) -> UIImage? { guard !hexEncodedPublicKey.isEmpty else { return nil } return OWSProfileManager.shared().profileAvatar(forRecipientId: hexEncodedPublicKey) ?? Identicon.generateIcon(string: hexEncodedPublicKey, size: size)