If a call message gets stuck, make sure it's treated as old later
Call messages delivered to the NSE have to be handled in the main app, so they're put in a synced key-value store and the app is notified. Rings are processed oldest-to-newest in case you get two calls in succession before the main app awakes. However, if this processing is interrupted, the store won't get cleared, and the app may try to process the *old* ring when it's woken up by a *new* ring. This would *still* be correct (e.g. for showing missed call notifications) except that the "age" of a ring message is calculated purely on when it makes it to the user's device, since it was assumed that it would be processed promptly. Since this is not necessarily the case in these error scenarios, this commit adds a second timestamp to track the skew between when the NSE enqueues the call message and when the main app processes it.
This commit is contained in:
parent
632029fc2f
commit
a302e7cfbc
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2021 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2022 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
@ -52,11 +52,19 @@ public class CallMessageRelay: NSObject {
|
||||
owsAssertDebug(pendingPayloads.count == 1, "Unexpectedly processing multiple messages from the NSE at once")
|
||||
|
||||
for payload in pendingPayloads {
|
||||
// Pretend we are just receiving the message now.
|
||||
// This ensures that if we process a very old ring message, it will correctly be considered "expired".
|
||||
// "This should never happen" in normal operation, but in practice we have seen it happen,
|
||||
// e.g. when there's a crash processing the queued ring message.
|
||||
let delaySecondsSinceDelivery = -(payload.enqueueTimestamp?.timeIntervalSinceNow ?? 0)
|
||||
let adjustedDeliveryTimestamp =
|
||||
payload.serverDeliveryTimestamp + UInt64(1000 * max(0, delaySecondsSinceDelivery))
|
||||
|
||||
messageManager.processEnvelope(
|
||||
payload.envelope,
|
||||
plaintextData: payload.plaintextData,
|
||||
wasReceivedByUD: payload.wasReceivedByUD,
|
||||
serverDeliveryTimestamp: payload.serverDeliveryTimestamp,
|
||||
serverDeliveryTimestamp: adjustedDeliveryTimestamp,
|
||||
shouldDiscardVisibleMessages: false,
|
||||
transaction: transaction
|
||||
)
|
||||
@ -75,7 +83,8 @@ public class CallMessageRelay: NSObject {
|
||||
envelope: envelope,
|
||||
plaintextData: plaintextData,
|
||||
wasReceivedByUD: wasReceivedByUD,
|
||||
serverDeliveryTimestamp: serverDeliveryTimestamp
|
||||
serverDeliveryTimestamp: serverDeliveryTimestamp,
|
||||
enqueueTimestamp: Date()
|
||||
)
|
||||
|
||||
try pendingCallMessageStore.setCodable(payload, key: "\(envelope.timestamp)", transaction: transaction)
|
||||
@ -87,5 +96,6 @@ public class CallMessageRelay: NSObject {
|
||||
let plaintextData: Data
|
||||
let wasReceivedByUD: Bool
|
||||
let serverDeliveryTimestamp: UInt64
|
||||
let enqueueTimestamp: Date?
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user