From ffe44e68be3a5fb807fe5bc0d7228904db2678ce Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Tue, 26 Sep 2017 11:45:22 -0400 Subject: [PATCH 1/2] Refactor linked device read receipts. // FREEBIE --- Signal/src/network/PushManager.m | 6 +- .../src/Devices/OWSLinkedDeviceReadReceipt.h | 21 ++ .../src/Devices/OWSLinkedDeviceReadReceipt.m | 53 +++++ SignalServiceKit/src/Devices/OWSReadReceipt.h | 23 -- SignalServiceKit/src/Devices/OWSReadReceipt.m | 140 ------------ .../OWSReadReceiptsForLinkedDevicesMessage.h | 4 +- .../OWSReadReceiptsForLinkedDevicesMessage.m | 8 +- .../Devices/OWSReadReceiptsForSenderMessage.m | 1 - .../src/Devices/OWSReadReceiptsProcessor.h | 41 ---- .../src/Devices/OWSReadReceiptsProcessor.m | 162 -------------- .../src/Messages/OWSMessageManager.m | 17 +- .../src/Messages/OWSReadReceiptManager.h | 17 +- .../src/Messages/OWSReadReceiptManager.m | 201 ++++++++++++++---- .../src/Storage/TSStorageManager.m | 4 +- 14 files changed, 262 insertions(+), 436 deletions(-) create mode 100644 SignalServiceKit/src/Devices/OWSLinkedDeviceReadReceipt.h create mode 100644 SignalServiceKit/src/Devices/OWSLinkedDeviceReadReceipt.m delete mode 100644 SignalServiceKit/src/Devices/OWSReadReceipt.h delete mode 100644 SignalServiceKit/src/Devices/OWSReadReceipt.m delete mode 100644 SignalServiceKit/src/Devices/OWSReadReceiptsProcessor.h delete mode 100644 SignalServiceKit/src/Devices/OWSReadReceiptsProcessor.m diff --git a/Signal/src/network/PushManager.m b/Signal/src/network/PushManager.m index cf0fd0a7c..c6f8ed2a2 100644 --- a/Signal/src/network/PushManager.m +++ b/Signal/src/network/PushManager.m @@ -11,7 +11,7 @@ #import #import #import -#import +#import #import #import #import @@ -85,7 +85,7 @@ NSString *const Signal_Message_MarkAsRead_Identifier = @"Signal_Message_MarkAsRe [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleMessageRead:) - name:OWSReadReceiptsProcessorMarkedMessageAsReadNotification + name:kMessageMarkedAsReadNotification object:nil]; return self; @@ -93,6 +93,8 @@ NSString *const Signal_Message_MarkAsRead_Identifier = @"Signal_Message_MarkAsRe - (void)handleMessageRead:(NSNotification *)notification { + OWSAssert([NSThread isMainThread]); + if ([notification.object isKindOfClass:[TSIncomingMessage class]]) { TSIncomingMessage *message = (TSIncomingMessage *)notification.object; diff --git a/SignalServiceKit/src/Devices/OWSLinkedDeviceReadReceipt.h b/SignalServiceKit/src/Devices/OWSLinkedDeviceReadReceipt.h new file mode 100644 index 000000000..90a53c6c5 --- /dev/null +++ b/SignalServiceKit/src/Devices/OWSLinkedDeviceReadReceipt.h @@ -0,0 +1,21 @@ +// +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// + +#import "TSYapDatabaseObject.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface OWSLinkedDeviceReadReceipt : TSYapDatabaseObject + +@property (nonatomic, readonly) NSString *senderId; +@property (nonatomic, readonly) uint64_t timestamp; + +- (instancetype)initWithSenderId:(NSString *)senderId timestamp:(uint64_t)timestamp; + ++ (nullable OWSLinkedDeviceReadReceipt *)linkedDeviceReadReceiptWithSenderId:(NSString *)senderId + timestamp:(uint64_t)timestamp; + +@end + +NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Devices/OWSLinkedDeviceReadReceipt.m b/SignalServiceKit/src/Devices/OWSLinkedDeviceReadReceipt.m new file mode 100644 index 000000000..eb2d576cb --- /dev/null +++ b/SignalServiceKit/src/Devices/OWSLinkedDeviceReadReceipt.m @@ -0,0 +1,53 @@ +// +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// + +#import "OWSLinkedDeviceReadReceipt.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation OWSLinkedDeviceReadReceipt + +- (instancetype)initWithSenderId:(NSString *)senderId timestamp:(uint64_t)timestamp; +{ + OWSAssert(senderId.length > 0 && timestamp > 0); + + self = [super initWithUniqueId:[OWSLinkedDeviceReadReceipt uniqueIdForSenderId:senderId timestamp:timestamp]]; + if (!self) { + return self; + } + + _senderId = senderId; + _timestamp = timestamp; + + return self; +} + ++ (NSString *)uniqueIdForSenderId:(NSString *)senderId timestamp:(uint64_t)timestamp +{ + OWSAssert(senderId.length > 0 && timestamp > 0); + + return [NSString stringWithFormat:@"%@ %llu", senderId, timestamp]; +} + ++ (nullable OWSLinkedDeviceReadReceipt *)linkedDeviceReadReceiptWithSenderId:(NSString *)senderId + timestamp:(uint64_t)timestamp +{ + return [OWSLinkedDeviceReadReceipt fetchObjectWithUniqueID:[self uniqueIdForSenderId:senderId timestamp:timestamp]]; +} + +#pragma mark - Logging + ++ (NSString *)tag +{ + return [NSString stringWithFormat:@"[%@]", self.class]; +} + +- (NSString *)tag +{ + return self.class.tag; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Devices/OWSReadReceipt.h b/SignalServiceKit/src/Devices/OWSReadReceipt.h deleted file mode 100644 index d247dd539..000000000 --- a/SignalServiceKit/src/Devices/OWSReadReceipt.h +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright © 2016 Open Whisper Systems. All rights reserved. - -#import "TSYapDatabaseObject.h" - -NS_ASSUME_NONNULL_BEGIN - -@class YapDatabase; - -@interface OWSReadReceipt : TSYapDatabaseObject - -@property (nonatomic, readonly) NSString *senderId; -@property (nonatomic, readonly) uint64_t timestamp; -@property (nonatomic, readonly, getter=isValid) BOOL valid; -@property (nonatomic, readonly) NSArray *validationErrorMessages; - -- (instancetype)initWithSenderId:(NSString *)senderId timestamp:(uint64_t)timestamp; - -+ (nullable instancetype)firstWithSenderId:(NSString *)senderId timestamp:(uint64_t)timestamp; -+ (void)asyncRegisterIndexOnSenderIdAndTimestampWithDatabase:(YapDatabase *)database; - -@end - -NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Devices/OWSReadReceipt.m b/SignalServiceKit/src/Devices/OWSReadReceipt.m deleted file mode 100644 index 280d07abe..000000000 --- a/SignalServiceKit/src/Devices/OWSReadReceipt.m +++ /dev/null @@ -1,140 +0,0 @@ -// -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. -// - -#import "OWSReadReceipt.h" -#import -#import -#import - -NS_ASSUME_NONNULL_BEGIN - -NSString *const OWSReadReceiptIndexOnSenderIdAndTimestamp = @"OWSReadReceiptIndexOnSenderIdAndTimestamp"; -NSString *const OWSReadReceiptColumnTimestamp = @"timestamp"; -NSString *const OWSReadReceiptColumnSenderId = @"senderId"; - -@implementation OWSReadReceipt - -- (instancetype)initWithSenderId:(NSString *)senderId timestamp:(uint64_t)timestamp; -{ - self = [super init]; - if (!self) { - return self; - } - - NSMutableArray *validationErrorMessage = [NSMutableArray new]; - if (!senderId) { - [validationErrorMessage addObject:@"Must specify sender id"]; - } - _senderId = senderId; - - if (!timestamp) { - [validationErrorMessage addObject:@"Must specify timestamp"]; - } - _timestamp = timestamp; - - _valid = validationErrorMessage.count == 0; - _validationErrorMessages = [validationErrorMessage copy]; - - return self; -} - -- (instancetype)initWithCoder:(NSCoder *)decoder -{ - self = [super initWithCoder:decoder]; - if (!self) { - return nil; - } - - _valid = YES; - _validationErrorMessages = @[]; - - return self; -} - -+ (MTLPropertyStorage)storageBehaviorForPropertyWithKey:(NSString *)propertyKey -{ - // Don't store ephemeral properties. - if ([propertyKey isEqualToString:@"valid"] || [propertyKey isEqualToString:@"validationErrorMessages"]) { - return MTLPropertyStorageNone; - } else { - return [super storageBehaviorForPropertyWithKey:propertyKey]; - } -} - -+ (void)asyncRegisterIndexOnSenderIdAndTimestampWithDatabase:(YapDatabase *)database -{ - YapDatabaseSecondaryIndexSetup *setup = [YapDatabaseSecondaryIndexSetup new]; - [setup addColumn:OWSReadReceiptColumnSenderId withType:YapDatabaseSecondaryIndexTypeText]; - [setup addColumn:OWSReadReceiptColumnTimestamp withType:YapDatabaseSecondaryIndexTypeInteger]; - - YapDatabaseSecondaryIndexHandler *handler = - [YapDatabaseSecondaryIndexHandler withObjectBlock:^(YapDatabaseReadTransaction *transaction, - NSMutableDictionary *dict, - NSString *collection, - NSString *key, - id object) { - if ([object isKindOfClass:[OWSReadReceipt class]]) { - OWSReadReceipt *readReceipt = (OWSReadReceipt *)object; - dict[OWSReadReceiptColumnSenderId] = readReceipt.senderId; - dict[OWSReadReceiptColumnTimestamp] = @(readReceipt.timestamp); - } - }]; - - YapDatabaseSecondaryIndex *index = [[YapDatabaseSecondaryIndex alloc] initWithSetup:setup handler:handler]; - - [database - asyncRegisterExtension:index - withName:OWSReadReceiptIndexOnSenderIdAndTimestamp - completionBlock:^(BOOL ready) { - if (ready) { - DDLogDebug(@"%@ Successfully set up extension: %@", - self.tag, - OWSReadReceiptIndexOnSenderIdAndTimestamp); - } else { - DDLogError( - @"%@ Unable to setup extension: %@", self.tag, OWSReadReceiptIndexOnSenderIdAndTimestamp); - } - }]; -} - -+ (nullable instancetype)firstWithSenderId:(NSString *)senderId timestamp:(uint64_t)timestamp -{ - __block OWSReadReceipt *foundReadReceipt; - - NSString *queryFormat = [NSString - stringWithFormat:@"WHERE %@ = ? AND %@ = ?", OWSReadReceiptColumnSenderId, OWSReadReceiptColumnTimestamp]; - YapDatabaseQuery *query = [YapDatabaseQuery queryWithFormat:queryFormat, senderId, @(timestamp)]; - - [[self dbReadConnection] readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) { - [[transaction ext:OWSReadReceiptIndexOnSenderIdAndTimestamp] - enumerateKeysAndObjectsMatchingQuery:query - usingBlock:^(NSString *collection, NSString *key, id object, BOOL *stop) { - if (![object isKindOfClass:[OWSReadReceipt class]]) { - DDLogError(@"%@ Unexpected object in index: %@", self.tag, object); - return; - } - - foundReadReceipt = (OWSReadReceipt *)object; - *stop = YES; - }]; - }]; - - return foundReadReceipt; -} - -#pragma mark - Logging - -+ (NSString *)tag -{ - return [NSString stringWithFormat:@"[%@]", self.class]; -} - -- (NSString *)tag -{ - return self.class.tag; -} - -@end - -NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Devices/OWSReadReceiptsForLinkedDevicesMessage.h b/SignalServiceKit/src/Devices/OWSReadReceiptsForLinkedDevicesMessage.h index acc306385..ae57b9910 100644 --- a/SignalServiceKit/src/Devices/OWSReadReceiptsForLinkedDevicesMessage.h +++ b/SignalServiceKit/src/Devices/OWSReadReceiptsForLinkedDevicesMessage.h @@ -6,11 +6,11 @@ NS_ASSUME_NONNULL_BEGIN -@class OWSReadReceipt; +@class OWSLinkedDeviceReadReceipt; @interface OWSReadReceiptsForLinkedDevicesMessage : OWSOutgoingSyncMessage -- (instancetype)initWithReadReceipts:(NSArray *)readReceipts; +- (instancetype)initWithReadReceipts:(NSArray *)readReceipts; @end diff --git a/SignalServiceKit/src/Devices/OWSReadReceiptsForLinkedDevicesMessage.m b/SignalServiceKit/src/Devices/OWSReadReceiptsForLinkedDevicesMessage.m index 9c309b18b..a72f10257 100644 --- a/SignalServiceKit/src/Devices/OWSReadReceiptsForLinkedDevicesMessage.m +++ b/SignalServiceKit/src/Devices/OWSReadReceiptsForLinkedDevicesMessage.m @@ -3,20 +3,20 @@ // #import "OWSReadReceiptsForLinkedDevicesMessage.h" -#import "OWSReadReceipt.h" +#import "OWSLinkedDeviceReadReceipt.h" #import "OWSSignalServiceProtos.pb.h" NS_ASSUME_NONNULL_BEGIN @interface OWSReadReceiptsForLinkedDevicesMessage () -@property (nonatomic, readonly) NSArray *readReceipts; +@property (nonatomic, readonly) NSArray *readReceipts; @end @implementation OWSReadReceiptsForLinkedDevicesMessage -- (instancetype)initWithReadReceipts:(NSArray *)readReceipts +- (instancetype)initWithReadReceipts:(NSArray *)readReceipts { self = [super init]; if (!self) { @@ -31,7 +31,7 @@ NS_ASSUME_NONNULL_BEGIN - (OWSSignalServiceProtosSyncMessageBuilder *)syncMessageBuilder { OWSSignalServiceProtosSyncMessageBuilder *syncMessageBuilder = [OWSSignalServiceProtosSyncMessageBuilder new]; - for (OWSReadReceipt *readReceipt in self.readReceipts) { + for (OWSLinkedDeviceReadReceipt *readReceipt in self.readReceipts) { OWSSignalServiceProtosSyncMessageReadBuilder *readProtoBuilder = [OWSSignalServiceProtosSyncMessageReadBuilder new]; [readProtoBuilder setSender:readReceipt.senderId]; diff --git a/SignalServiceKit/src/Devices/OWSReadReceiptsForSenderMessage.m b/SignalServiceKit/src/Devices/OWSReadReceiptsForSenderMessage.m index 6eab6e485..2542a185f 100644 --- a/SignalServiceKit/src/Devices/OWSReadReceiptsForSenderMessage.m +++ b/SignalServiceKit/src/Devices/OWSReadReceiptsForSenderMessage.m @@ -4,7 +4,6 @@ #import "OWSReadReceiptsForSenderMessage.h" #import "NSDate+OWS.h" -#import "OWSReadReceipt.h" #import "OWSSignalServiceProtos.pb.h" #import "SignalRecipient.h" diff --git a/SignalServiceKit/src/Devices/OWSReadReceiptsProcessor.h b/SignalServiceKit/src/Devices/OWSReadReceiptsProcessor.h deleted file mode 100644 index ded956f09..000000000 --- a/SignalServiceKit/src/Devices/OWSReadReceiptsProcessor.h +++ /dev/null @@ -1,41 +0,0 @@ -// -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. -// - -NS_ASSUME_NONNULL_BEGIN - -@class OWSReadReceipt; -@class OWSSignalServiceProtosSyncMessageRead; -@class TSIncomingMessage; -@class TSStorageManager; -@class YapDatabaseReadWriteTransaction; - -extern NSString *const OWSReadReceiptsProcessorMarkedMessageAsReadNotification; - -// TODO: -@interface OWSReadReceiptsProcessor : NSObject - -/** - * Mark existing messages as read from the given received read receipts. - */ -- (instancetype)initWithReadReceiptProtos:(NSArray *)readReceiptProtos - storageManager:(TSStorageManager *)storageManager; - -/** - * Mark a new message as read in the rare (but does happen!) case that we receive the read receipt before the message - * the read receipt refers to. - */ -- (instancetype)initWithIncomingMessage:(TSIncomingMessage *)incomingMessage - storageManager:(TSStorageManager *)storageManager; - -- (instancetype)initWithReadReceipts:(NSArray *)readReceipts - storageManager:(TSStorageManager *)storageManager NS_DESIGNATED_INITIALIZER; - -- (instancetype)init NS_UNAVAILABLE; - -- (void)process; -- (void)processWithTransaction:(YapDatabaseReadWriteTransaction *)transaction; - -@end - -NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Devices/OWSReadReceiptsProcessor.m b/SignalServiceKit/src/Devices/OWSReadReceiptsProcessor.m deleted file mode 100644 index fe77baa7f..000000000 --- a/SignalServiceKit/src/Devices/OWSReadReceiptsProcessor.m +++ /dev/null @@ -1,162 +0,0 @@ -// -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. -// - -#import "OWSReadReceiptsProcessor.h" -#import "NSNotificationCenter+OWS.h" -#import "OWSDisappearingMessagesJob.h" -#import "OWSReadReceipt.h" -#import "OWSSignalServiceProtos.pb.h" -#import "TSContactThread.h" -#import "TSDatabaseView.h" -#import "TSIncomingMessage.h" -#import "TSStorageManager.h" -#import - -NS_ASSUME_NONNULL_BEGIN - -NSString *const OWSReadReceiptsProcessorMarkedMessageAsReadNotification = - @"OWSReadReceiptsProcessorMarkedMessageAsReadNotification"; - -@interface OWSReadReceiptsProcessor () - -@property (nonatomic, readonly) NSArray *readReceipts; -@property (nonatomic, readonly) TSStorageManager *storageManager; - -@end - -@implementation OWSReadReceiptsProcessor - -- (instancetype)initWithReadReceipts:(NSArray *)readReceipts - storageManager:(TSStorageManager *)storageManager; -{ - self = [super init]; - if (!self) { - return self; - } - - _readReceipts = [readReceipts copy]; - _storageManager = storageManager; - - return self; -} - -- (instancetype)initWithReadReceiptProtos:(NSArray *)readReceiptProtos - storageManager:(TSStorageManager *)storageManager -{ - NSMutableArray *readReceipts = [NSMutableArray new]; - for (OWSSignalServiceProtosSyncMessageRead *readReceiptProto in readReceiptProtos) { - OWSReadReceipt *readReceipt = - [[OWSReadReceipt alloc] initWithSenderId:readReceiptProto.sender timestamp:readReceiptProto.timestamp]; - if (readReceipt.isValid) { - [readReceipts addObject:readReceipt]; - } else { - DDLogError(@"%@ Received invalid read receipt: %@", self.tag, readReceipt.validationErrorMessages); - } - } - - return [self initWithReadReceipts:[readReceipts copy] storageManager:storageManager]; -} - -- (instancetype)initWithIncomingMessage:(TSIncomingMessage *)message storageManager:(TSStorageManager *)storageManager -{ - NSString *messageAuthorId = message.messageAuthorId; - OWSAssert(messageAuthorId.length > 0); - - OWSReadReceipt *readReceipt = [OWSReadReceipt firstWithSenderId:messageAuthorId timestamp:message.timestamp]; - if (readReceipt) { - DDLogInfo(@"%@ Found prior read receipt for incoming message.", self.tag); - return [self initWithReadReceipts:@[ readReceipt ] storageManager:storageManager]; - } else { - // no-op - return [self initWithReadReceipts:@[] storageManager:storageManager]; - } -} - -- (void)process -{ - [[self.storageManager newDatabaseConnection] readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - [self processWithTransaction:transaction]; - }]; -} - -- (void)processWithTransaction:(YapDatabaseReadWriteTransaction *)transaction -{ - OWSAssert(transaction); - - DDLogDebug(@"%@ Processing %ld read receipts.", self.tag, (unsigned long)self.readReceipts.count); - for (OWSReadReceipt *readReceipt in self.readReceipts) { - TSIncomingMessage *message = [TSIncomingMessage findMessageWithAuthorId:readReceipt.senderId - timestamp:readReceipt.timestamp - transaction:transaction]; - if (message) { - OWSAssert(message.thread); - - // Mark all unread messages in this thread that are older than message specified in the read - // receipt. - NSMutableArray> *interactionsToMarkAsRead = [NSMutableArray new]; - - // Always mark the message specified by the read receipt as read. - [interactionsToMarkAsRead addObject:message]; - - [[TSDatabaseView unseenDatabaseViewExtension:transaction] - enumerateRowsInGroup:message.uniqueThreadId - usingBlock:^(NSString *collection, - NSString *key, - id object, - id metadata, - NSUInteger index, - BOOL *stop) { - - TSInteraction *interaction = object; - if (interaction.timestampForSorting > message.timestampForSorting) { - *stop = YES; - return; - } - - id possiblyRead = (id)object; - OWSAssert(!possiblyRead.read); - [interactionsToMarkAsRead addObject:possiblyRead]; - }]; - - for (id interaction in interactionsToMarkAsRead) { - // * Don't send a read receipt in response to a read receipt. - // * Don't update expiration; we'll do that in the next statement. - [interaction markAsReadWithTransaction:transaction sendReadReceipt:NO updateExpiration:NO]; - - if ([interaction isKindOfClass:[TSMessage class]]) { - TSMessage *otherMessage = (TSMessage *)interaction; - - // Update expiration using the timestamp from the readReceipt. - [OWSDisappearingMessagesJob setExpirationForMessage:otherMessage - expirationStartedAt:readReceipt.timestamp]; - - // Fire event that will cancel any pending notifications for this message. - [[NSNotificationCenter defaultCenter] - postNotificationNameAsync:OWSReadReceiptsProcessorMarkedMessageAsReadNotification - object:otherMessage]; - } - } - - // If it was previously saved, no need to keep it around any longer. - [readReceipt removeWithTransaction:transaction]; - } else { - DDLogDebug(@"%@ Received read receipt for an unknown message. Saving it for later.", self.tag); - [readReceipt saveWithTransaction:transaction]; - } - } -} - -+ (NSString *)tag -{ - return [NSString stringWithFormat:@"[%@]", self.class]; -} - -- (NSString *)tag -{ - return self.class.tag; -} - -@end - -NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Messages/OWSMessageManager.m b/SignalServiceKit/src/Messages/OWSMessageManager.m index ac372c17e..258f4909e 100644 --- a/SignalServiceKit/src/Messages/OWSMessageManager.m +++ b/SignalServiceKit/src/Messages/OWSMessageManager.m @@ -19,7 +19,6 @@ #import "OWSIncomingSentMessageTranscript.h" #import "OWSMessageSender.h" #import "OWSReadReceiptManager.h" -#import "OWSReadReceiptsProcessor.h" #import "OWSRecordTranscriptJob.h" #import "OWSSyncContactsMessage.h" #import "OWSSyncGroupsMessage.h" @@ -570,10 +569,8 @@ NS_ASSUME_NONNULL_BEGIN } else if (syncMessage.read.count > 0) { DDLogInfo(@"%@ Received %ld read receipt(s)", self.tag, (u_long)syncMessage.read.count); - OWSReadReceiptsProcessor *readReceiptsProcessor = - [[OWSReadReceiptsProcessor alloc] initWithReadReceiptProtos:syncMessage.read - storageManager:self.storageManager]; - [readReceiptsProcessor processWithTransaction:transaction]; + [OWSReadReceiptManager.sharedManager processReadReceiptsFromLinkedDevice:syncMessage.read + transaction:transaction]; } else if (syncMessage.hasVerified) { DDLogInfo(@"%@ Received verification state for %@", self.tag, syncMessage.verified.destination); // TODO: Do this synchronously. @@ -900,14 +897,12 @@ NS_ASSUME_NONNULL_BEGIN } if (thread && incomingMessage) { + // In case we already have a read receipt for this new message (this happens sometimes). + [OWSReadReceiptManager.sharedManager updateIncomingMessage:incomingMessage + transaction:transaction]; + // TODO: Do this synchronously. dispatch_async(dispatch_get_main_queue(), ^{ - // In case we already have a read receipt for this new message (happens sometimes). - OWSReadReceiptsProcessor *readReceiptsProcessor = - [[OWSReadReceiptsProcessor alloc] initWithIncomingMessage:incomingMessage - storageManager:self.storageManager]; - [readReceiptsProcessor process]; - [OWSDisappearingMessagesJob becomeConsistentWithConfigurationForMessage:incomingMessage contactsManager:self.contactsManager]; diff --git a/SignalServiceKit/src/Messages/OWSReadReceiptManager.h b/SignalServiceKit/src/Messages/OWSReadReceiptManager.h index 55be7af2c..af611821a 100644 --- a/SignalServiceKit/src/Messages/OWSReadReceiptManager.h +++ b/SignalServiceKit/src/Messages/OWSReadReceiptManager.h @@ -6,11 +6,14 @@ NS_ASSUME_NONNULL_BEGIN @class OWSSignalServiceProtosEnvelope; @class OWSSignalServiceProtosReceiptMessage; +@class OWSSignalServiceProtosSyncMessageRead; @class TSIncomingMessage; @class TSOutgoingMessage; @class TSThread; @class YapDatabaseReadWriteTransaction; +extern NSString *const kMessageMarkedAsReadNotification; + // There are four kinds of read receipts: // // * Read receipts that this client sends to linked @@ -26,12 +29,14 @@ NS_ASSUME_NONNULL_BEGIN // * These read receipts are saved so that they can be applied // if they arrive before the corresponding message. // -// TODO: Merge OWSReadReceiptsProcessor into this class. +// This manager is responsible for handling and emitting all four kinds. @interface OWSReadReceiptManager : NSObject - (instancetype)init NS_UNAVAILABLE; + (instancetype)sharedManager; +#pragma mark - Sender/Recipient Read Receipts + // This method should be called when we receive a read receipt // from a user to whom we have sent a message. // @@ -42,6 +47,16 @@ NS_ASSUME_NONNULL_BEGIN - (void)updateOutgoingMessageFromLinkedDevice:(TSOutgoingMessage *)message transaction:(YapDatabaseReadWriteTransaction *)transaction; +#pragma mark - Linked Device Read Receipts + +- (void)processReadReceiptsFromLinkedDevice:(NSArray *)readReceiptProtos + transaction:(YapDatabaseReadWriteTransaction *)transaction; + +- (void)updateIncomingMessage:(TSIncomingMessage *)message + transaction:(YapDatabaseReadWriteTransaction *)transaction; + +#pragma mark - Locally Read + // This method cues this manager: // // * ...to inform the sender that this message was read (if read receipts diff --git a/SignalServiceKit/src/Messages/OWSReadReceiptManager.m b/SignalServiceKit/src/Messages/OWSReadReceiptManager.m index d5ecca6a3..872c793f9 100644 --- a/SignalServiceKit/src/Messages/OWSReadReceiptManager.m +++ b/SignalServiceKit/src/Messages/OWSReadReceiptManager.m @@ -3,8 +3,9 @@ // #import "OWSReadReceiptManager.h" +#import "NSNotificationCenter+OWS.h" +#import "OWSLinkedDeviceReadReceipt.h" #import "OWSMessageSender.h" -#import "OWSReadReceipt.h" #import "OWSReadReceiptsForLinkedDevicesMessage.h" #import "OWSReadReceiptsForSenderMessage.h" #import "OWSSignalServiceProtos.pb.h" @@ -17,6 +18,8 @@ NS_ASSUME_NONNULL_BEGIN +NSString *const kMessageMarkedAsReadNotification = @"kMessageMarkedAsReadNotification"; + @interface TSRecipientReadReceipt : TSYapDatabaseObject @property (nonatomic, readonly) uint64_t sentTimestamp; @@ -115,7 +118,7 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE // we will send to our linked devices. // // Should only be accessed while synchronized on the OWSReadReceiptManager. -@property (nonatomic, readonly) NSMutableDictionary *toLinkedDevicesReadReceiptMap; +@property (nonatomic, readonly) NSMutableDictionary *toLinkedDevicesReadReceiptMap; // A map of "recipient id"-to-"timestamp list" for read receipts that // we will send to senders. @@ -211,7 +214,7 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE // Process read receipts every N seconds. // - // We want a value high enough to allow us to effectively deduplicate, + // We want a value high enough to allow us to effectively de-duplicate, // read receipts without being so high that we risk not sending read // receipts due to app exit. const CGFloat kProcessingFrequencySeconds = 3.f; @@ -288,46 +291,10 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - NSMutableArray> *interactions = [NSMutableArray new]; - - [[TSDatabaseView unseenDatabaseViewExtension:transaction] - enumerateRowsInGroup:thread.uniqueId - usingBlock:^(NSString *collection, - NSString *key, - id object, - id metadata, - NSUInteger index, - BOOL *stop) { - - if (![object conformsToProtocol:@protocol(OWSReadTracking)]) { - OWSFail( - @"Expected to conform to OWSReadTracking: object with class: %@ collection: %@ " - @"key: %@", - [object class], - collection, - key); - return; - } - id possiblyRead = (id)object; - - if (possiblyRead.timestampForSorting > timestamp) { - *stop = YES; - return; - } - - OWSAssert(!possiblyRead.read); - if (!possiblyRead.read) { - [interactions addObject:possiblyRead]; - } - }]; - - if (interactions.count < 1) { - return; - } - DDLogError(@"Marking %zd messages as read.", interactions.count); - for (id possiblyRead in interactions) { - [possiblyRead markAsReadWithTransaction:transaction sendReadReceipt:YES updateExpiration:YES]; - } + [self markAsReadBeforeTimestamp:timestamp + thread:thread + wasLocal:YES + transaction:transaction]; }]; }); } @@ -343,10 +310,10 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE NSString *messageAuthorId = message.messageAuthorId; OWSAssert(messageAuthorId.length > 0); - OWSReadReceipt *newReadReceipt = - [[OWSReadReceipt alloc] initWithSenderId:messageAuthorId timestamp:message.timestamp]; + OWSLinkedDeviceReadReceipt *newReadReceipt = + [[OWSLinkedDeviceReadReceipt alloc] initWithSenderId:messageAuthorId timestamp:message.timestamp]; - OWSReadReceipt *_Nullable oldReadReceipt = self.toLinkedDevicesReadReceiptMap[threadUniqueId]; + OWSLinkedDeviceReadReceipt *_Nullable oldReadReceipt = self.toLinkedDevicesReadReceiptMap[threadUniqueId]; if (oldReadReceipt && oldReadReceipt.timestamp > newReadReceipt.timestamp) { // If there's an existing read receipt for the same thread with // a newer timestamp, discard the new read receipt. @@ -445,6 +412,148 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE [TSRecipientReadReceipt removeRecipientIdsForTimestamp:message.timestamp transaction:transaction]; } +#pragma mark - Linked Device Read Receipts + +- (void)updateIncomingMessage:(TSIncomingMessage *)message + transaction:(YapDatabaseReadWriteTransaction *)transaction +{ + OWSAssert(message); + OWSAssert(transaction); + + NSString *senderId = message.messageAuthorId; + uint64_t timestamp = message.timestamp; + if (senderId.length < 1 || timestamp < 1) { + OWSFail(@"%@ Invalid incoming message: %@ %llu", self.tag, senderId, timestamp); + return; + } + + OWSLinkedDeviceReadReceipt *_Nullable readReceipt = [OWSLinkedDeviceReadReceipt linkedDeviceReadReceiptWithSenderId:senderId + timestamp:timestamp]; + if (!readReceipt) { + return; + } + [message markAsReadWithTransaction:transaction sendReadReceipt:NO updateExpiration:YES]; + [readReceipt removeWithTransaction:transaction]; + + dispatch_async(dispatch_get_main_queue(), ^{ + [[NSNotificationCenter defaultCenter] + postNotificationNameAsync:kMessageMarkedAsReadNotification + object:message]; + }); +} + +- (void)processReadReceiptsFromLinkedDevice:(NSArray *)readReceiptProtos + transaction:(YapDatabaseReadWriteTransaction *)transaction +{ + OWSAssert(readReceiptProtos); + OWSAssert(transaction); + + for (OWSSignalServiceProtosSyncMessageRead *readReceiptProto in readReceiptProtos) { + NSString *_Nullable senderId = readReceiptProto.sender; + uint64_t timestamp = readReceiptProto.timestamp; + BOOL isValid = senderId.length > 0 && timestamp > 0; + if (!isValid) { + continue; + } + + NSArray *messages = (NSArray *) [TSInteraction interactionsWithTimestamp:timestamp + ofClass:[TSIncomingMessage class] + withTransaction:transaction]; + if (messages.count > 0) { + for (TSIncomingMessage *message in messages) { + OWSAssert([message isKindOfClass:[TSIncomingMessage class]]); + + [self markAsReadOnLinkedDevice:message + transaction:transaction]; + } + } else { + // Received read receipt for unknown incoming message. + // Persist in case we receive the incoming message later. + OWSLinkedDeviceReadReceipt *readReceipt = [[OWSLinkedDeviceReadReceipt alloc] initWithSenderId:senderId timestamp:timestamp]; + [readReceipt saveWithTransaction:transaction]; + } + } +} + +- (void)markAsReadOnLinkedDevice:(TSIncomingMessage *)message + transaction:(YapDatabaseReadWriteTransaction *)transaction +{ + OWSAssert(message); + OWSAssert(transaction); + + [self markAsReadBeforeTimestamp:message.timestamp + thread:message.thread + wasLocal:NO + transaction:transaction]; +} + +#pragma mark - Mark As Read + +- (void)markAsReadBeforeTimestamp:(uint64_t)timestamp + thread:(TSThread *)thread + wasLocal:(BOOL)wasLocal + transaction:(YapDatabaseReadWriteTransaction *)transaction +{ + OWSAssert(timestamp > 0); + OWSAssert(thread); + OWSAssert(transaction); + + NSMutableArray> *interactions = [NSMutableArray new]; + + [[TSDatabaseView unseenDatabaseViewExtension:transaction] + enumerateRowsInGroup:thread.uniqueId + usingBlock:^(NSString *collection, + NSString *key, + id object, + id metadata, + NSUInteger index, + BOOL *stop) { + + if (![object conformsToProtocol:@protocol(OWSReadTracking)]) { + OWSFail( + @"Expected to conform to OWSReadTracking: object with class: %@ collection: %@ " + @"key: %@", + [object class], + collection, + key); + return; + } + id possiblyRead = (id)object; + + if (possiblyRead.timestampForSorting > timestamp) { + *stop = YES; + return; + } + + OWSAssert(!possiblyRead.read); + if (!possiblyRead.read) { + [interactions addObject:possiblyRead]; + } + }]; + + if (interactions.count < 1) { + return; + } + + if (wasLocal) { + DDLogError(@"Marking %zd messages as read locally.", interactions.count); + } else { + DDLogError(@"Marking %zd messages as read by linked device.", interactions.count); + } + for (id possiblyRead in interactions) { + [possiblyRead markAsReadWithTransaction:transaction sendReadReceipt:wasLocal updateExpiration:YES]; + + if ([possiblyRead isKindOfClass:[TSIncomingMessage class]]) { + TSIncomingMessage *incomingMessage = (TSIncomingMessage *)possiblyRead; + dispatch_async(dispatch_get_main_queue(), ^{ + [[NSNotificationCenter defaultCenter] + postNotificationNameAsync:kMessageMarkedAsReadNotification + object:incomingMessage]; + }); + } + } +} + #pragma mark - Settings - (void)prepareCachedValues diff --git a/SignalServiceKit/src/Storage/TSStorageManager.m b/SignalServiceKit/src/Storage/TSStorageManager.m index 898432694..19828b785 100644 --- a/SignalServiceKit/src/Storage/TSStorageManager.m +++ b/SignalServiceKit/src/Storage/TSStorageManager.m @@ -9,7 +9,6 @@ #import "OWSFailedAttachmentDownloadsJob.h" #import "OWSFailedMessagesJob.h" #import "OWSIncomingMessageFinder.h" -#import "OWSReadReceipt.h" #import "SignalRecipient.h" #import "TSAttachmentStream.h" #import "TSDatabaseSecondaryIndexes.h" @@ -332,10 +331,9 @@ void setDatabaseInitialized() [TSDatabaseView asyncRegisterThreadOutgoingMessagesDatabaseView]; [TSDatabaseView asyncRegisterThreadSpecialMessagesDatabaseView]; - // Register extensions which aren't essential for rendering threads async + // Register extensions which aren't essential for rendering threads async. [[OWSIncomingMessageFinder new] asyncRegisterExtension]; [TSDatabaseView asyncRegisterSecondaryDevicesDatabaseView]; - [OWSReadReceipt asyncRegisterIndexOnSenderIdAndTimestampWithDatabase:self.database]; [OWSDisappearingMessagesFinder asyncRegisterDatabaseExtensions:self]; OWSFailedMessagesJob *failedMessagesJob = [[OWSFailedMessagesJob alloc] initWithStorageManager:self]; [failedMessagesJob asyncRegisterDatabaseExtensions]; From ee13084d5c0f734ec0b1c5c3e1433ba878bd9a38 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Wed, 27 Sep 2017 14:05:21 -0400 Subject: [PATCH 2/2] Respond to CR. // FREEBIE --- Signal/src/network/PushManager.m | 2 +- .../src/Devices/OWSLinkedDeviceReadReceipt.h | 6 ++-- .../src/Devices/OWSLinkedDeviceReadReceipt.m | 13 ++++--- .../src/Devices/OWSRecordTranscriptJob.m | 3 +- .../src/Messages/OWSMessageManager.m | 4 +-- .../src/Messages/OWSReadReceiptManager.h | 10 +++--- .../src/Messages/OWSReadReceiptManager.m | 36 +++++++++---------- .../src/Network/API/OWSUploadingService.m | 14 ++++---- SignalServiceKit/src/Storage/TSDatabaseView.m | 10 +++--- 9 files changed, 50 insertions(+), 48 deletions(-) diff --git a/Signal/src/network/PushManager.m b/Signal/src/network/PushManager.m index c6f8ed2a2..9481540ca 100644 --- a/Signal/src/network/PushManager.m +++ b/Signal/src/network/PushManager.m @@ -85,7 +85,7 @@ NSString *const Signal_Message_MarkAsRead_Identifier = @"Signal_Message_MarkAsRe [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleMessageRead:) - name:kMessageMarkedAsReadNotification + name:kIncomingMessageMarkedAsReadNotification object:nil]; return self; diff --git a/SignalServiceKit/src/Devices/OWSLinkedDeviceReadReceipt.h b/SignalServiceKit/src/Devices/OWSLinkedDeviceReadReceipt.h index 90a53c6c5..8a4728c56 100644 --- a/SignalServiceKit/src/Devices/OWSLinkedDeviceReadReceipt.h +++ b/SignalServiceKit/src/Devices/OWSLinkedDeviceReadReceipt.h @@ -13,8 +13,10 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithSenderId:(NSString *)senderId timestamp:(uint64_t)timestamp; -+ (nullable OWSLinkedDeviceReadReceipt *)linkedDeviceReadReceiptWithSenderId:(NSString *)senderId - timestamp:(uint64_t)timestamp; ++ (nullable OWSLinkedDeviceReadReceipt *)findLinkedDeviceReadReceiptWithSenderId:(NSString *)senderId + timestamp:(uint64_t)timestamp + transaction: + (YapDatabaseReadTransaction *)transaction; @end diff --git a/SignalServiceKit/src/Devices/OWSLinkedDeviceReadReceipt.m b/SignalServiceKit/src/Devices/OWSLinkedDeviceReadReceipt.m index eb2d576cb..c07f98bbd 100644 --- a/SignalServiceKit/src/Devices/OWSLinkedDeviceReadReceipt.m +++ b/SignalServiceKit/src/Devices/OWSLinkedDeviceReadReceipt.m @@ -27,13 +27,18 @@ NS_ASSUME_NONNULL_BEGIN { OWSAssert(senderId.length > 0 && timestamp > 0); - return [NSString stringWithFormat:@"%@ %llu", senderId, timestamp]; + return [NSString stringWithFormat:@"%@-%llu", senderId, timestamp]; } -+ (nullable OWSLinkedDeviceReadReceipt *)linkedDeviceReadReceiptWithSenderId:(NSString *)senderId - timestamp:(uint64_t)timestamp ++ (nullable OWSLinkedDeviceReadReceipt *)findLinkedDeviceReadReceiptWithSenderId:(NSString *)senderId + timestamp:(uint64_t)timestamp + transaction: + (YapDatabaseReadTransaction *)transaction { - return [OWSLinkedDeviceReadReceipt fetchObjectWithUniqueID:[self uniqueIdForSenderId:senderId timestamp:timestamp]]; + OWSAssert(transaction); + + return [OWSLinkedDeviceReadReceipt fetchObjectWithUniqueID:[self uniqueIdForSenderId:senderId timestamp:timestamp] + transaction:transaction]; } #pragma mark - Logging diff --git a/SignalServiceKit/src/Devices/OWSRecordTranscriptJob.m b/SignalServiceKit/src/Devices/OWSRecordTranscriptJob.m index cd754520b..50b603c83 100644 --- a/SignalServiceKit/src/Devices/OWSRecordTranscriptJob.m +++ b/SignalServiceKit/src/Devices/OWSRecordTranscriptJob.m @@ -113,7 +113,8 @@ NS_ASSUME_NONNULL_BEGIN sentAt:transcript.expirationStartedAt transaction:transaction]; - [self.readReceiptManager updateOutgoingMessageFromLinkedDevice:outgoingMessage transaction:transaction]; + [self.readReceiptManager applyEarlyReadReceiptsForOutgoingMessageFromLinkedDevice:outgoingMessage + transaction:transaction]; [attachmentsProcessor fetchAttachmentsForMessage:outgoingMessage diff --git a/SignalServiceKit/src/Messages/OWSMessageManager.m b/SignalServiceKit/src/Messages/OWSMessageManager.m index 258f4909e..90d7539f0 100644 --- a/SignalServiceKit/src/Messages/OWSMessageManager.m +++ b/SignalServiceKit/src/Messages/OWSMessageManager.m @@ -898,8 +898,8 @@ NS_ASSUME_NONNULL_BEGIN if (thread && incomingMessage) { // In case we already have a read receipt for this new message (this happens sometimes). - [OWSReadReceiptManager.sharedManager updateIncomingMessage:incomingMessage - transaction:transaction]; + [OWSReadReceiptManager.sharedManager applyEarlyReadReceiptsForIncomingMessage:incomingMessage + transaction:transaction]; // TODO: Do this synchronously. dispatch_async(dispatch_get_main_queue(), ^{ diff --git a/SignalServiceKit/src/Messages/OWSReadReceiptManager.h b/SignalServiceKit/src/Messages/OWSReadReceiptManager.h index af611821a..ad925c6f1 100644 --- a/SignalServiceKit/src/Messages/OWSReadReceiptManager.h +++ b/SignalServiceKit/src/Messages/OWSReadReceiptManager.h @@ -12,7 +12,7 @@ NS_ASSUME_NONNULL_BEGIN @class TSThread; @class YapDatabaseReadWriteTransaction; -extern NSString *const kMessageMarkedAsReadNotification; +extern NSString *const kIncomingMessageMarkedAsReadNotification; // There are four kinds of read receipts: // @@ -44,16 +44,16 @@ extern NSString *const kMessageMarkedAsReadNotification; - (void)processReadReceiptsFromRecipient:(OWSSignalServiceProtosReceiptMessage *)receiptMessage envelope:(OWSSignalServiceProtosEnvelope *)envelope; -- (void)updateOutgoingMessageFromLinkedDevice:(TSOutgoingMessage *)message - transaction:(YapDatabaseReadWriteTransaction *)transaction; +- (void)applyEarlyReadReceiptsForOutgoingMessageFromLinkedDevice:(TSOutgoingMessage *)message + transaction:(YapDatabaseReadWriteTransaction *)transaction; #pragma mark - Linked Device Read Receipts - (void)processReadReceiptsFromLinkedDevice:(NSArray *)readReceiptProtos transaction:(YapDatabaseReadWriteTransaction *)transaction; -- (void)updateIncomingMessage:(TSIncomingMessage *)message - transaction:(YapDatabaseReadWriteTransaction *)transaction; +- (void)applyEarlyReadReceiptsForIncomingMessage:(TSIncomingMessage *)message + transaction:(YapDatabaseReadWriteTransaction *)transaction; #pragma mark - Locally Read diff --git a/SignalServiceKit/src/Messages/OWSReadReceiptManager.m b/SignalServiceKit/src/Messages/OWSReadReceiptManager.m index 872c793f9..bdabd2eac 100644 --- a/SignalServiceKit/src/Messages/OWSReadReceiptManager.m +++ b/SignalServiceKit/src/Messages/OWSReadReceiptManager.m @@ -18,7 +18,7 @@ NS_ASSUME_NONNULL_BEGIN -NSString *const kMessageMarkedAsReadNotification = @"kMessageMarkedAsReadNotification"; +NSString *const kIncomingMessageMarkedAsReadNotification = @"kIncomingMessageMarkedAsReadNotification"; @interface TSRecipientReadReceipt : TSYapDatabaseObject @@ -315,8 +315,8 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE OWSLinkedDeviceReadReceipt *_Nullable oldReadReceipt = self.toLinkedDevicesReadReceiptMap[threadUniqueId]; if (oldReadReceipt && oldReadReceipt.timestamp > newReadReceipt.timestamp) { - // If there's an existing read receipt for the same thread with - // a newer timestamp, discard the new read receipt. + // If there's an existing "linked device" read receipt for the same thread with + // a newer timestamp, discard this "linked device" read receipt. DDLogVerbose(@"%@ Ignoring redundant read receipt for linked devices.", self.tag); } else { DDLogVerbose(@"%@ Enqueuing read receipt for linked devices.", self.tag); @@ -389,8 +389,8 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE }); } -- (void)updateOutgoingMessageFromLinkedDevice:(TSOutgoingMessage *)message - transaction:(YapDatabaseReadWriteTransaction *)transaction +- (void)applyEarlyReadReceiptsForOutgoingMessageFromLinkedDevice:(TSOutgoingMessage *)message + transaction:(YapDatabaseReadWriteTransaction *)transaction { OWSAssert(message); OWSAssert(transaction); @@ -414,8 +414,8 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE #pragma mark - Linked Device Read Receipts -- (void)updateIncomingMessage:(TSIncomingMessage *)message - transaction:(YapDatabaseReadWriteTransaction *)transaction +- (void)applyEarlyReadReceiptsForIncomingMessage:(TSIncomingMessage *)message + transaction:(YapDatabaseReadWriteTransaction *)transaction { OWSAssert(message); OWSAssert(transaction); @@ -427,19 +427,18 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE return; } - OWSLinkedDeviceReadReceipt *_Nullable readReceipt = [OWSLinkedDeviceReadReceipt linkedDeviceReadReceiptWithSenderId:senderId - timestamp:timestamp]; + OWSLinkedDeviceReadReceipt *_Nullable readReceipt = + [OWSLinkedDeviceReadReceipt findLinkedDeviceReadReceiptWithSenderId:senderId + timestamp:timestamp + transaction:transaction]; if (!readReceipt) { return; } [message markAsReadWithTransaction:transaction sendReadReceipt:NO updateExpiration:YES]; [readReceipt removeWithTransaction:transaction]; - - dispatch_async(dispatch_get_main_queue(), ^{ - [[NSNotificationCenter defaultCenter] - postNotificationNameAsync:kMessageMarkedAsReadNotification - object:message]; - }); + + [[NSNotificationCenter defaultCenter] postNotificationNameAsync:kIncomingMessageMarkedAsReadNotification + object:message]; } - (void)processReadReceiptsFromLinkedDevice:(NSArray *)readReceiptProtos @@ -545,11 +544,8 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE if ([possiblyRead isKindOfClass:[TSIncomingMessage class]]) { TSIncomingMessage *incomingMessage = (TSIncomingMessage *)possiblyRead; - dispatch_async(dispatch_get_main_queue(), ^{ - [[NSNotificationCenter defaultCenter] - postNotificationNameAsync:kMessageMarkedAsReadNotification - object:incomingMessage]; - }); + [[NSNotificationCenter defaultCenter] postNotificationNameAsync:kIncomingMessageMarkedAsReadNotification + object:incomingMessage]; } } } diff --git a/SignalServiceKit/src/Network/API/OWSUploadingService.m b/SignalServiceKit/src/Network/API/OWSUploadingService.m index fc3e4ca19..97127bdb2 100644 --- a/SignalServiceKit/src/Network/API/OWSUploadingService.m +++ b/SignalServiceKit/src/Network/API/OWSUploadingService.m @@ -168,13 +168,13 @@ static const CGFloat kAttachmentUploadProgressTheta = 0.001f; - (void)fireProgressNotification:(CGFloat)progress attachmentId:(NSString *)attachmentId { - NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; - [notificationCenter postNotificationNameAsync:kAttachmentUploadProgressNotification - object:nil - userInfo:@{ - kAttachmentUploadProgressKey : @(progress), - kAttachmentUploadAttachmentIDKey : attachmentId - }]; + NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; + [notificationCenter postNotificationNameAsync:kAttachmentUploadProgressNotification + object:nil + userInfo:@{ + kAttachmentUploadProgressKey : @(progress), + kAttachmentUploadAttachmentIDKey : attachmentId + }]; } #pragma mark - Logging diff --git a/SignalServiceKit/src/Storage/TSDatabaseView.m b/SignalServiceKit/src/Storage/TSDatabaseView.m index 6d2e1b5b1..19cf4fcab 100644 --- a/SignalServiceKit/src/Storage/TSDatabaseView.m +++ b/SignalServiceKit/src/Storage/TSDatabaseView.m @@ -442,12 +442,10 @@ NSString *const TSSecondaryDevicesDatabaseViewExtensionName = @"TSSecondaryDevic asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { [TSDatabaseView.sharedInstance setAreAllAsyncRegistrationsComplete]; - dispatch_async(dispatch_get_main_queue(), ^{ - [[NSNotificationCenter defaultCenter] - postNotificationNameAsync:kNSNotificationName_DatabaseViewRegistrationComplete - object:nil - userInfo:nil]; - }); + [[NSNotificationCenter defaultCenter] + postNotificationNameAsync:kNSNotificationName_DatabaseViewRegistrationComplete + object:nil + userInfo:nil]; }]; }