From 21e9f57cbe557be599ebbfe2da5d4b2d52ba4875 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Thu, 16 Nov 2017 09:54:55 -0500 Subject: [PATCH] Imitate Android's behavior of delaying local notifications based on incoming sync messages. --- Signal/src/network/PushManager.m | 16 ++++++++++++---- SignalServiceKit/src/Devices/OWSDevice.h | 3 +++ SignalServiceKit/src/Devices/OWSDevice.m | 11 +++++++++++ .../src/Messages/OWSMessageManager.m | 3 +++ 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/Signal/src/network/PushManager.m b/Signal/src/network/PushManager.m index 6ea920a78..a4d7a8243 100644 --- a/Signal/src/network/PushManager.m +++ b/Signal/src/network/PushManager.m @@ -9,6 +9,7 @@ #import "Signal-Swift.h" #import "ThreadUtil.h" #import +#import #import #import #import @@ -440,10 +441,17 @@ NSString *const PushManagerUserInfoKeysCallBackSignalRecipientId = @"PushManager dispatch_async(dispatch_get_main_queue(), ^{ NSString *threadId = notification.userInfo[Signal_Thread_UserInfo_Key]; if (checkForCancel && threadId != nil) { - // The longer we wait, the more obsolete notifications we can suppress - - // but the more lag we introduce to notification delivery. - const CGFloat kDelaySeconds = 0.5f; - notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:kDelaySeconds]; + if ([[OWSDeviceManager sharedManager] hasReceivedSyncMessageInLastSeconds:60.f]) { + // "If you’ve heard from desktop in last minute, wait 5 seconds." + // + // This provides a window in which we can cancel notifications + // already viewed on desktop before they are presented here. + const CGFloat kDelaySeconds = 5.f; + notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:kDelaySeconds]; + } else { + notification.fireDate = [NSDate new]; + } + notification.timeZone = [NSTimeZone localTimeZone]; } diff --git a/SignalServiceKit/src/Devices/OWSDevice.h b/SignalServiceKit/src/Devices/OWSDevice.h index eba4af55c..ba4fc39cc 100644 --- a/SignalServiceKit/src/Devices/OWSDevice.h +++ b/SignalServiceKit/src/Devices/OWSDevice.h @@ -18,6 +18,9 @@ extern uint32_t const OWSDevicePrimaryDeviceId; - (BOOL)mayHaveLinkedDevices:(YapDatabaseConnection *)dbConnection; - (void)setMayHaveLinkedDevices:(BOOL)value dbConnection:(YapDatabaseConnection *)dbConnection; +- (BOOL)hasReceivedSyncMessageInLastSeconds:(NSTimeInterval)intervalSeconds; +- (void)setHasReceivedSyncMessage; + @end #pragma mark - diff --git a/SignalServiceKit/src/Devices/OWSDevice.m b/SignalServiceKit/src/Devices/OWSDevice.m index 2cccb3c69..6b6755649 100644 --- a/SignalServiceKit/src/Devices/OWSDevice.m +++ b/SignalServiceKit/src/Devices/OWSDevice.m @@ -19,6 +19,7 @@ NSString *const kTSStorageManager_MayHaveLinkedDevices = @"kTSStorageManager_May @interface OWSDeviceManager () @property (atomic, nullable) NSNumber *mayHaveLinkedDevicesCached; +@property (atomic) NSDate *lastReceivedSyncMessage; @end @@ -73,6 +74,16 @@ NSString *const kTSStorageManager_MayHaveLinkedDevices = @"kTSStorageManager_May } } +- (BOOL)hasReceivedSyncMessageInLastSeconds:(NSTimeInterval)intervalSeconds +{ + return (self.lastReceivedSyncMessage && fabs(self.lastReceivedSyncMessage.timeIntervalSinceNow) < intervalSeconds); +} + +- (void)setHasReceivedSyncMessage +{ + self.lastReceivedSyncMessage = [NSDate new]; +} + @end #pragma mark - diff --git a/SignalServiceKit/src/Messages/OWSMessageManager.m b/SignalServiceKit/src/Messages/OWSMessageManager.m index e74e898ab..6ec4b9a72 100644 --- a/SignalServiceKit/src/Messages/OWSMessageManager.m +++ b/SignalServiceKit/src/Messages/OWSMessageManager.m @@ -11,6 +11,7 @@ #import "OWSAttachmentsProcessor.h" #import "OWSBlockingManager.h" #import "OWSCallMessageHandler.h" +#import "OWSDevice.h" #import "OWSDisappearingConfigurationUpdateInfoMessage.h" #import "OWSDisappearingMessagesConfiguration.h" #import "OWSDisappearingMessagesJob.h" @@ -267,6 +268,8 @@ NS_ASSUME_NONNULL_BEGIN if (content.hasSyncMessage) { [self handleIncomingEnvelope:envelope withSyncMessage:content.syncMessage transaction:transaction]; + + [[OWSDeviceManager sharedManager] setHasReceivedSyncMessage]; } else if (content.hasDataMessage) { [self handleIncomingEnvelope:envelope withDataMessage:content.dataMessage transaction:transaction]; } else if (content.hasCallMessage) {