Fix notification delivery after powering on a device. (#5035)
* Debugging with Notifications. * Don't run the NSE until the device is unlocked. * Let the NSE run long enough to deliver the default notification content. Turns out that exit(0) results in the notification be discarded when you have the notification filtering entitlement. * Remove debugging notifications. --------- Co-authored-by: Stefan Ceriu <stefanc@matrix.org>
This commit is contained in:
@@ -51,7 +51,12 @@ class NotificationServiceExtension: UNNotificationServiceExtension {
|
||||
appHooks = AppHooks()
|
||||
appHooks.setUp()
|
||||
|
||||
if Self.targetConfiguration == nil {
|
||||
// If the device is still locked then we can't write to the app group container and
|
||||
// the target configuration will fail. We could call exit(0) here, however with the
|
||||
// notification filtering entitlement that results in the notification being discarded
|
||||
// so we need to wait for the delegate method to be called and bail out there instead.
|
||||
if !DataProtectionManager.isDeviceLockedAfterReboot(containerURL: URL.appGroupContainerDirectory),
|
||||
Self.targetConfiguration == nil {
|
||||
Self.targetConfiguration = Target.nse.configure(logLevel: settings.logLevel,
|
||||
traceLogPacks: settings.traceLogPacks,
|
||||
sentryURL: nil,
|
||||
@@ -67,16 +72,32 @@ class NotificationServiceExtension: UNNotificationServiceExtension {
|
||||
}
|
||||
|
||||
private func handle(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) async {
|
||||
guard !DataProtectionManager.isDeviceLockedAfterReboot(containerURL: URL.appGroupContainerDirectory),
|
||||
let roomID = request.content.roomID,
|
||||
let eventID = request.content.eventID,
|
||||
let clientID = request.content.pusherNotificationClientIdentifier,
|
||||
let credentials = keychainController.restorationTokens().first(where: { $0.restorationToken.pusherNotificationClientIdentifier == clientID }) else {
|
||||
// We cannot process this notification, it might be due to one of these:
|
||||
// - Device rebooted and locked
|
||||
// - Not a Matrix notification
|
||||
// - User is not signed in
|
||||
// - NotificationID could not be resolved
|
||||
// If we skipped configuring the target it means we can't write to the app group, so we're unlikely
|
||||
// to be able to create a session (and even if we could, we would be missing the lightweightTokioRuntime),
|
||||
// so instead lets deliver the default generic notification and avoid attempting to process the notification.
|
||||
guard Self.targetConfiguration != nil else {
|
||||
// swiftlint:disable:next print_deprecation (MXLog isn't configured)
|
||||
print("Device is locked after reboot, delivering the unmodified notification.")
|
||||
return contentHandler(request.content)
|
||||
}
|
||||
|
||||
guard let roomID = request.content.roomID else {
|
||||
MXLog.error("Invalid roomID, bailing out: \(request.content)")
|
||||
return contentHandler(request.content)
|
||||
}
|
||||
|
||||
guard let eventID = request.content.eventID else {
|
||||
MXLog.error("Invalid eventID, bailing out: \(request.content)")
|
||||
return contentHandler(request.content)
|
||||
}
|
||||
|
||||
guard let clientID = request.content.pusherNotificationClientIdentifier else {
|
||||
MXLog.error("Invalid eventID, bailing out: \(request.content)")
|
||||
return contentHandler(request.content)
|
||||
}
|
||||
|
||||
guard let credentials = keychainController.restorationTokens().first(where: { $0.restorationToken.pusherNotificationClientIdentifier == clientID }) else {
|
||||
MXLog.error("Invalid credentials, bailing out: \(request.content)")
|
||||
return contentHandler(request.content)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user