Handle new-style delivery receipts.

// FREEBIE
This commit is contained in:
Matthew Chen 2017-09-22 16:40:44 -04:00
parent 60738b450f
commit 25c40ea3cf
5 changed files with 59 additions and 45 deletions

View File

@ -172,7 +172,6 @@ typedef NS_ENUM(NSInteger, TSGroupMetaMessage) {
- (void)updateWithCustomMessage:(NSString *)customMessage transaction:(YapDatabaseReadWriteTransaction *)transaction;
- (void)updateWithCustomMessage:(NSString *)customMessage;
- (void)updateWithWasDeliveredWithTransaction:(YapDatabaseReadWriteTransaction *)transaction;
- (void)updateWithWasDelivered;
- (void)updateWithWasSentFromLinkedDeviceWithTransaction:(YapDatabaseReadWriteTransaction *)transaction;
- (void)updateWithSingleGroupRecipient:(NSString *)singleGroupRecipient
transaction:(YapDatabaseReadWriteTransaction *)transaction;

View File

@ -317,13 +317,6 @@ NSString *const kTSOutgoingMessageSentRecipientAll = @"kTSOutgoingMessageSentRec
}];
}
- (void)updateWithWasDelivered
{
[self.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[self updateWithWasDeliveredWithTransaction:transaction];
}];
}
- (void)updateWithWasSentFromLinkedDeviceWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
OWSAssert(transaction);

View File

@ -186,23 +186,40 @@ NS_ASSUME_NONNULL_BEGIN
OWSAssert(envelope);
OWSAssert(transaction);
NSArray<TSOutgoingMessage *> *messages
= (NSArray<TSOutgoingMessage *> *)[TSInteraction interactionsWithTimestamp:envelope.timestamp
ofClass:[TSOutgoingMessage class]
withTransaction:transaction];
if (messages.count < 1) {
// Desktop currently sends delivery receipts for "unpersisted" messages
// like group updates, so these errors are expected to a certain extent.
DDLogInfo(@"%@ Missing message for delivery receipt: %llu", self.tag, envelope.timestamp);
} else {
if (messages.count > 1) {
DDLogInfo(@"%@ More than one message (%zd) for delivery receipt: %llu",
self.tag,
messages.count,
envelope.timestamp);
}
for (TSOutgoingMessage *outgoingMessage in messages) {
[outgoingMessage updateWithWasDeliveredWithTransaction:transaction];
[self processDeliveryReceipts:envelope.source
sentTimestamps:@[
@(envelope.timestamp),
]
transaction:transaction];
}
- (void)processDeliveryReceipts:(NSString *)recipientId
sentTimestamps:(NSArray<NSNumber *> *)sentTimestamps
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
OWSAssert(recipientId);
OWSAssert(sentTimestamps);
OWSAssert(transaction);
for (NSNumber *nsTimestamp in sentTimestamps) {
uint64_t timestamp = [nsTimestamp unsignedLongLongValue];
NSArray<TSOutgoingMessage *> *messages
= (NSArray<TSOutgoingMessage *> *)[TSInteraction interactionsWithTimestamp:timestamp
ofClass:[TSOutgoingMessage class]
withTransaction:transaction];
if (messages.count < 1) {
// Desktop currently sends delivery receipts for "unpersisted" messages
// like group updates, so these errors are expected to a certain extent.
DDLogInfo(@"%@ Missing message for delivery receipt: %llu", self.tag, timestamp);
} else {
if (messages.count > 1) {
DDLogInfo(
@"%@ More than one message (%zd) for delivery receipt: %llu", self.tag, messages.count, timestamp);
}
for (TSOutgoingMessage *outgoingMessage in messages) {
[outgoingMessage updateWithWasDeliveredWithTransaction:transaction];
}
}
}
}
@ -243,7 +260,7 @@ NS_ASSUME_NONNULL_BEGIN
} else if (content.hasNullMessage) {
DDLogInfo(@"%@ Received null message.", self.tag);
} else if (content.hasReceiptMessage) {
[self handleIncomingEnvelope:envelope withReceiptMessage:content.receiptMessage];
[self handleIncomingEnvelope:envelope withReceiptMessage:content.receiptMessage transaction:transaction];
} else {
DDLogWarn(@"%@ Ignoring envelope. Content with no known payload", self.tag);
}
@ -340,17 +357,29 @@ NS_ASSUME_NONNULL_BEGIN
- (void)handleIncomingEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
withReceiptMessage:(OWSSignalServiceProtosReceiptMessage *)receiptMessage
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
OWSAssert(envelope);
OWSAssert(receiptMessage);
OWSAssert(transaction);
PBArray *messageTimestamps = receiptMessage.timestamp;
NSMutableArray<NSNumber *> *sentTimestamps = [NSMutableArray new];
for (int i = 0; i < messageTimestamps.count; i++) {
UInt64 timestamp = [messageTimestamps uint64AtIndex:i];
[sentTimestamps addObject:@(timestamp)];
}
switch (receiptMessage.type) {
case OWSSignalServiceProtosReceiptMessageTypeDelivery:
DDLogInfo(@"%@ Ignoring receipt message with delivery receipt.", self.tag);
DDLogVerbose(@"%@ Processing receipt message with delivery receipts.", self.tag);
[self processDeliveryReceipts:envelope.source sentTimestamps:sentTimestamps transaction:transaction];
return;
case OWSSignalServiceProtosReceiptMessageTypeRead:
DDLogVerbose(@"%@ Processing receipt message with read receipts.", self.tag);
[OWSReadReceiptManager.sharedManager processReadReceiptsFromRecipient:receiptMessage envelope:envelope];
[OWSReadReceiptManager.sharedManager processReadReceiptsFromRecipientId:envelope.source
sentTimestamps:sentTimestamps
readTimestamp:envelope.timestamp];
break;
default:
DDLogInfo(@"%@ Ignoring receipt message of unknown type: %d.", self.tag, (int)receiptMessage.type);

View File

@ -4,8 +4,6 @@
NS_ASSUME_NONNULL_BEGIN
@class OWSSignalServiceProtosEnvelope;
@class OWSSignalServiceProtosReceiptMessage;
@class OWSSignalServiceProtosSyncMessageRead;
@class TSIncomingMessage;
@class TSOutgoingMessage;
@ -41,8 +39,9 @@ extern NSString *const kIncomingMessageMarkedAsReadNotification;
// from a user to whom we have sent a message.
//
// This method can be called from any thread.
- (void)processReadReceiptsFromRecipient:(OWSSignalServiceProtosReceiptMessage *)receiptMessage
envelope:(OWSSignalServiceProtosEnvelope *)envelope;
- (void)processReadReceiptsFromRecipientId:(NSString *)recipientId
sentTimestamps:(NSArray<NSNumber *> *)sentTimestamps
readTimestamp:(uint64_t)readTimestamp;
- (void)applyEarlyReadReceiptsForOutgoingMessageFromLinkedDevice:(TSOutgoingMessage *)message
transaction:(YapDatabaseReadWriteTransaction *)transaction;

View File

@ -340,28 +340,22 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
#pragma mark - Read Receipts From Recipient
- (void)processReadReceiptsFromRecipient:(OWSSignalServiceProtosReceiptMessage *)receiptMessage
envelope:(OWSSignalServiceProtosEnvelope *)envelope
- (void)processReadReceiptsFromRecipientId:(NSString *)recipientId
sentTimestamps:(NSArray<NSNumber *> *)sentTimestamps
readTimestamp:(uint64_t)readTimestamp
{
OWSAssert(receiptMessage);
OWSAssert(envelope);
OWSAssert(receiptMessage.type == OWSSignalServiceProtosReceiptMessageTypeRead);
OWSAssert(recipientId.length > 0);
OWSAssert(sentTimestamps);
if (![self areReadReceiptsEnabled]) {
DDLogInfo(@"%@ Ignoring incoming receipt message as read receipts are disabled.", self.tag);
return;
}
NSString *recipientId = envelope.source;
OWSAssert(recipientId.length > 0);
PBArray *sentTimestamps = receiptMessage.timestamp;
UInt64 readTimestamp = envelope.timestamp;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
for (int i = 0; i < sentTimestamps.count; i++) {
UInt64 sentTimestamp = [sentTimestamps uint64AtIndex:i];
for (NSNumber *nsSentTimestamp in sentTimestamps) {
UInt64 sentTimestamp = [nsSentTimestamp unsignedLongLongValue];
NSArray<TSOutgoingMessage *> *messages
= (NSArray<TSOutgoingMessage *> *)[TSInteraction interactionsWithTimestamp:sentTimestamp