Automatically retry decryptions in the active room when the app becomes active again just in case the NSE received keys we're not aware of (#3628)

This commit is contained in:
Stefan Ceriu 2024-12-18 11:10:56 +02:00 committed by GitHub
parent 2a865ce5bf
commit 435dfb8e46
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 38 additions and 42 deletions

View File

@ -14150,15 +14150,15 @@ class TimelineProxyMock: TimelineProxyProtocol {
} }
//MARK: - retryDecryption //MARK: - retryDecryption
var retryDecryptionForUnderlyingCallsCount = 0 var retryDecryptionSessionIDsUnderlyingCallsCount = 0
var retryDecryptionForCallsCount: Int { var retryDecryptionSessionIDsCallsCount: Int {
get { get {
if Thread.isMainThread { if Thread.isMainThread {
return retryDecryptionForUnderlyingCallsCount return retryDecryptionSessionIDsUnderlyingCallsCount
} else { } else {
var returnValue: Int? = nil var returnValue: Int? = nil
DispatchQueue.main.sync { DispatchQueue.main.sync {
returnValue = retryDecryptionForUnderlyingCallsCount returnValue = retryDecryptionSessionIDsUnderlyingCallsCount
} }
return returnValue! return returnValue!
@ -14166,28 +14166,28 @@ class TimelineProxyMock: TimelineProxyProtocol {
} }
set { set {
if Thread.isMainThread { if Thread.isMainThread {
retryDecryptionForUnderlyingCallsCount = newValue retryDecryptionSessionIDsUnderlyingCallsCount = newValue
} else { } else {
DispatchQueue.main.sync { DispatchQueue.main.sync {
retryDecryptionForUnderlyingCallsCount = newValue retryDecryptionSessionIDsUnderlyingCallsCount = newValue
} }
} }
} }
} }
var retryDecryptionForCalled: Bool { var retryDecryptionSessionIDsCalled: Bool {
return retryDecryptionForCallsCount > 0 return retryDecryptionSessionIDsCallsCount > 0
} }
var retryDecryptionForReceivedSessionID: String? var retryDecryptionSessionIDsReceivedSessionIDs: [String]?
var retryDecryptionForReceivedInvocations: [String] = [] var retryDecryptionSessionIDsReceivedInvocations: [[String]?] = []
var retryDecryptionForClosure: ((String) async -> Void)? var retryDecryptionSessionIDsClosure: (([String]?) async -> Void)?
func retryDecryption(for sessionID: String) async { func retryDecryption(sessionIDs: [String]?) async {
retryDecryptionForCallsCount += 1 retryDecryptionSessionIDsCallsCount += 1
retryDecryptionForReceivedSessionID = sessionID retryDecryptionSessionIDsReceivedSessionIDs = sessionIDs
DispatchQueue.main.async { DispatchQueue.main.async {
self.retryDecryptionForReceivedInvocations.append(sessionID) self.retryDecryptionSessionIDsReceivedInvocations.append(sessionIDs)
} }
await retryDecryptionForClosure?(sessionID) await retryDecryptionSessionIDsClosure?(sessionIDs)
} }
//MARK: - paginateBackwards //MARK: - paginateBackwards

View File

@ -196,6 +196,14 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
.throttle(for: .milliseconds(100), scheduler: DispatchQueue.main, latest: true) .throttle(for: .milliseconds(100), scheduler: DispatchQueue.main, latest: true)
.weakAssign(to: \.state.unseenKnockRequests, on: self) .weakAssign(to: \.state.unseenKnockRequests, on: self)
.store(in: &cancellables) .store(in: &cancellables)
NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)
.sink { [weak self] _ in
Task {
await self?.roomProxy.timeline.retryDecryption()
}
}
.store(in: &cancellables)
} }
private func processIdentityStatusChanges(_ changes: [IdentityStatusChange]) async { private func processIdentityStatusChanges(_ changes: [IdentityStatusChange]) async {

View File

@ -157,8 +157,6 @@ class TimelineInteractionHandler {
let debugInfo = timelineController.debugInfo(for: eventTimelineItem.id) let debugInfo = timelineController.debugInfo(for: eventTimelineItem.id)
MXLog.info("Showing debug info for \(eventTimelineItem.id)") MXLog.info("Showing debug info for \(eventTimelineItem.id)")
actionsSubject.send(.showDebugInfo(debugInfo)) actionsSubject.send(.showDebugInfo(debugInfo))
case .retryDecryption(let sessionID):
Task { await timelineController.retryDecryption(for: sessionID) }
case .report: case .report:
actionsSubject.send(.displayReportContent(itemID: itemID, senderID: eventTimelineItem.sender.id)) actionsSubject.send(.displayReportContent(itemID: itemID, senderID: eventTimelineItem.sender.id))
case .react: case .react:

View File

@ -67,7 +67,6 @@ enum TimelineItemMenuAction: Identifiable, Hashable {
case reply(isThread: Bool) case reply(isThread: Bool)
case forward(itemID: TimelineItemIdentifier) case forward(itemID: TimelineItemIdentifier)
case viewSource case viewSource
case retryDecryption(sessionID: String)
case report case report
case react case react
case toggleReaction(key: String) case toggleReaction(key: String)
@ -164,8 +163,6 @@ enum TimelineItemMenuAction: Identifiable, Hashable {
Label(L10n.actionRemoveMessage, icon: \.delete) Label(L10n.actionRemoveMessage, icon: \.delete)
case .viewSource: case .viewSource:
Label(L10n.actionViewSource, icon: \.code) Label(L10n.actionViewSource, icon: \.code)
case .retryDecryption:
Label(L10n.actionRetryDecryption, systemImage: "arrow.down.message")
case .report: case .report:
Label(L10n.actionReportContent, icon: \.chatProblem) Label(L10n.actionReportContent, icon: \.chatProblem)
case .react: case .react:

View File

@ -137,13 +137,6 @@ struct TimelineItemMenuActionProvider {
actions.append(.viewSource) actions.append(.viewSource)
} }
switch encryptedItem.encryptionType {
case .megolmV1AesSha2(let sessionID, _):
secondaryActions.append(.retryDecryption(sessionID: sessionID))
default:
break
}
return .init(isReactable: false, return .init(isReactable: false,
actions: actions, actions: actions,
secondaryActions: secondaryActions, secondaryActions: secondaryActions,

View File

@ -139,8 +139,6 @@ class MockRoomTimelineController: RoomTimelineControllerProtocol {
nil nil
} }
func retryDecryption(for sessionID: String) async { }
func eventTimestamp(for itemID: TimelineItemIdentifier) -> Date? { func eventTimestamp(for itemID: TimelineItemIdentifier) -> Date? {
timelineItemsTimestamp[itemID] ?? .now timelineItemsTimestamp[itemID] ?? .now
} }

View File

@ -356,10 +356,6 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
return nil return nil
} }
func retryDecryption(for sessionID: String) async {
await activeTimeline.retryDecryption(for: sessionID)
}
// MARK: - Private // MARK: - Private
/// The cancellable used to update the timeline items. /// The cancellable used to update the timeline items.

View File

@ -82,7 +82,5 @@ protocol RoomTimelineControllerProtocol {
func sendHandle(for itemID: TimelineItemIdentifier) -> SendHandleProxy? func sendHandle(for itemID: TimelineItemIdentifier) -> SendHandleProxy?
func retryDecryption(for sessionID: String) async
func eventTimestamp(for itemID: TimelineItemIdentifier) -> Date? func eventTimestamp(for itemID: TimelineItemIdentifier) -> Date?
} }

View File

@ -155,12 +155,14 @@ final class TimelineProxy: TimelineProxyProtocol {
} }
} }
func retryDecryption(for sessionID: String) async { func retryDecryption(sessionIDs: [String]?) async {
MXLog.info("Retrying decryption for sessionID: \(sessionID)") let sessionIDs = sessionIDs ?? []
MXLog.info("Retrying decryption for sessionIDs: \(sessionIDs)")
await Task.dispatch(on: .global()) { [weak self] in await Task.dispatch(on: .global()) { [weak self] in
self?.timeline.retryDecryption(sessionIds: [sessionID]) self?.timeline.retryDecryption(sessionIds: sessionIDs)
MXLog.info("Finished retrying decryption for sessionID: \(sessionID)") MXLog.info("Finished retrying decryption for sessionID: \(sessionIDs)")
} }
} }

View File

@ -35,7 +35,7 @@ protocol TimelineProxyProtocol {
func messageEventContent(for timelineItemID: TimelineItemIdentifier) async -> RoomMessageEventContentWithoutRelation? func messageEventContent(for timelineItemID: TimelineItemIdentifier) async -> RoomMessageEventContentWithoutRelation?
func retryDecryption(for sessionID: String) async func retryDecryption(sessionIDs: [String]?) async
func paginateBackwards(requestSize: UInt16) async -> Result<Void, TimelineProxyError> func paginateBackwards(requestSize: UInt16) async -> Result<Void, TimelineProxyError>
func paginateForwards(requestSize: UInt16) async -> Result<Void, TimelineProxyError> func paginateForwards(requestSize: UInt16) async -> Result<Void, TimelineProxyError>
@ -113,3 +113,9 @@ protocol TimelineProxyProtocol {
html: String?, html: String?,
intentionalMentions: Mentions) -> RoomMessageEventContentWithoutRelation intentionalMentions: Mentions) -> RoomMessageEventContentWithoutRelation
} }
extension TimelineProxyProtocol {
func retryDecryption() async {
await retryDecryption(sessionIDs: nil)
}
}