From 81f1a946f65bae11169b6d34db07ff63aa1bca62 Mon Sep 17 00:00:00 2001 From: David Langley Date: Tue, 16 Nov 2021 12:00:20 +0000 Subject: [PATCH 1/7] Ignore badge updates for virtual rooms. --- Config/BuildSettings.swift | 2 ++ RiotNSE/NotificationService.swift | 49 ++++++++++++++++++++++++++----- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/Config/BuildSettings.swift b/Config/BuildSettings.swift index 2d080c6d2..4c7927f5e 100644 --- a/Config/BuildSettings.swift +++ b/Config/BuildSettings.swift @@ -154,6 +154,8 @@ final class BuildSettings: NSObject { } static let stunServerFallbackUrlString: String? = "stun:turn.matrix.org" + // For use in conjunction with virtual rooms. Events from virtual rooms should not be reflected in badge count for unread messages. + static let ignoreBadgeUpdatesForVirtualRooms = true // MARK: - Public rooms Directory #warning("Unused build setting: should this be implemented in ShowDirectory?") diff --git a/RiotNSE/NotificationService.swift b/RiotNSE/NotificationService.swift index 0b2ff4758..76192fee7 100644 --- a/RiotNSE/NotificationService.swift +++ b/RiotNSE/NotificationService.swift @@ -53,6 +53,12 @@ class NotificationService: UNNotificationServiceExtension { private lazy var configuration: Configurable = { return CommonConfiguration() }() + private lazy var mxRestClient: MXRestClient? = { + guard let userAccount = userAccount else { + return nil + } + return MXRestClient(credentials: userAccount.mxCredentials, unrecognizedCertificateHandler: nil) + }() private static var isLoggerInitialized: Bool = false private lazy var pushGatewayRestClient: MXPushGatewayRestClient = { let url = URL(string: BuildSettings.serverConfigSygnalAPIUrlString)! @@ -222,7 +228,7 @@ class NotificationService: UNNotificationServiceExtension { return } - self.notificationContent(forEvent: event, forAccount: userAccount) { (notificationContent) in + self.notificationContent(forEvent: event, forAccount: userAccount) { (notificationContent, ignoreBadgeUpdate) in var isUnwantedNotification = false // Modify the notification content here... @@ -240,6 +246,10 @@ class NotificationService: UNNotificationServiceExtension { isUnwantedNotification = true } + if ignoreBadgeUpdate { + content.badge = nil + } + if self.ongoingVoIPPushRequests[event.eventId] == true { // modify the best attempt content, to be able to use in the future self.bestAttemptContents[event.eventId] = content @@ -279,10 +289,10 @@ class NotificationService: UNNotificationServiceExtension { MXLog.debug("--------------------------------------------------------------------------------") } - private func notificationContent(forEvent event: MXEvent, forAccount account: MXKAccount, onComplete: @escaping (UNNotificationContent?) -> Void) { + private func notificationContent(forEvent event: MXEvent, forAccount account: MXKAccount, onComplete: @escaping (UNNotificationContent?, Bool) -> Void) { guard let content = event.content, content.count > 0 else { MXLog.debug("[NotificationService] notificationContentForEvent: empty event content") - onComplete(nil) + onComplete(nil, false) return } @@ -298,7 +308,7 @@ class NotificationService: UNNotificationServiceExtension { var notificationTitle: String? var notificationBody: String? var additionalUserInfo: [AnyHashable: Any]? - + var ignoreBadgeUpdate = false var threadIdentifier: String? = roomId let currentUserId = account.mxCredentials.userId let roomDisplayName = roomSummary?.displayname @@ -322,6 +332,10 @@ class NotificationService: UNNotificationServiceExtension { if let callInviteContent = MXCallInviteEventContent(fromJSON: event.content), callInviteContent.lifetime > event.age, (callInviteContent.lifetime - event.age) > UInt(NSE.Constants.timeNeededToSendVoIPPushes * MSEC_PER_SEC) { + if BuildSettings.ignoreBadgeUpdatesForVirtualRooms { + self.sendReadReceipt(forEvent: event) + ignoreBadgeUpdate = true + } self.sendVoipPush(forEvent: event) } else { MXLog.debug("[NotificationService] notificationContent: Do not attempt to send a VoIP push, there is not enough time to process it.") @@ -351,7 +365,7 @@ class NotificationService: UNNotificationServiceExtension { #warning("In practice, this only hides the notification's content. An empty notification may be less useful in this instance?") // Ignore this notif. MXLog.debug("[NotificationService] notificationContentForEvent: Ignore non highlighted notif in mentions only room") - onComplete(nil) + onComplete(nil, false) return } } @@ -483,7 +497,7 @@ class NotificationService: UNNotificationServiceExtension { guard notificationBody != nil else { MXLog.debug("[NotificationService] notificationContentForEvent: notificationBody is nil") - onComplete(nil) + onComplete(nil, false) return } @@ -496,10 +510,10 @@ class NotificationService: UNNotificationServiceExtension { additionalInfo: additionalUserInfo) MXLog.debug("[NotificationService] notificationContentForEvent: Calling onComplete.") - onComplete(notificationContent) + onComplete(notificationContent, ignoreBadgeUpdate) case .failure(let error): MXLog.debug("[NotificationService] notificationContentForEvent: error: \(error)") - onComplete(nil) + onComplete(nil, false) } }) } @@ -710,4 +724,23 @@ class NotificationService: UNNotificationServiceExtension { } } + private func sendReadReceipt(forEvent event: MXEvent) { + guard let mxRestClient = mxRestClient else { + MXLog.error("[NotificationService] sendVoipReadReceipt: Missing mxRestClient for read receipt request.") + return + } + guard let eventId = event.eventId, + let roomId = event.roomId else { + MXLog.error("[NotificationService] sendVoipReadReceipt: Event information missing for read receipt request.") + return + } + + mxRestClient.sendReadReceipt(toRoom: roomId, forEvent: eventId) { response in + if response.isSuccess { + MXLog.debug("[NotificationService] sendVoipReadReceipt: Read receipt send successfully.") + } else if let error = response.error { + MXLog.error("[NotificationService] sendVoipReadReceipt: Read receipt send failed with error \(error).") + } + } + } } From d49b65b22cf5b754f8c78678f8f57679f13485fc Mon Sep 17 00:00:00 2001 From: David Langley Date: Tue, 16 Nov 2021 12:19:35 +0000 Subject: [PATCH 2/7] changelog --- changelog.d/5155.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5155.bugfix diff --git a/changelog.d/5155.bugfix b/changelog.d/5155.bugfix new file mode 100644 index 000000000..0d821ee92 --- /dev/null +++ b/changelog.d/5155.bugfix @@ -0,0 +1 @@ +Add BuildSetting to ignore badge updates from virtual rooms. From 3bce1c6df65d71600459f597b826cc369ecf791a Mon Sep 17 00:00:00 2001 From: David Langley Date: Tue, 16 Nov 2021 12:24:21 +0000 Subject: [PATCH 3/7] Fix logging function name --- RiotNSE/NotificationService.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/RiotNSE/NotificationService.swift b/RiotNSE/NotificationService.swift index 76192fee7..6c10eb6c8 100644 --- a/RiotNSE/NotificationService.swift +++ b/RiotNSE/NotificationService.swift @@ -726,20 +726,20 @@ class NotificationService: UNNotificationServiceExtension { private func sendReadReceipt(forEvent event: MXEvent) { guard let mxRestClient = mxRestClient else { - MXLog.error("[NotificationService] sendVoipReadReceipt: Missing mxRestClient for read receipt request.") + MXLog.error("[NotificationService] sendReadReceipt: Missing mxRestClient for read receipt request.") return } guard let eventId = event.eventId, let roomId = event.roomId else { - MXLog.error("[NotificationService] sendVoipReadReceipt: Event information missing for read receipt request.") + MXLog.error("[NotificationService] sendReadReceipt: Event information missing for read receipt request.") return } mxRestClient.sendReadReceipt(toRoom: roomId, forEvent: eventId) { response in if response.isSuccess { - MXLog.debug("[NotificationService] sendVoipReadReceipt: Read receipt send successfully.") + MXLog.debug("[NotificationService] sendReadReceipt: Read receipt send successfully.") } else if let error = response.error { - MXLog.error("[NotificationService] sendVoipReadReceipt: Read receipt send failed with error \(error).") + MXLog.error("[NotificationService] sendReadReceipt: Read receipt send failed with error \(error).") } } } From 4e721897391f443c9b4d2b43dd142d8846a5d8b3 Mon Sep 17 00:00:00 2001 From: David Langley Date: Tue, 16 Nov 2021 14:40:22 +0000 Subject: [PATCH 4/7] Remove build setting and get check virtual info --- RiotNSE/NotificationService.swift | 92 ++++++++++++++++++++++--------- 1 file changed, 67 insertions(+), 25 deletions(-) diff --git a/RiotNSE/NotificationService.swift b/RiotNSE/NotificationService.swift index 6c10eb6c8..b0d14f089 100644 --- a/RiotNSE/NotificationService.swift +++ b/RiotNSE/NotificationService.swift @@ -332,11 +332,25 @@ class NotificationService: UNNotificationServiceExtension { if let callInviteContent = MXCallInviteEventContent(fromJSON: event.content), callInviteContent.lifetime > event.age, (callInviteContent.lifetime - event.age) > UInt(NSE.Constants.timeNeededToSendVoIPPushes * MSEC_PER_SEC) { - if BuildSettings.ignoreBadgeUpdatesForVirtualRooms { - self.sendReadReceipt(forEvent: event) - ignoreBadgeUpdate = true + NotificationService.backgroundSyncService.roomAccountData(forRoomId: roomId) { response in + if let accountData = response.value, accountData.virtualRoomInfo.isVirtual { + self.sendReadReceipt(forEvent: event) + ignoreBadgeUpdate = true + } + self.sendVoipPush(forEvent: event) + self.validateNotificationContentAndComplete( + notificationTitle: notificationTitle, + notificationBody: notificationBody, + additionalUserInfo: additionalUserInfo, + ignoreBadgeUpdate: ignoreBadgeUpdate, + threadIdentifier: threadIdentifier, + currentUserId: currentUserId, + event: event, + pushRule: pushRule, + onComplete: onComplete + ) } - self.sendVoipPush(forEvent: event) + return } else { MXLog.debug("[NotificationService] notificationContent: Do not attempt to send a VoIP push, there is not enough time to process it.") } @@ -489,28 +503,18 @@ class NotificationService: UNNotificationServiceExtension { break } - if self.localAuthenticationService.isProtectionSet { - MXLog.debug("[NotificationService] notificationContentForEvent: Resetting title and body because app protection is set") - notificationBody = NSString.localizedUserNotificationString(forKey: "MESSAGE_PROTECTED", arguments: []) - notificationTitle = nil - } - guard notificationBody != nil else { - MXLog.debug("[NotificationService] notificationContentForEvent: notificationBody is nil") - onComplete(nil, false) - return - } - - let notificationContent = self.notificationContent(withTitle: notificationTitle, - body: notificationBody, - threadIdentifier: threadIdentifier, - userId: currentUserId, - event: event, - pushRule: pushRule, - additionalInfo: additionalUserInfo) - - MXLog.debug("[NotificationService] notificationContentForEvent: Calling onComplete.") - onComplete(notificationContent, ignoreBadgeUpdate) + self.validateNotificationContentAndComplete( + notificationTitle: notificationTitle, + notificationBody: notificationBody, + additionalUserInfo: additionalUserInfo, + ignoreBadgeUpdate: ignoreBadgeUpdate, + threadIdentifier: threadIdentifier, + currentUserId: currentUserId, + event: event, + pushRule: pushRule, + onComplete: onComplete + ) case .failure(let error): MXLog.debug("[NotificationService] notificationContentForEvent: error: \(error)") onComplete(nil, false) @@ -518,6 +522,44 @@ class NotificationService: UNNotificationServiceExtension { }) } + private func validateNotificationContentAndComplete( + notificationTitle: String?, + notificationBody: String?, + additionalUserInfo: [AnyHashable: Any]?, + ignoreBadgeUpdate: Bool, + threadIdentifier: String?, + currentUserId: String?, + event: MXEvent, + pushRule: MXPushRule?, + onComplete: @escaping (UNNotificationContent?, Bool) -> Void + ) { + + var validatedNotificationBody: String? = notificationBody + var validatedNotificationTitle: String? = notificationTitle + if self.localAuthenticationService.isProtectionSet { + MXLog.debug("[NotificationService] notificationContentForEvent: Resetting title and body because app protection is set") + validatedNotificationBody = NSString.localizedUserNotificationString(forKey: "MESSAGE_PROTECTED", arguments: []) + validatedNotificationTitle = nil + } + + guard notificationBody != nil else { + MXLog.debug("[NotificationService] notificationContentForEvent: notificationBody is nil") + onComplete(nil, false) + return + } + + let notificationContent = self.notificationContent(withTitle: validatedNotificationTitle, + body: validatedNotificationBody, + threadIdentifier: threadIdentifier, + userId: currentUserId, + event: event, + pushRule: pushRule, + additionalInfo: additionalUserInfo) + + MXLog.debug("[NotificationService] notificationContentForEvent: Calling onComplete.") + onComplete(notificationContent, ignoreBadgeUpdate) + } + /// Returns the default title for message notifications. /// - Parameters: /// - eventSenderName: The displayname of the sender. From 14c42865e5024141444109a815a4611e2338ecb0 Mon Sep 17 00:00:00 2001 From: David Langley Date: Tue, 16 Nov 2021 14:55:07 +0000 Subject: [PATCH 5/7] Fix changelog description --- changelog.d/5155.bugfix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.d/5155.bugfix b/changelog.d/5155.bugfix index 0d821ee92..1e21bfc43 100644 --- a/changelog.d/5155.bugfix +++ b/changelog.d/5155.bugfix @@ -1 +1 @@ -Add BuildSetting to ignore badge updates from virtual rooms. +Ignore badge updates from virtual rooms. From 08b6b25e01723e5f29105e39efc6b5c61f8445b1 Mon Sep 17 00:00:00 2001 From: David Langley Date: Tue, 16 Nov 2021 15:02:52 +0000 Subject: [PATCH 6/7] Remove buildsetting --- Config/BuildSettings.swift | 3 --- 1 file changed, 3 deletions(-) diff --git a/Config/BuildSettings.swift b/Config/BuildSettings.swift index 4c7927f5e..44c32742c 100644 --- a/Config/BuildSettings.swift +++ b/Config/BuildSettings.swift @@ -154,9 +154,6 @@ final class BuildSettings: NSObject { } static let stunServerFallbackUrlString: String? = "stun:turn.matrix.org" - // For use in conjunction with virtual rooms. Events from virtual rooms should not be reflected in badge count for unread messages. - static let ignoreBadgeUpdatesForVirtualRooms = true - // MARK: - Public rooms Directory #warning("Unused build setting: should this be implemented in ShowDirectory?") static let publicRoomsAllowServerChange: Bool = true From c507166aa4096e00b635edff7137be2e5626f6d4 Mon Sep 17 00:00:00 2001 From: David Langley Date: Tue, 16 Nov 2021 16:16:04 +0000 Subject: [PATCH 7/7] Don't wait for accountData to start voip call. --- RiotNSE/NotificationService.swift | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/RiotNSE/NotificationService.swift b/RiotNSE/NotificationService.swift index b0d14f089..99a9bba12 100644 --- a/RiotNSE/NotificationService.swift +++ b/RiotNSE/NotificationService.swift @@ -337,7 +337,6 @@ class NotificationService: UNNotificationServiceExtension { self.sendReadReceipt(forEvent: event) ignoreBadgeUpdate = true } - self.sendVoipPush(forEvent: event) self.validateNotificationContentAndComplete( notificationTitle: notificationTitle, notificationBody: notificationBody, @@ -350,6 +349,7 @@ class NotificationService: UNNotificationServiceExtension { onComplete: onComplete ) } + self.sendVoipPush(forEvent: event) return } else { MXLog.debug("[NotificationService] notificationContent: Do not attempt to send a VoIP push, there is not enough time to process it.") @@ -537,13 +537,13 @@ class NotificationService: UNNotificationServiceExtension { var validatedNotificationBody: String? = notificationBody var validatedNotificationTitle: String? = notificationTitle if self.localAuthenticationService.isProtectionSet { - MXLog.debug("[NotificationService] notificationContentForEvent: Resetting title and body because app protection is set") + MXLog.debug("[NotificationService] validateNotificationContentAndComplete: Resetting title and body because app protection is set") validatedNotificationBody = NSString.localizedUserNotificationString(forKey: "MESSAGE_PROTECTED", arguments: []) validatedNotificationTitle = nil } - guard notificationBody != nil else { - MXLog.debug("[NotificationService] notificationContentForEvent: notificationBody is nil") + guard validatedNotificationBody != nil else { + MXLog.debug("[NotificationService] validateNotificationContentAndComplete: notificationBody is nil") onComplete(nil, false) return } @@ -556,7 +556,7 @@ class NotificationService: UNNotificationServiceExtension { pushRule: pushRule, additionalInfo: additionalUserInfo) - MXLog.debug("[NotificationService] notificationContentForEvent: Calling onComplete.") + MXLog.debug("[NotificationService] validateNotificationContentAndComplete: Calling onComplete.") onComplete(notificationContent, ignoreBadgeUpdate) }