From 190678c7886c5ac7d6075f022e95699243460da6 Mon Sep 17 00:00:00 2001 From: David Langley Date: Thu, 3 Mar 2022 17:26:36 +0000 Subject: [PATCH 1/8] Add MXEventStreamService for monitoring events. --- MatrixSDK.xcodeproj/project.pbxproj | 27 ++++++++ .../Algorithms/Megolm/MXMegolmDecryption.m | 3 + MatrixSDK/Crypto/MXCrypto.h | 6 +- MatrixSDK/Crypto/MXCrypto.m | 19 ++++++ .../EventTimeline/Room/MXRoomEventTimeline.m | 2 + .../EventStream/MXEventStreamService.swift | 62 +++++++++++++++++++ .../EventStream/MXLiveEventListener.swift | 30 +++++++++ MatrixSDK/MXSession.h | 6 ++ MatrixSDK/MXSession.m | 15 +---- MatrixSDKTests/MXCryptoTests.m | 4 +- MatrixSDKTests/MXRoomSummaryTests.m | 2 +- 11 files changed, 158 insertions(+), 18 deletions(-) create mode 100644 MatrixSDK/EventStream/MXEventStreamService.swift create mode 100644 MatrixSDK/EventStream/MXLiveEventListener.swift diff --git a/MatrixSDK.xcodeproj/project.pbxproj b/MatrixSDK.xcodeproj/project.pbxproj index 180946f6a6..7f1fecbe69 100644 --- a/MatrixSDK.xcodeproj/project.pbxproj +++ b/MatrixSDK.xcodeproj/project.pbxproj @@ -703,6 +703,12 @@ 3B60DCAB92D470B91262BF0C /* libPods-MatrixSDKTests-macOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 15D7F292D95EB58AEE801C4E /* libPods-MatrixSDKTests-macOS.a */; }; 66398BA527A4085B00466E89 /* MXRefreshResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 66398BA427A4085B00466E89 /* MXRefreshResponse.m */; }; 66398BA627A4085B00466E89 /* MXRefreshResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 66398BA427A4085B00466E89 /* MXRefreshResponse.m */; }; + 66836AB727CFA17200515780 /* MXEventStreamService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66836AB527CFA17200515780 /* MXEventStreamService.swift */; }; + 66836AB827CFA17200515780 /* MXEventStreamService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66836AB527CFA17200515780 /* MXEventStreamService.swift */; }; + 66836AB927CFA17200515780 /* MXLiveEventListener.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66836AB627CFA17200515780 /* MXLiveEventListener.swift */; }; + 66836ABA27CFA17200515780 /* MXLiveEventListener.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66836AB627CFA17200515780 /* MXLiveEventListener.swift */; }; + 66836ABC27CFA51900515780 /* MXToDeviceService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66836ABB27CFA51900515780 /* MXToDeviceService.swift */; }; + 66836ABD27CFA51900515780 /* MXToDeviceService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66836ABB27CFA51900515780 /* MXToDeviceService.swift */; }; 66AC9D23278CE627002E9B8F /* MXRefreshTokenData.h in Headers */ = {isa = PBXBuildFile; fileRef = 66AC9D21278CE626002E9B8F /* MXRefreshTokenData.h */; }; 66AC9D24278CE627002E9B8F /* MXRefreshTokenData.h in Headers */ = {isa = PBXBuildFile; fileRef = 66AC9D21278CE626002E9B8F /* MXRefreshTokenData.h */; }; 66AC9D25278CE627002E9B8F /* MXRefreshTokenData.m in Sources */ = {isa = PBXBuildFile; fileRef = 66AC9D22278CE626002E9B8F /* MXRefreshTokenData.m */; }; @@ -2303,6 +2309,9 @@ 6257D945D115DA658F44E8D4 /* Pods-SDK-MatrixSDK-macOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SDK-MatrixSDK-macOS.release.xcconfig"; path = "Target Support Files/Pods-SDK-MatrixSDK-macOS/Pods-SDK-MatrixSDK-macOS.release.xcconfig"; sourceTree = ""; }; 66398BA427A4085B00466E89 /* MXRefreshResponse.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MXRefreshResponse.m; sourceTree = ""; }; 66398BA727A408C000466E89 /* MXRefreshResponse.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MXRefreshResponse.h; sourceTree = ""; }; + 66836AB527CFA17200515780 /* MXEventStreamService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MXEventStreamService.swift; sourceTree = ""; }; + 66836AB627CFA17200515780 /* MXLiveEventListener.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MXLiveEventListener.swift; sourceTree = ""; }; + 66836ABB27CFA51900515780 /* MXToDeviceService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MXToDeviceService.swift; sourceTree = ""; }; 66AC9D21278CE626002E9B8F /* MXRefreshTokenData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MXRefreshTokenData.h; sourceTree = ""; }; 66AC9D22278CE626002E9B8F /* MXRefreshTokenData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXRefreshTokenData.m; sourceTree = ""; }; 6869D206EA7C7FB05EAB75B0 /* Pods-MatrixSDKTests-iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MatrixSDKTests-iOS.release.xcconfig"; path = "Target Support Files/Pods-MatrixSDKTests-iOS/Pods-MatrixSDKTests-iOS.release.xcconfig"; sourceTree = ""; }; @@ -3717,6 +3726,7 @@ 32C6F92F19DD814400EA4E9C /* MatrixSDK */ = { isa = PBXGroup; children = ( + 66836AB427CFA17200515780 /* EventStream */, ECCA02B9273485A100B6F34F /* Threads */, 3259CFD9260266F700C365DB /* Categories */, EC383BA0253DE49B002FBBE6 /* Background */, @@ -4022,6 +4032,17 @@ path = Dehydration; sourceTree = ""; }; + 66836AB427CFA17200515780 /* EventStream */ = { + isa = PBXGroup; + children = ( + 66836AB527CFA17200515780 /* MXEventStreamService.swift */, + 66836AB627CFA17200515780 /* MXLiveEventListener.swift */, + 66836ABB27CFA51900515780 /* MXToDeviceService.swift */, + ); + name = EventStream; + path = MatrixSDK/EventStream; + sourceTree = SOURCE_ROOT; + }; 916911E77039455CC9D0900C /* Pods */ = { isa = PBXGroup; children = ( @@ -5743,6 +5764,7 @@ 32DC15D51A8CF874006F9AD3 /* MXPushRuleEventMatchConditionChecker.m in Sources */, EC1165B427107E330089FA56 /* MXStoreRoomListDataManager.swift in Sources */, 32B94E06228EE90300716A26 /* MXRealmReactionRelation.m in Sources */, + 66836AB927CFA17200515780 /* MXLiveEventListener.swift in Sources */, 320BBF411D6C81550079890E /* MXEventsByTypesEnumeratorOnArray.m in Sources */, 181FD5D62660C791008EC084 /* MXLogObjcWrapper.m in Sources */, EC60ED87265CFD0700B39A4E /* MXRoomsSyncResponse.m in Sources */, @@ -5777,6 +5799,7 @@ 329FB1761A0A3A1600A5E88E /* MXRoomMember.m in Sources */, 3251D41F25AF01D7001E6E77 /* MXUIKitApplicationStateService.swift in Sources */, B1136965230AC9D900E2B2FA /* MXIdentityService.m in Sources */, + 66836AB727CFA17200515780 /* MXEventStreamService.swift in Sources */, B11BD44922CB56790064D8B0 /* MXReplyEventParser.m in Sources */, EC0B941127184E8A00B4D440 /* MXRoomSummaryMO.swift in Sources */, EC0B941327184E8A00B4D440 /* MXRoomMembersCountMO.swift in Sources */, @@ -6019,6 +6042,7 @@ ECB5D98C2552C9B4000AD89C /* MXStopwatch.swift in Sources */, B1136964230AC9D900E2B2FA /* MXIdentityServerRestClient.m in Sources */, F0C34CBB1C18C93700C36F09 /* MXSDKOptions.m in Sources */, + 66836ABC27CFA51900515780 /* MXToDeviceService.swift in Sources */, B16F35A225F916A00029AE98 /* MXRoomTypeMapper.swift in Sources */, ECD289BF26FDE5F700F268CF /* MXStoreRoomListDataCounts.swift in Sources */, 320BBF441D6C81550079890E /* MXEventsEnumeratorOnArray.m in Sources */, @@ -6253,6 +6277,7 @@ B14EF1E42397E90400758AF0 /* MXWellknownIntegrations.m in Sources */, EC60EDF5265CFFAC00B39A4E /* MXGroupsSyncResponse.m in Sources */, EC1165B527107E330089FA56 /* MXStoreRoomListDataManager.swift in Sources */, + 66836ABA27CFA17200515780 /* MXLiveEventListener.swift in Sources */, B14EF1E52397E90400758AF0 /* MXLoginPolicy.m in Sources */, B14EF1E62397E90400758AF0 /* (null) in Sources */, EC60EDB5265CFE6200B39A4E /* MXRoomSyncEphemeral.m in Sources */, @@ -6287,6 +6312,7 @@ B14EF1F82397E90400758AF0 /* MXReplyEventParts.m in Sources */, 3259D02426037A7200C365DB /* NSArray.swift in Sources */, 3A108A8125810C96005EEBE9 /* MXKeyData.m in Sources */, + 66836AB827CFA17200515780 /* MXEventStreamService.swift in Sources */, 3A59A4A025A7A16F00DDA1FC /* MXOlmOutboundGroupSession.m in Sources */, EC0B941227184E8A00B4D440 /* MXRoomSummaryMO.swift in Sources */, EC0B941427184E8A00B4D440 /* MXRoomMembersCountMO.swift in Sources */, @@ -6529,6 +6555,7 @@ EC60ED6A265CFC7200B39A4E /* MXPresenceSyncResponse.m in Sources */, 3A108AA525810FE5005EEBE9 /* MXRawDataKey.m in Sources */, 324DD29C246AD2B500377005 /* MXSecretStorage.m in Sources */, + 66836ABD27CFA51900515780 /* MXToDeviceService.swift in Sources */, EC60EDC9265CFEA800B39A4E /* MXRoomSyncUnreadNotifications.m in Sources */, B14EF26F2397E90400758AF0 /* MXUser.m in Sources */, 324AAC772399140D00380A66 /* MXKeyVerificationDone.m in Sources */, diff --git a/MatrixSDK/Crypto/Algorithms/Megolm/MXMegolmDecryption.m b/MatrixSDK/Crypto/Algorithms/Megolm/MXMegolmDecryption.m index 76b99e74c4..43eb150770 100644 --- a/MatrixSDK/Crypto/Algorithms/Megolm/MXMegolmDecryption.m +++ b/MatrixSDK/Crypto/Algorithms/Megolm/MXMegolmDecryption.m @@ -24,6 +24,7 @@ #import "MXCryptoAlgorithms.h" #import "MXCrypto_Private.h" #import "MXTools.h" +#import "MatrixSDKSwiftHeader.h" @interface MXMegolmDecryption () { @@ -108,9 +109,11 @@ - (MXEventDecryptionResult *)decryptEvent:(MXEvent*)event inTimeline:(NSString*) result.senderCurve25519Key = olmResult.senderKey; result.claimedEd25519Key = olmResult.keysClaimed[@"ed25519"]; result.forwardingCurve25519KeyChain = olmResult.forwardingCurve25519KeyChain; + [crypto.mxSession.eventStreamService dispatchLiveEventDecryptedWithEvent:event result:result]; } else { + [crypto.mxSession.eventStreamService dispatchLiveEventDecryptionFailedWithEvent:event error:olmError]; if ([olmError.domain isEqualToString:OLMErrorDomain]) { // Manage OLMKit error diff --git a/MatrixSDK/Crypto/MXCrypto.h b/MatrixSDK/Crypto/MXCrypto.h index 01f980236e..6fe541811b 100644 --- a/MatrixSDK/Crypto/MXCrypto.h +++ b/MatrixSDK/Crypto/MXCrypto.h @@ -264,12 +264,12 @@ extern NSString *const MXDeviceListDidUpdateUsersDevicesNotification; - (void)handleDeviceUnusedFallbackKeys:(NSArray *)deviceUnusedFallbackKeys; /** - Handle a room key event. + Handle toDevice event - @param event the room key event. + @param event the `toDevice` event. @param onComplete the block called when the operation completes. */ -- (void)handleRoomKeyEvent:(MXEvent*)event onComplete:(void (^)(void))onComplete; +- (void)handleToDeviceEvent:(MXEvent*)event onComplete:(void (^)(void))onComplete; /** Handle the completion of a /sync. diff --git a/MatrixSDK/Crypto/MXCrypto.m b/MatrixSDK/Crypto/MXCrypto.m index 3a85751db2..3966f92b2c 100644 --- a/MatrixSDK/Crypto/MXCrypto.m +++ b/MatrixSDK/Crypto/MXCrypto.m @@ -51,6 +51,7 @@ #import "MXDeviceListResponse.h" +#import "MatrixSDKSwiftHeader.h" /** The store to use for crypto. */ @@ -817,6 +818,24 @@ - (void)handleDeviceListsChanges:(MXDeviceListResponse*)deviceLists #endif } +- (void)handleToDeviceEvent:(MXEvent *)event onComplete:(void (^)(void))onComplete +{ + switch (event.eventType) + { + case MXEventTypeRoomKey: + { + [self handleRoomKeyEvent:event onComplete:onComplete]; + break; + } + + default: + onComplete(); + break; + } + [self.mxSession.eventStreamService dispatchOnLiveToDeviceWithEvent:event]; +} + + - (void)handleRoomKeyEvent:(MXEvent*)event onComplete:(void (^)(void))onComplete { // Use decryptionQueue as synchronisation because decryptions require room keys diff --git a/MatrixSDK/Data/EventTimeline/Room/MXRoomEventTimeline.m b/MatrixSDK/Data/EventTimeline/Room/MXRoomEventTimeline.m index 3daa0605dd..7f5f3db931 100644 --- a/MatrixSDK/Data/EventTimeline/Room/MXRoomEventTimeline.m +++ b/MatrixSDK/Data/EventTimeline/Room/MXRoomEventTimeline.m @@ -299,6 +299,7 @@ - (MXHTTPOperation *)paginate:(NSUInteger)numItems direction:(MXTimelineDirectio // Handle events from the most recent for (MXEvent *event in eventsFromStore.reverseObjectEnumerator) { + [self->room.mxSession.eventStreamService dispatchPaginatedEventReceivedWithEvent:event roomId:self->room.roomId]; [self addEvent:event direction:MXTimelineDirectionBackwards fromStore:YES isRoomInitialSync:NO]; } @@ -520,6 +521,7 @@ - (void)handleJoinedRoomSync:(MXRoomSync *)roomSync onComplete:(void (^)(void))o for (MXEvent *event in roomSync.timeline.events) { + [self->room.mxSession.eventStreamService dispatchLiveEventReceivedWithEvent:event roomId:self->room.roomId initialSync:isRoomInitialSync]; // Add the event to the end of the timeline [self addEvent:event direction:MXTimelineDirectionForwards fromStore:NO isRoomInitialSync:isRoomInitialSync]; } diff --git a/MatrixSDK/EventStream/MXEventStreamService.swift b/MatrixSDK/EventStream/MXEventStreamService.swift new file mode 100644 index 0000000000..db3b9ab001 --- /dev/null +++ b/MatrixSDK/EventStream/MXEventStreamService.swift @@ -0,0 +1,62 @@ +// +// Copyright 2022 The Matrix.org Foundation C.I.C +// +// 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 + +@objcMembers public class MXEventStreamService: NSObject { + + var listeners = [MXLiveEventListener]() + + public func add(eventStreamListener: MXLiveEventListener) { + listeners.append(eventStreamListener) + } + + public func remove(eventStreamListener: MXLiveEventListener) { + listeners.removeAll { $0 === eventStreamListener } + } + + public func dispatchLiveEventReceived(event: MXEvent, roomId: String, initialSync: Bool) { + guard !initialSync else { return } + listeners.forEach { listener in + listener.onLiveEvent(roomId: roomId, event: event) + } + } + + public func dispatchPaginatedEventReceived(event: MXEvent, roomId: String) { + listeners.forEach { listener in + listener.onPaginatedEvent(roomId: roomId, event: event) + } + } + + public func dispatchLiveEventDecrypted(event: MXEvent, result: MXEventDecryptionResult) { + listeners.forEach { listener in + listener.onEventDecrypted(eventId: event.eventId, roomId: event.roomId, clearEvent: result.clearEvent) + } + } + + public func dispatchLiveEventDecryptionFailed(event: MXEvent, error: Error) { + listeners.forEach { listener in + listener.onEventDecryptionError(eventId: event.eventId, roomId: event.roomId, error: error) + } + } + + public func dispatchOnLiveToDevice(event: MXEvent) { + listeners.forEach { listener in + listener.onLiveToDeviceEvent(event: event) + } + } +} + diff --git a/MatrixSDK/EventStream/MXLiveEventListener.swift b/MatrixSDK/EventStream/MXLiveEventListener.swift new file mode 100644 index 0000000000..b8bb202fe1 --- /dev/null +++ b/MatrixSDK/EventStream/MXLiveEventListener.swift @@ -0,0 +1,30 @@ +// +// Copyright 2022 The Matrix.org Foundation C.I.C +// +// 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. +// + +public protocol MXLiveEventListener: AnyObject { + + func onLiveEvent(roomId: String, event: MXEvent) + + func onPaginatedEvent(roomId: String, event: MXEvent) + + func onEventDecrypted(eventId: String, roomId: String, clearEvent: [AnyHashable: Any]) + + func onEventDecryptionError(eventId: String, roomId: String, error: Error) + + func onLiveToDeviceEvent(event: MXEvent) + + // Maybe later add more, like onJoin, onLeave.. +} diff --git a/MatrixSDK/MXSession.h b/MatrixSDK/MXSession.h index 4231b43e34..cac6c6b7be 100644 --- a/MatrixSDK/MXSession.h +++ b/MatrixSDK/MXSession.h @@ -347,6 +347,7 @@ FOUNDATION_EXPORT NSString *const kMXSessionNoRoomTag; @class MXSpaceService; @class MXThreadingService; @class MXCapabilities; +@class MXEventStreamService; #pragma mark - MXSession /** @@ -487,6 +488,11 @@ FOUNDATION_EXPORT NSString *const kMXSessionNoRoomTag; */ @property (nonatomic, readonly) MXThreadingService *threadingService NS_REFINED_FOR_SWIFT; +/** + Service to observe events. + */ +@property (nonatomic, readonly) MXEventStreamService *eventStreamService; + /** Flag indicating the session can be paused. */ diff --git a/MatrixSDK/MXSession.m b/MatrixSDK/MXSession.m index 2077ecb84e..1b95ebc2cf 100644 --- a/MatrixSDK/MXSession.m +++ b/MatrixSDK/MXSession.m @@ -243,6 +243,7 @@ - (id)initWithMatrixRestClient:(MXRestClient*)mxRestClient name:MXSpaceService.didBuildSpaceGraph object:_spaceService]; _threadingService = [[MXThreadingService alloc] initWithSession:self]; + _eventStreamService = [[MXEventStreamService alloc] init]; [self setIdentityServer:mxRestClient.identityServer andAccessToken:mxRestClient.credentials.identityServerAccessToken]; @@ -1870,18 +1871,8 @@ - (void)handleToDeviceEvent:(MXEvent *)event onComplete:(void (^)(void))onComple onComplete(); }; - switch (event.eventType) - { - case MXEventTypeRoomKey: - { - [_crypto handleRoomKeyEvent:event onComplete:onHandleToDeviceEventDone]; - break; - } - - default: - onHandleToDeviceEventDone(); - break; - } + + [_crypto handleToDeviceEvent:event onComplete:onHandleToDeviceEventDone]; } /** diff --git a/MatrixSDKTests/MXCryptoTests.m b/MatrixSDKTests/MXCryptoTests.m index f1c9e34d13..60f7b4ecb4 100644 --- a/MatrixSDKTests/MXCryptoTests.m +++ b/MatrixSDKTests/MXCryptoTests.m @@ -1843,7 +1843,7 @@ - (void)testRoomKeyReshare newContent[@"session_key"] = sessionInfo.session.sessionKey; toDeviceEvent.clearEvent.wireContent = newContent; - [bobSession.crypto handleRoomKeyEvent:toDeviceEvent onComplete:^{}]; + [bobSession.crypto handleToDeviceEvent:toDeviceEvent onComplete:^{}]; // We still must be able to decrypt the event // ie, the implementation must have ignored the new room key with the advanced outbound group @@ -1913,7 +1913,7 @@ - (void)testLateRoomKey }]; // Reinject the m.room_key event. This mimics a room_key event that arrives after message events. - [bobSession.crypto handleRoomKeyEvent:toDeviceEvent onComplete:^{}]; + [bobSession.crypto handleToDeviceEvent:toDeviceEvent onComplete:^{}]; }]; }]; }]; diff --git a/MatrixSDKTests/MXRoomSummaryTests.m b/MatrixSDKTests/MXRoomSummaryTests.m index 395ed09a9b..363269249b 100644 --- a/MatrixSDKTests/MXRoomSummaryTests.m +++ b/MatrixSDKTests/MXRoomSummaryTests.m @@ -1398,7 +1398,7 @@ - (void)testLateRoomKey // Attempt a new decryption [bobSession decryptEvents:@[event] inTimeline:nil onComplete:^(NSArray *failedEvents) { // Reinject the m.room_key event. This mimics a room_key event that arrives after message events. - [bobSession.crypto handleRoomKeyEvent:toDeviceEvent onComplete:^{}]; + [bobSession.crypto handleToDeviceEvent:toDeviceEvent onComplete:^{}]; }]; break; From a456229c8e086bbe11bd02b1f33a528c568361c4 Mon Sep 17 00:00:00 2001 From: David Langley Date: Tue, 8 Mar 2022 17:39:32 +0000 Subject: [PATCH 2/8] txnId should be optional --- MatrixSDK/Contrib/Swift/MXRestClient.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MatrixSDK/Contrib/Swift/MXRestClient.swift b/MatrixSDK/Contrib/Swift/MXRestClient.swift index 4c4d5b0cd9..5ea955027c 100644 --- a/MatrixSDK/Contrib/Swift/MXRestClient.swift +++ b/MatrixSDK/Contrib/Swift/MXRestClient.swift @@ -1798,7 +1798,7 @@ public extension MXRestClient { - returns: a `MXHTTPOperation` instance. */ - @nonobjc @discardableResult func sendDirectToDevice(eventType: String, contentMap: MXUsersDevicesMap, txnId: String, completion: @escaping (_ response: MXResponse) -> Void) -> MXHTTPOperation { + @nonobjc @discardableResult func sendDirectToDevice(eventType: String, contentMap: MXUsersDevicesMap, txnId: String?, completion: @escaping (_ response: MXResponse) -> Void) -> MXHTTPOperation { return __send(toDevice: eventType, contentMap: contentMap, txnId: txnId, success: currySuccess(completion), failure: curryFailure(completion)) } From a2ec902b2b22d7216b3ae7ca8dd06b69fee53e08 Mon Sep 17 00:00:00 2001 From: David Langley Date: Fri, 11 Mar 2022 16:44:40 +0000 Subject: [PATCH 3/8] Fix crash on optional progress block and add reportUrl to success block. --- MatrixSDK/Utils/MXBugReportRestClient.h | 2 +- MatrixSDK/Utils/MXBugReportRestClient.m | 20 ++++++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/MatrixSDK/Utils/MXBugReportRestClient.h b/MatrixSDK/Utils/MXBugReportRestClient.h index e8cf5647d7..b3841f0e0d 100644 --- a/MatrixSDK/Utils/MXBugReportRestClient.h +++ b/MatrixSDK/Utils/MXBugReportRestClient.h @@ -74,7 +74,7 @@ typedef enum : NSUInteger sendFiles:(NSArray*)files attachGitHubLabels:(NSArray*)gitHubLabels progress:(void (^)(MXBugReportState state, NSProgress *progress))progress - success:(void (^)(void))success + success:(void (^)(NSString *reportUrl))success failure:(void (^)(NSError *error))failure; /** diff --git a/MatrixSDK/Utils/MXBugReportRestClient.m b/MatrixSDK/Utils/MXBugReportRestClient.m index 4b52834534..8503b60f37 100644 --- a/MatrixSDK/Utils/MXBugReportRestClient.m +++ b/MatrixSDK/Utils/MXBugReportRestClient.m @@ -98,7 +98,7 @@ - (instancetype)initWithBugReportEndpoint:(NSString *)theBugReportEndpoint return self; } -- (void)sendBugReport:(NSString *)text sendLogs:(BOOL)sendLogs sendCrashLog:(BOOL)sendCrashLog sendFiles:(NSArray*)files attachGitHubLabels:(NSArray*)gitHubLabels progress:(void (^)(MXBugReportState, NSProgress *))progress success:(void (^)(void))success failure:(void (^)(NSError *))failure +- (void)sendBugReport:(NSString *)text sendLogs:(BOOL)sendLogs sendCrashLog:(BOOL)sendCrashLog sendFiles:(NSArray*)files attachGitHubLabels:(NSArray*)gitHubLabels progress:(void (^)(MXBugReportState, NSProgress *))progress success:(void (^)(NSString*))success failure:(void (^)(NSError *))failure { if (_state != MXBugReportStateReady) { @@ -124,7 +124,7 @@ - (void)sendBugReport:(NSString *)text sendLogs:(BOOL)sendLogs sendCrashLog:(BOO } } --(void)sendBugReport:(NSString *)text sendFiles:(NSArray*)files attachGitHubLabels:(NSArray*)gitHubLabels progress:(void (^)(MXBugReportState, NSProgress *))progress success:(void (^)(void))success failure:(void (^)(NSError *))failure +-(void)sendBugReport:(NSString *)text sendFiles:(NSArray*)files attachGitHubLabels:(NSArray*)gitHubLabels progress:(void (^)(MXBugReportState, NSProgress *))progress success:(void (^)(NSString*))success failure:(void (^)(NSError *))failure { // The bugreport api needs at least app and version to render well NSParameterAssert(_appName && _version); @@ -276,10 +276,15 @@ -(void)sendBugReport:(NSString *)text sendFiles:(NSArray*)files attachGi else { MXLogDebug(@"[MXBugReport] sendBugReport: report done in %.3fms", [[NSDate date] timeIntervalSinceDate:startDate] * 1000); - + + NSString *reportUrl = nil; + if ([response isKindOfClass:[NSDictionary class]]) { + NSDictionary *responseDictionary = (NSDictionary*)responseObject; + reportUrl = responseDictionary[@"report_url"]; + } if (success) { - success(); + success(reportUrl); } } }]; @@ -316,9 +321,12 @@ - (void)zipFiles:(BOOL)logs crashLog:(BOOL)crashLog progress:(void (^)(MXBugRepo if (logFiles.count) { _state = MXBugReportStateProgressZipping; - + NSProgress *zipProgress = [NSProgress progressWithTotalUnitCount:logFiles.count]; - progress(_state, zipProgress); + if (progress) + { + progress(_state, zipProgress); + } MXWeakify(self); dispatch_async(dispatchQueue, ^{ From 6fe5744a0295c61d038c96a5ea73325b2091934c Mon Sep 17 00:00:00 2001 From: David Langley Date: Wed, 16 Mar 2022 17:47:23 +0000 Subject: [PATCH 4/8] Update event stream service to just watch decryption attempts and current sync state. --- .../Algorithms/Megolm/MXMegolmDecryption.m | 5 ++-- .../EventTimeline/Room/MXRoomEventTimeline.m | 2 -- .../EventStream/MXEventStreamService.swift | 23 ++++--------------- .../EventStream/MXLiveEventListener.swift | 13 ++++------- MatrixSDK/MXSession.m | 1 + 5 files changed, 12 insertions(+), 32 deletions(-) diff --git a/MatrixSDK/Crypto/Algorithms/Megolm/MXMegolmDecryption.m b/MatrixSDK/Crypto/Algorithms/Megolm/MXMegolmDecryption.m index 43eb150770..352013fe75 100644 --- a/MatrixSDK/Crypto/Algorithms/Megolm/MXMegolmDecryption.m +++ b/MatrixSDK/Crypto/Algorithms/Megolm/MXMegolmDecryption.m @@ -109,11 +109,9 @@ - (MXEventDecryptionResult *)decryptEvent:(MXEvent*)event inTimeline:(NSString*) result.senderCurve25519Key = olmResult.senderKey; result.claimedEd25519Key = olmResult.keysClaimed[@"ed25519"]; result.forwardingCurve25519KeyChain = olmResult.forwardingCurve25519KeyChain; - [crypto.mxSession.eventStreamService dispatchLiveEventDecryptedWithEvent:event result:result]; } else { - [crypto.mxSession.eventStreamService dispatchLiveEventDecryptionFailedWithEvent:event error:olmError]; if ([olmError.domain isEqualToString:OLMErrorDomain]) { // Manage OLMKit error @@ -143,7 +141,8 @@ - (MXEventDecryptionResult *)decryptEvent:(MXEvent*)event inTimeline:(NSString*) result.error = olmError; } - + + [crypto.mxSession.eventStreamService dispatchLiveEventDecryptionAttemptedWithEvent:event result:result]; return result; } diff --git a/MatrixSDK/Data/EventTimeline/Room/MXRoomEventTimeline.m b/MatrixSDK/Data/EventTimeline/Room/MXRoomEventTimeline.m index 7f5f3db931..3daa0605dd 100644 --- a/MatrixSDK/Data/EventTimeline/Room/MXRoomEventTimeline.m +++ b/MatrixSDK/Data/EventTimeline/Room/MXRoomEventTimeline.m @@ -299,7 +299,6 @@ - (MXHTTPOperation *)paginate:(NSUInteger)numItems direction:(MXTimelineDirectio // Handle events from the most recent for (MXEvent *event in eventsFromStore.reverseObjectEnumerator) { - [self->room.mxSession.eventStreamService dispatchPaginatedEventReceivedWithEvent:event roomId:self->room.roomId]; [self addEvent:event direction:MXTimelineDirectionBackwards fromStore:YES isRoomInitialSync:NO]; } @@ -521,7 +520,6 @@ - (void)handleJoinedRoomSync:(MXRoomSync *)roomSync onComplete:(void (^)(void))o for (MXEvent *event in roomSync.timeline.events) { - [self->room.mxSession.eventStreamService dispatchLiveEventReceivedWithEvent:event roomId:self->room.roomId initialSync:isRoomInitialSync]; // Add the event to the end of the timeline [self addEvent:event direction:MXTimelineDirectionForwards fromStore:NO isRoomInitialSync:isRoomInitialSync]; } diff --git a/MatrixSDK/EventStream/MXEventStreamService.swift b/MatrixSDK/EventStream/MXEventStreamService.swift index db3b9ab001..6143a940f6 100644 --- a/MatrixSDK/EventStream/MXEventStreamService.swift +++ b/MatrixSDK/EventStream/MXEventStreamService.swift @@ -28,28 +28,15 @@ import Foundation listeners.removeAll { $0 === eventStreamListener } } - public func dispatchLiveEventReceived(event: MXEvent, roomId: String, initialSync: Bool) { - guard !initialSync else { return } + public func dispatchSessionStateChanged(state: MXSessionState) { listeners.forEach { listener in - listener.onLiveEvent(roomId: roomId, event: event) + listener.onSessionStateChanged(state: state) } } - - public func dispatchPaginatedEventReceived(event: MXEvent, roomId: String) { - listeners.forEach { listener in - listener.onPaginatedEvent(roomId: roomId, event: event) - } - } - - public func dispatchLiveEventDecrypted(event: MXEvent, result: MXEventDecryptionResult) { - listeners.forEach { listener in - listener.onEventDecrypted(eventId: event.eventId, roomId: event.roomId, clearEvent: result.clearEvent) - } - } - - public func dispatchLiveEventDecryptionFailed(event: MXEvent, error: Error) { + + public func dispatchLiveEventDecryptionAttempted(event: MXEvent, result: MXEventDecryptionResult) { listeners.forEach { listener in - listener.onEventDecryptionError(eventId: event.eventId, roomId: event.roomId, error: error) + listener.onLiveEventDecryptionAttempted(event: event, result: result) } } diff --git a/MatrixSDK/EventStream/MXLiveEventListener.swift b/MatrixSDK/EventStream/MXLiveEventListener.swift index b8bb202fe1..fa14517c54 100644 --- a/MatrixSDK/EventStream/MXLiveEventListener.swift +++ b/MatrixSDK/EventStream/MXLiveEventListener.swift @@ -15,16 +15,11 @@ // public protocol MXLiveEventListener: AnyObject { - - func onLiveEvent(roomId: String, event: MXEvent) - - func onPaginatedEvent(roomId: String, event: MXEvent) - - func onEventDecrypted(eventId: String, roomId: String, clearEvent: [AnyHashable: Any]) - - func onEventDecryptionError(eventId: String, roomId: String, error: Error) + + func onSessionStateChanged(state: MXSessionState) + + func onLiveEventDecryptionAttempted(event: MXEvent, result:MXEventDecryptionResult) func onLiveToDeviceEvent(event: MXEvent) - // Maybe later add more, like onJoin, onLeave.. } diff --git a/MatrixSDK/MXSession.m b/MatrixSDK/MXSession.m index 1b95ebc2cf..7233e74594 100644 --- a/MatrixSDK/MXSession.m +++ b/MatrixSDK/MXSession.m @@ -327,6 +327,7 @@ - (void)setState:(MXSessionState)state NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; [notificationCenter postNotificationName:kMXSessionStateDidChangeNotification object:self userInfo:nil]; + [_eventStreamService dispatchSessionStateChangedWithState:state]; } } From a5e891071060ee3fb6d92c3ac943a8b8ff8a8313 Mon Sep 17 00:00:00 2001 From: David Langley Date: Wed, 16 Mar 2022 21:08:51 +0000 Subject: [PATCH 5/8] Fix conflict and invalid file reference --- MatrixSDK.xcodeproj/project.pbxproj | 6 ------ 1 file changed, 6 deletions(-) diff --git a/MatrixSDK.xcodeproj/project.pbxproj b/MatrixSDK.xcodeproj/project.pbxproj index 6afaf1bb9e..7e70b7d526 100644 --- a/MatrixSDK.xcodeproj/project.pbxproj +++ b/MatrixSDK.xcodeproj/project.pbxproj @@ -717,8 +717,6 @@ 66836AB827CFA17200515780 /* MXEventStreamService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66836AB527CFA17200515780 /* MXEventStreamService.swift */; }; 66836AB927CFA17200515780 /* MXLiveEventListener.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66836AB627CFA17200515780 /* MXLiveEventListener.swift */; }; 66836ABA27CFA17200515780 /* MXLiveEventListener.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66836AB627CFA17200515780 /* MXLiveEventListener.swift */; }; - 66836ABC27CFA51900515780 /* MXToDeviceService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66836ABB27CFA51900515780 /* MXToDeviceService.swift */; }; - 66836ABD27CFA51900515780 /* MXToDeviceService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66836ABB27CFA51900515780 /* MXToDeviceService.swift */; }; 66AC9D23278CE627002E9B8F /* MXRefreshTokenData.h in Headers */ = {isa = PBXBuildFile; fileRef = 66AC9D21278CE626002E9B8F /* MXRefreshTokenData.h */; }; 66AC9D24278CE627002E9B8F /* MXRefreshTokenData.h in Headers */ = {isa = PBXBuildFile; fileRef = 66AC9D21278CE626002E9B8F /* MXRefreshTokenData.h */; }; 66AC9D25278CE627002E9B8F /* MXRefreshTokenData.m in Sources */ = {isa = PBXBuildFile; fileRef = 66AC9D22278CE626002E9B8F /* MXRefreshTokenData.m */; }; @@ -2332,7 +2330,6 @@ 66398BA727A408C000466E89 /* MXRefreshResponse.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MXRefreshResponse.h; sourceTree = ""; }; 66836AB527CFA17200515780 /* MXEventStreamService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MXEventStreamService.swift; sourceTree = ""; }; 66836AB627CFA17200515780 /* MXLiveEventListener.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MXLiveEventListener.swift; sourceTree = ""; }; - 66836ABB27CFA51900515780 /* MXToDeviceService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MXToDeviceService.swift; sourceTree = ""; }; 66AC9D21278CE626002E9B8F /* MXRefreshTokenData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MXRefreshTokenData.h; sourceTree = ""; }; 66AC9D22278CE626002E9B8F /* MXRefreshTokenData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXRefreshTokenData.m; sourceTree = ""; }; 6869D206EA7C7FB05EAB75B0 /* Pods-MatrixSDKTests-iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MatrixSDKTests-iOS.release.xcconfig"; path = "Target Support Files/Pods-MatrixSDKTests-iOS/Pods-MatrixSDKTests-iOS.release.xcconfig"; sourceTree = ""; }; @@ -4074,7 +4071,6 @@ children = ( 66836AB527CFA17200515780 /* MXEventStreamService.swift */, 66836AB627CFA17200515780 /* MXLiveEventListener.swift */, - 66836ABB27CFA51900515780 /* MXToDeviceService.swift */, ); name = EventStream; path = MatrixSDK/EventStream; @@ -6109,7 +6105,6 @@ ECB5D98C2552C9B4000AD89C /* MXStopwatch.swift in Sources */, B1136964230AC9D900E2B2FA /* MXIdentityServerRestClient.m in Sources */, F0C34CBB1C18C93700C36F09 /* MXSDKOptions.m in Sources */, - 66836ABC27CFA51900515780 /* MXToDeviceService.swift in Sources */, B16F35A225F916A00029AE98 /* MXRoomTypeMapper.swift in Sources */, ECD289BF26FDE5F700F268CF /* MXStoreRoomListDataCounts.swift in Sources */, 320BBF441D6C81550079890E /* MXEventsEnumeratorOnArray.m in Sources */, @@ -6630,7 +6625,6 @@ EC60ED6A265CFC7200B39A4E /* MXPresenceSyncResponse.m in Sources */, 3A108AA525810FE5005EEBE9 /* MXRawDataKey.m in Sources */, 324DD29C246AD2B500377005 /* MXSecretStorage.m in Sources */, - 66836ABD27CFA51900515780 /* MXToDeviceService.swift in Sources */, EC60EDC9265CFEA800B39A4E /* MXRoomSyncUnreadNotifications.m in Sources */, B14EF26F2397E90400758AF0 /* MXUser.m in Sources */, 324AAC772399140D00380A66 /* MXKeyVerificationDone.m in Sources */, From 47964a4c71c09c06d8932a18ad6809c74cea2c39 Mon Sep 17 00:00:00 2001 From: David Langley Date: Wed, 16 Mar 2022 21:43:20 +0000 Subject: [PATCH 6/8] Update documentation --- MatrixSDK/EventStream/MXEventStreamService.swift | 1 + MatrixSDK/EventStream/MXLiveEventListener.swift | 6 +++++- MatrixSDK/MXSession.h | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/MatrixSDK/EventStream/MXEventStreamService.swift b/MatrixSDK/EventStream/MXEventStreamService.swift index 6143a940f6..5d5116ad0e 100644 --- a/MatrixSDK/EventStream/MXEventStreamService.swift +++ b/MatrixSDK/EventStream/MXEventStreamService.swift @@ -16,6 +16,7 @@ import Foundation +/// Manages the adding, removing MXLiveEventListeners and dispatching of events to those listeners. @objcMembers public class MXEventStreamService: NSObject { var listeners = [MXLiveEventListener]() diff --git a/MatrixSDK/EventStream/MXLiveEventListener.swift b/MatrixSDK/EventStream/MXLiveEventListener.swift index fa14517c54..3b7bb85bd1 100644 --- a/MatrixSDK/EventStream/MXLiveEventListener.swift +++ b/MatrixSDK/EventStream/MXLiveEventListener.swift @@ -14,12 +14,16 @@ // limitations under the License. // +/// Protocol used to monitor events of a specific session public protocol MXLiveEventListener: AnyObject { + /// Monitor changes to session state func onSessionStateChanged(state: MXSessionState) + /// Monitor decryption attempts func onLiveEventDecryptionAttempted(event: MXEvent, result:MXEventDecryptionResult) - + + /// Monitor to device events func onLiveToDeviceEvent(event: MXEvent) } diff --git a/MatrixSDK/MXSession.h b/MatrixSDK/MXSession.h index 10447ff5c4..e3563036a7 100644 --- a/MatrixSDK/MXSession.h +++ b/MatrixSDK/MXSession.h @@ -495,7 +495,7 @@ FOUNDATION_EXPORT NSString *const kMXSessionNoRoomTag; @property (nonatomic, readonly) MXThreadingService *threadingService NS_REFINED_FOR_SWIFT; /** - Service to observe events. + Service used to monitor live events of the session. */ @property (nonatomic, readonly) MXEventStreamService *eventStreamService; From 19574c64ae4e49b46095a0bbfbc3e697cd737f47 Mon Sep 17 00:00:00 2001 From: David Langley Date: Mon, 21 Mar 2022 14:45:27 +0000 Subject: [PATCH 7/8] Make bug report client init nonnull --- MatrixSDK/Utils/MXBugReportRestClient.h | 2 +- MatrixSDK/Utils/MXBugReportRestClient.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MatrixSDK/Utils/MXBugReportRestClient.h b/MatrixSDK/Utils/MXBugReportRestClient.h index b3841f0e0d..0e0e294baf 100644 --- a/MatrixSDK/Utils/MXBugReportRestClient.h +++ b/MatrixSDK/Utils/MXBugReportRestClient.h @@ -51,7 +51,7 @@ typedef enum : NSUInteger @param bugReportEndpoint the endpoint URL. @return a MXBugReportRestClient instance. */ -- (instancetype)initWithBugReportEndpoint:(NSString *)bugReportEndpoint; +- (nonnull instancetype)initWithBugReportEndpoint:(NSString *)bugReportEndpoint; /** Send a bug report. diff --git a/MatrixSDK/Utils/MXBugReportRestClient.m b/MatrixSDK/Utils/MXBugReportRestClient.m index 8503b60f37..51c6e4c5b3 100644 --- a/MatrixSDK/Utils/MXBugReportRestClient.m +++ b/MatrixSDK/Utils/MXBugReportRestClient.m @@ -59,7 +59,7 @@ @interface MXBugReportRestClient () @implementation MXBugReportRestClient -- (instancetype)initWithBugReportEndpoint:(NSString *)theBugReportEndpoint +- (nonnull instancetype)initWithBugReportEndpoint:(NSString *)theBugReportEndpoint { self = [super init]; if (self) From 0c63debc5f0d27fc54d28c1e2dc1fa1bee0b5ccb Mon Sep 17 00:00:00 2001 From: David Langley Date: Mon, 21 Mar 2022 17:12:11 +0000 Subject: [PATCH 8/8] Move to `MXMulticastDelegate` which is the convention and manages weak references to the listeners. --- .../EventStream/MXEventStreamService.swift | 20 +++++++------------ .../EventStream/MXLiveEventListener.swift | 1 + 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/MatrixSDK/EventStream/MXEventStreamService.swift b/MatrixSDK/EventStream/MXEventStreamService.swift index 5d5116ad0e..d01c2cdede 100644 --- a/MatrixSDK/EventStream/MXEventStreamService.swift +++ b/MatrixSDK/EventStream/MXEventStreamService.swift @@ -19,32 +19,26 @@ import Foundation /// Manages the adding, removing MXLiveEventListeners and dispatching of events to those listeners. @objcMembers public class MXEventStreamService: NSObject { - var listeners = [MXLiveEventListener]() - + private let multicastDelegate: MXMulticastDelegate = MXMulticastDelegate() + public func add(eventStreamListener: MXLiveEventListener) { - listeners.append(eventStreamListener) + multicastDelegate.addDelegate(eventStreamListener) } public func remove(eventStreamListener: MXLiveEventListener) { - listeners.removeAll { $0 === eventStreamListener } + multicastDelegate.removeDelegate(eventStreamListener) } public func dispatchSessionStateChanged(state: MXSessionState) { - listeners.forEach { listener in - listener.onSessionStateChanged(state: state) - } + multicastDelegate.invoke({ listener in listener.onSessionStateChanged(state: state) }) } public func dispatchLiveEventDecryptionAttempted(event: MXEvent, result: MXEventDecryptionResult) { - listeners.forEach { listener in - listener.onLiveEventDecryptionAttempted(event: event, result: result) - } + multicastDelegate.invoke({ listener in listener.onLiveEventDecryptionAttempted(event: event, result: result) }) } public func dispatchOnLiveToDevice(event: MXEvent) { - listeners.forEach { listener in - listener.onLiveToDeviceEvent(event: event) - } + multicastDelegate.invoke({ listener in listener.onLiveToDeviceEvent(event: event)}) } } diff --git a/MatrixSDK/EventStream/MXLiveEventListener.swift b/MatrixSDK/EventStream/MXLiveEventListener.swift index 3b7bb85bd1..9d790ddb5e 100644 --- a/MatrixSDK/EventStream/MXLiveEventListener.swift +++ b/MatrixSDK/EventStream/MXLiveEventListener.swift @@ -15,6 +15,7 @@ // /// Protocol used to monitor events of a specific session +@objc public protocol MXLiveEventListener: AnyObject { /// Monitor changes to session state