Two sync loop experimental solution to decrypt push notifications (#1082)

* Experimental two sync loop solution

* better logging

* improved the code and handled invite notifications display better

* improved invite notifications

* new exerimental branch

* new sync loop

* code updated

* code improvements

* code improvements

* fix typo

* code improvements

* removed some unused code and added a respawn

* fixing some NSE issues

* code improvements

* new version of the branch

* more logging

* running the nse process ONLY IF necessary

* finally works! made also the feature flag

* also the encryption value of the room list api will depend on the flag now

* changelog

* code improvements

* code improvement

* updated proj

* fixing some compilation error after the rebase

* opt-in for the encryption sync

* fix
This commit is contained in:
Mauro
2023-06-22 19:23:33 +02:00
committed by GitHub
parent 652fd3cf76
commit afc4332716
18 changed files with 184 additions and 60 deletions
@@ -28,7 +28,10 @@ class ClientProxy: ClientProxyProtocol {
private var roomListService: RoomListService?
private var roomListStateUpdateTaskHandle: TaskHandle?
private var encryptionSyncService: EncryptionSync?
private var isEncryptionSyncing = false
var roomSummaryProvider: RoomSummaryProviderProtocol?
var inviteSummaryProvider: RoomSummaryProviderProtocol?
@@ -103,7 +106,7 @@ class ClientProxy: ClientProxyProtocol {
}
var isSyncing: Bool {
roomListService?.isSyncing() ?? false
roomListService?.isSyncing() ?? false && isEncryptionSyncing
}
func startSync() {
@@ -111,18 +114,30 @@ class ClientProxy: ClientProxyProtocol {
guard !isSyncing else {
return
}
startEncryptionSyncService()
roomListService?.sync()
}
func stopSync() {
MXLog.info("Stopping sync")
stopEncryptionSyncService()
do {
try roomListService?.stopSync()
} catch {
MXLog.error("Failed stopping room list service with error: \(error)")
}
}
private func stopEncryptionSyncService() {
guard isEncryptionSyncing else {
return
}
isEncryptionSyncing = false
encryptionSyncService?.stop()
MXLog.info("Stopping Encryption Sync service")
}
func directRoomForUserID(_ userID: String) async -> Result<String?, ClientProxyError> {
await Task.dispatch(on: clientQueue) {
@@ -359,14 +374,47 @@ class ClientProxy: ClientProxyProtocol {
self.avatarURLSubject.value = urlString.flatMap(URL.init)
}
}
private func startEncryptionSyncService() {
guard ServiceLocator.shared.settings.isEncryptionSyncEnabled else {
return
}
configureEncryptionSyncService()
}
private func configureEncryptionSyncService() {
do {
let listener = EncryptionSyncListenerProxy { [weak self] reason in
switch reason {
case .done:
MXLog.info("Encryption Sync has finished for user: \(self?.userID ?? "unknown")")
case .error(let msg):
MXLog.error("Encryption Sync has terminated for user: \(self?.userID ?? "unknown") for reason: \(msg)")
guard let self else {
return
}
Task {
self.configureEncryptionSyncService()
}
}
}
let encryptionSync = try client.mainEncryptionSync(id: "Main App", listener: listener)
encryptionSync.reloadCaches()
isEncryptionSyncing = true
encryptionSyncService = encryptionSync
MXLog.info("Encryption sync started for user: \(userID)")
} catch {
MXLog.error("Configure encryption sync failed with error: \(error)")
}
}
private func configureRoomListService() async {
guard roomListService == nil else {
fatalError("This shouldn't be called more than once")
}
do {
let roomListService = try client.roomListServiceWithEncryption()
let roomListService = try ServiceLocator.shared.settings.isEncryptionSyncEnabled ? client.roomListService() : client.roomListServiceWithEncryption()
roomListStateUpdateTaskHandle = roomListService.state(listener: RoomListStateListenerProxy { [weak self] state in
guard let self else { return }
MXLog.info("Received room list update: \(state)")
@@ -0,0 +1,31 @@
//
// Copyright 2023 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import Foundation
import MatrixRustSDK
final class EncryptionSyncListenerProxy: EncryptionSyncListener {
private let didTerminateClosure: (EncryptionSyncTerminationReason) -> Void
init(_ didTerminateClosure: @escaping (EncryptionSyncTerminationReason) -> Void) {
self.didTerminateClosure = didTerminateClosure
}
func didTerminate(reason: EncryptionSyncTerminationReason) {
didTerminateClosure(reason)
}
}
@@ -48,17 +48,6 @@ protocol NotificationItemProxyProtocol {
var isEncrypted: Bool { get }
}
extension NotificationItemProxyProtocol {
var id: String? {
let identifiers = receiverID + roomID + event.eventID
guard let data = identifiers.data(using: .utf8) else {
return nil
}
let digest = SHA256.hash(data: data)
return digest.compactMap { String(format: "%02x", $0) }.joined()
}
}
struct NotificationItemProxy: NotificationItemProxyProtocol {
let notificationItem: NotificationItem
let receiverID: String
@@ -168,7 +157,6 @@ extension NotificationItemProxyProtocol {
notification.receiverID = receiverID
notification.roomID = roomID
notification.eventID = event.eventID
notification.notificationID = id
notification.sound = isNoisy ? UNNotificationSound(named: UNNotificationSoundName(rawValue: "message.caf")) : nil
// So that the UI groups notification that are received for the same room but also for the same user
notification.threadIdentifier = "\(receiverID)\(roomID)"