Cleanup following the AppMediator introduction (#2723)

- stop using multiple background task, the appCoordinator sync one is enough for the whole app
- move the AppMeditor to the MainActor
- expose the WindowManager through the AppMediator
- hide sensitive WindowManager API behind a different protocol
- remove the now unnecessary `BackgroundTaskService`
This commit is contained in:
Stefan Ceriu 2024-04-22 18:10:24 +03:00 committed by GitHub
parent a3ec0b8505
commit 8ba544bc44
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
34 changed files with 117 additions and 929 deletions

View File

@ -50,7 +50,6 @@
07CC13C5729C24255348CBBD /* ElementCallWidgetDriver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 309AD8BAE6437C31BA7157BF /* ElementCallWidgetDriver.swift */; };
086D01E79C8E8D3F004FAF21 /* AudioPlayerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC9104846487244648D32C6D /* AudioPlayerProtocol.swift */; };
08CB4BD12CEEDE6AAE4A18DD /* WindowManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 035177BCD8E8308B098AC3C2 /* WindowManager.swift */; };
08E02C56E8B277A22C5E5BA5 /* BackgroundTaskProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83D7FA960FE1A1A63622CC5E /* BackgroundTaskProtocol.swift */; };
095C0ACFC234E0550A6404C5 /* AppCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FC803282F9268D49F4ABF14 /* AppCoordinator.swift */; };
095D3906CF2F940C2D2D17CC /* RoomFlowCoordinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FCB2126C091EEF2454B4D56 /* RoomFlowCoordinatorTests.swift */; };
09713669577CDA8D012EE380 /* MatrixRustSDK in Frameworks */ = {isa = PBXBuildFile; productRef = 6647C55D93508C7CE9D954A5 /* MatrixRustSDK */; };
@ -81,7 +80,6 @@
0EE5EBA18BA1FE10254BB489 /* UIFont+AttributedStringBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = E8CA187FE656EE5A3F6C7DE5 /* UIFont+AttributedStringBuilder.m */; };
0EEC614342F823E5BF966C2C /* AppLockTimerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A5B4CD611DE7E94F5BA87B2 /* AppLockTimerTests.swift */; };
0F6C8033FA60CFD36F7CA205 /* AppLockSetupPINScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A019A12C866D64CF072024B9 /* AppLockSetupPINScreenViewModel.swift */; };
0F9E38A75337D0146652ACAB /* BackgroundTaskTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DFCAA239095A116976E32C4 /* BackgroundTaskTests.swift */; };
10D60D287025B71F4743A425 /* RoomDirectorySearchProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 471BB7276C97AF60B3A5463B /* RoomDirectorySearchProxy.swift */; };
1146E9EDCF8344F7D6E0D553 /* MockCoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0376C429FAB1687C3D905F3E /* MockCoder.swift */; };
119AE9A3FC6E0606C1146528 /* NotificationSettingsEditScreenRoomCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C97F8963B14EB0AF3940DDBF /* NotificationSettingsEditScreenRoomCell.swift */; };
@ -330,7 +328,6 @@
4E0D9E09B52CEC4C0E6211A8 /* MediaPickerScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64F49FB9EE2913234F06CE68 /* MediaPickerScreenCoordinator.swift */; };
4E36A66E0EDA74BF3A036FD0 /* RoomChangeRolesScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AAD8C633AA57948B34EDCF7 /* RoomChangeRolesScreenViewModelProtocol.swift */; };
4E8A2A2CFEB212F14E49E1A1 /* AppLockSetupSettingsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5484457C81B325660901B161 /* AppLockSetupSettingsScreen.swift */; };
4E8F17EBA24FBBA6ABB62ECB /* MockBackgroundTaskService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3948D16F021DFDB2CD26EAA8 /* MockBackgroundTaskService.swift */; };
4E945AD6862C403F74E57755 /* RoomTimelineItemFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 105B2A8426404EF66F00CFDB /* RoomTimelineItemFactory.swift */; };
4EA1CE0E88EA68E862FF0EA2 /* NotificationSettingsEditScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B564D748B67A156F413CD97 /* NotificationSettingsEditScreenModels.swift */; };
4F2DF6138E87A4B8C2488CA3 /* VoiceMessageCacheProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43A84EE187D0C772E18A4E39 /* VoiceMessageCacheProtocol.swift */; };
@ -751,7 +748,6 @@
B22D857D1E8FCA6DD74A58E3 /* UserSessionScreenTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F899D02CF26EA7675EEBE74C /* UserSessionScreenTests.swift */; };
B245583C63F8F90357B87FAE /* KZFileWatchers in Frameworks */ = {isa = PBXBuildFile; productRef = A2AE110B053B55E38F8D10C7 /* KZFileWatchers */; };
B2F8E01ABA1BA30265B4ECBE /* RoundedCornerShape.swift in Sources */ = {isa = PBXBuildFile; fileRef = 839E2C35DF3F9C7B54C3CE49 /* RoundedCornerShape.swift */; };
B3066502FA56D9199846C5E7 /* BackgroundTaskProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83D7FA960FE1A1A63622CC5E /* BackgroundTaskProtocol.swift */; };
B3D652AA1654270742072FB3 /* DeveloperOptionsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86A6F283BC574FDB96ABBB07 /* DeveloperOptionsScreenViewModel.swift */; };
B3EDDEC1839BB5A3747624BB /* FormButtonStyles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95A1CCDEE545CB6453B084BF /* FormButtonStyles.swift */; };
B402708F8728DD0DB7C324E2 /* StartChatScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78910787F967CBC6042A101E /* StartChatScreenViewModelProtocol.swift */; };
@ -850,7 +846,6 @@
C9F5B48D15B9BCAE1F8D564E /* RoomNotificationModeProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1511766C534367700C8DD75 /* RoomNotificationModeProxy.swift */; };
CA12AE0DCD57D49CD96C699A /* WaveformCursorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB9EABCA9348DFA27439A809 /* WaveformCursorView.swift */; };
CA5BFF0C2EF5A8EF40CA2D69 /* VoiceMessageRecordingComposer.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCB6F36CCE44A29A06FCAF1C /* VoiceMessageRecordingComposer.swift */; };
CB0C53B67DA62F7E30DDD720 /* UIKitBackgroundTaskService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3199367BC31381F67C870976 /* UIKitBackgroundTaskService.swift */; };
CB137BFB3E083C33E398A6CB /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 020597E28A4BC8E1BE8EDF6E /* KeychainAccess */; };
CB498F4E27AA0545DCEF0F6F /* DTCoreText in Frameworks */ = {isa = PBXBuildFile; productRef = 36B7FC232711031AA2B0D188 /* DTCoreText */; };
CB6BCBF28E4B76EA08C2926D /* StateRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = B16048D30F0438731C41F775 /* StateRoomTimelineItem.swift */; };
@ -910,11 +905,9 @@
D5FE90A6AF5FD5AE91BD37C7 /* NotificationSettingsEditScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 780258F1B9D15E30549FF4BE /* NotificationSettingsEditScreenViewModel.swift */; };
D63974A88CF2BC721F109C77 /* Compound in Frameworks */ = {isa = PBXBuildFile; productRef = DCA3C4A997AD28E6918D4CE5 /* Compound */; };
D6661A94DBD97658B2ADBD6A /* MapTilerStaticMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A4D29F2683F5772AC72406F /* MapTilerStaticMap.swift */; };
D798A150BB6569FC07CBEB25 /* BackgroundTaskServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23C089E93ECE0EF83E182ED /* BackgroundTaskServiceProtocol.swift */; };
D7CDBAE82782BD0529DECB5F /* AttributedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52BD6ED18E2EB61E28C340AD /* AttributedString.swift */; };
D8359F67AF3A83516E9083C1 /* MockUserSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4756C5A8C8649AD6C10C615 /* MockUserSession.swift */; };
D876EC0FED3B6D46C806912A /* AvatarSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = E24B88AD3D1599E8CB1376E0 /* AvatarSize.swift */; };
D8ED2FCF46D63A7357E9D502 /* BackgroundTaskServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23C089E93ECE0EF83E182ED /* BackgroundTaskServiceProtocol.swift */; };
D9473FC9B077A6EDB7A12001 /* LocationRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 772334731A8BF8E6D90B194D /* LocationRoomTimelineView.swift */; };
D98B5EE8C4F5A2CE84687AE8 /* UTType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 897DF5E9A70CE05A632FC8AF /* UTType.swift */; };
D9F80CE61BF8FF627FDB0543 /* LoadableImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C352359663A0E52BA20761EE /* LoadableImage.swift */; };
@ -955,7 +948,6 @@
E3AC72E3E58F364EF15C1CC7 /* NotificationSettingsScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 514363244AE7D68080D44C6F /* NotificationSettingsScreenViewModelTests.swift */; };
E3CA565A4B9704F191B191F0 /* JoinedRoomSize+MemberCount.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBF9AEA706926DD0DA2B954C /* JoinedRoomSize+MemberCount.swift */; };
E3E1E255DC8CB34BD8573E0D /* UserIndicatorControllerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = A12D3B1BCF920880CA8BBB6B /* UserIndicatorControllerProtocol.swift */; };
E3E3D645C7F80DD64A86D936 /* UIKitBackgroundTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB49AE5D902C0FE40AF4ADF5 /* UIKitBackgroundTask.swift */; };
E45C9FA22BC13B477FD3B4AC /* EmojiDetection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D99730313BEBF08CDE81EE3 /* EmojiDetection.swift */; };
E468CC731C3F4D678499E52F /* LAContextMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BA5A62DA4B543827FF82354 /* LAContextMock.swift */; };
E481C8FDCB6C089963C95344 /* DeviceKit in Frameworks */ = {isa = PBXBuildFile; productRef = BC01130651CB23340B899032 /* DeviceKit */; };
@ -1339,7 +1331,6 @@
30ED584467DB380E3CEFB1DB /* NotificationManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationManagerTests.swift; sourceTree = "<group>"; };
314F1C79850BE46E8ABEAFCB /* ReadReceipt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadReceipt.swift; sourceTree = "<group>"; };
317F41A4B5C4F457AF710666 /* PollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollView.swift; sourceTree = "<group>"; };
3199367BC31381F67C870976 /* UIKitBackgroundTaskService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIKitBackgroundTaskService.swift; sourceTree = "<group>"; };
31A6314FDC51DA25712D9A81 /* PillContextTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PillContextTests.swift; sourceTree = "<group>"; };
31D6764D6976D235926FE5FC /* HomeScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenViewModel.swift; sourceTree = "<group>"; };
3203C6566DC17B7AECC1B7FD /* RoomNotificationSettingsUserDefinedScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomNotificationSettingsUserDefinedScreen.swift; sourceTree = "<group>"; };
@ -1369,7 +1360,6 @@
38345442415E07A931197C55 /* AppLockScreenPINKeypad.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockScreenPINKeypad.swift; sourceTree = "<group>"; };
38354164AF59C5006CD05878 /* GlobalSearchScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlobalSearchScreenViewModel.swift; sourceTree = "<group>"; };
38E521D6C2BF8DF0DFB35146 /* DeveloperOptionsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeveloperOptionsScreen.swift; sourceTree = "<group>"; };
3948D16F021DFDB2CD26EAA8 /* MockBackgroundTaskService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockBackgroundTaskService.swift; sourceTree = "<group>"; };
3984C93B8E9B10C92DADF9EE /* RoomDirectorySearchScreenScreenModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDirectorySearchScreenScreenModelProtocol.swift; sourceTree = "<group>"; };
398817652FA8ABAE0A31AC6D /* ReadableFrameModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadableFrameModifier.swift; sourceTree = "<group>"; };
39C0D861FC397AC34BCF089E /* KeychainControllerMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainControllerMock.swift; sourceTree = "<group>"; };
@ -1561,7 +1551,6 @@
6DC30DEC0097B9D217493007 /* ResetRecoveryKeyScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResetRecoveryKeyScreen.swift; sourceTree = "<group>"; };
6DF438EAFC732D2D95D34BF6 /* StartChatViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StartChatViewModelTests.swift; sourceTree = "<group>"; };
6DF81D7F2A6BA9DE3F6F8D9D /* InvitesScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvitesScreenViewModel.swift; sourceTree = "<group>"; };
6DFCAA239095A116976E32C4 /* BackgroundTaskTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundTaskTests.swift; sourceTree = "<group>"; };
6E2656184491C505700D2405 /* CollapsibleRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollapsibleRoomTimelineView.swift; sourceTree = "<group>"; };
6E5725BC6C63604CB769145B /* LegalInformationScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegalInformationScreenViewModelTests.swift; sourceTree = "<group>"; };
6E5E9C044BEB7C70B1378E91 /* UserSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSession.swift; sourceTree = "<group>"; };
@ -1645,7 +1634,6 @@
8319173DD66C07F45DC48848 /* IdentityConfirmedScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentityConfirmedScreenViewModelProtocol.swift; sourceTree = "<group>"; };
837B440C4705E4B899BCB899 /* RoomDetailsScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetailsScreenViewModel.swift; sourceTree = "<group>"; };
839E2C35DF3F9C7B54C3CE49 /* RoundedCornerShape.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoundedCornerShape.swift; sourceTree = "<group>"; };
83D7FA960FE1A1A63622CC5E /* BackgroundTaskProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundTaskProtocol.swift; sourceTree = "<group>"; };
84311D707B09854D67F78BBF /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = "<group>"; };
845DDBDE5A0887E73D38B826 /* InviteUsersViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InviteUsersViewModelTests.swift; sourceTree = "<group>"; };
848F69921527D31CAACB93AF /* SecureBackupLogoutConfirmationScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureBackupLogoutConfirmationScreenViewModelTests.swift; sourceTree = "<group>"; };
@ -1965,7 +1953,6 @@
D196116D2DD3F2757D45FCB7 /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/SAS.strings; sourceTree = "<group>"; };
D1BC84BA0AF11C2128D58ABD /* Common.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Common.swift; sourceTree = "<group>"; };
D1D8479BB704B7EF696F8ABE /* RoomPollsHistoryScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomPollsHistoryScreenCoordinator.swift; sourceTree = "<group>"; };
D23C089E93ECE0EF83E182ED /* BackgroundTaskServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundTaskServiceProtocol.swift; sourceTree = "<group>"; };
D263254AFE5B7993FFBBF324 /* NSE.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NSE.entitlements; sourceTree = "<group>"; };
D26813CCE39221FE30BF22CD /* PlatformViewVersionPredicate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlatformViewVersionPredicate.swift; sourceTree = "<group>"; };
D28F7A6CEEA4A2815B0F0F55 /* SettingsFlowCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsFlowCoordinator.swift; sourceTree = "<group>"; };
@ -2067,7 +2054,6 @@
EA880E78AF4BD24E45A7808C /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bg; path = bg.lproj/InfoPlist.strings; sourceTree = "<group>"; };
EAF710CB1C31F8938EAA3A7D /* RoomChangeRolesScreenSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomChangeRolesScreenSection.swift; sourceTree = "<group>"; };
EB3B237387B8288A5A938F1B /* UserAgentBuilderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserAgentBuilderTests.swift; sourceTree = "<group>"; };
EB49AE5D902C0FE40AF4ADF5 /* UIKitBackgroundTask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIKitBackgroundTask.swift; sourceTree = "<group>"; };
EB63761D9F9CE8B23CBD6179 /* PollFormScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollFormScreenModels.swift; sourceTree = "<group>"; };
EB76A9AFC6CCAD4998D9B045 /* IdentityConfirmationScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentityConfirmationScreenViewModel.swift; sourceTree = "<group>"; };
EBEB8D9F4940E161B18FE4BC /* UITestsNotificationCenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITestsNotificationCenter.swift; sourceTree = "<group>"; };
@ -2327,7 +2313,6 @@
7803E03F759061C948D66B7E /* AppLock */,
FCE7249621F507F34A8122FB /* Audio */,
AAFDD509929A0CCF8BCE51EB /* Authentication */,
C488FC0F4ACF26D0A2C5246E /* BackgroundTasks */,
0ED3F5C21537519389C07644 /* BugReport */,
8039515BAA53B7C3275AC64A /* Client */,
8C3BAE06B336D97DABBE2509 /* CreateRoom */,
@ -3551,7 +3536,6 @@
C55CC239AE12339C565F6C9A /* AudioRecorderStateTests.swift */,
2441E2424E78A40FC95DBA76 /* AudioRecorderTests.swift */,
8FB89DC7F9A4A91020037001 /* AuthenticationStartScreenViewModelTests.swift */,
6DFCAA239095A116976E32C4 /* BackgroundTaskTests.swift */,
240610DF32F3213BEC5611D7 /* BlockedUsersScreenViewModelTests.swift */,
EFFD3200F9960D4996159F10 /* BugReportServiceTests.swift */,
7AB7ED3A898B07976F3AA90F /* BugReportViewModelTests.swift */,
@ -3689,7 +3673,6 @@
children = (
3EF1AC723C2609C7705569CA /* MediaLoaderTests.swift */,
62A81CCC2516D9CF9322DF01 /* MediaProviderTests.swift */,
3948D16F021DFDB2CD26EAA8 /* MockBackgroundTaskService.swift */,
AC1DA29A5A041CC0BACA7CB0 /* MockImageCache.swift */,
4AB7D7DAAAF662DED9D02379 /* MockMediaLoader.swift */,
);
@ -4672,17 +4655,6 @@
path = RoomDirectorySearchScreen;
sourceTree = "<group>";
};
C488FC0F4ACF26D0A2C5246E /* BackgroundTasks */ = {
isa = PBXGroup;
children = (
83D7FA960FE1A1A63622CC5E /* BackgroundTaskProtocol.swift */,
D23C089E93ECE0EF83E182ED /* BackgroundTaskServiceProtocol.swift */,
EB49AE5D902C0FE40AF4ADF5 /* UIKitBackgroundTask.swift */,
3199367BC31381F67C870976 /* UIKitBackgroundTaskService.swift */,
);
path = BackgroundTasks;
sourceTree = "<group>";
};
C844840F3DD48A154C65AE0C /* View */ = {
isa = PBXGroup;
children = (
@ -5661,8 +5633,6 @@
CDCA8A559E098503DDE29477 /* AttributedStringBuilder.swift in Sources */,
BA43D782BE85C7F5F20C624A /* AttributedStringBuilderProtocol.swift in Sources */,
968A5B890004526AB58A217C /* AvatarSize.swift in Sources */,
08E02C56E8B277A22C5E5BA5 /* BackgroundTaskProtocol.swift in Sources */,
D8ED2FCF46D63A7357E9D502 /* BackgroundTaskServiceProtocol.swift in Sources */,
9A3B0CDF097E3838FB1B9595 /* Bundle.swift in Sources */,
B5618E3C948584E5C1F67033 /* DTHTMLElement+AttributedStringBuilder.swift in Sources */,
DFCA89C4EC2A5332ED6B441F /* DataProtectionManager.swift in Sources */,
@ -5736,7 +5706,6 @@
3042527CB344A9EF1157FC26 /* AudioRecorderStateTests.swift in Sources */,
192A3CDCD0174AD1E4A128E4 /* AudioRecorderTests.swift in Sources */,
8ED8AF57A06F5EE9978ED23F /* AuthenticationStartScreenViewModelTests.swift in Sources */,
0F9E38A75337D0146652ACAB /* BackgroundTaskTests.swift in Sources */,
CEAEA57B7665C8E790599A78 /* BlockedUsersScreenViewModelTests.swift in Sources */,
7F61F9ACD5EC9E845EF3EFBF /* BugReportServiceTests.swift in Sources */,
C7CFDB4929DDD9A3B5BA085D /* BugReportViewModelTests.swift in Sources */,
@ -5772,7 +5741,6 @@
B9A8C34A00D03094C0CF56F3 /* MediaUploadPreviewScreenViewModelTests.swift in Sources */,
23701DE32ACD6FD40AA992C3 /* MediaUploadingPreprocessorTests.swift in Sources */,
F777C6FEE7D106136E2ED2B2 /* MessageForwardingScreenViewModelTests.swift in Sources */,
4E8F17EBA24FBBA6ABB62ECB /* MockBackgroundTaskService.swift in Sources */,
1146E9EDCF8344F7D6E0D553 /* MockCoder.swift in Sources */,
DC68E866D6E664B0D2B06E74 /* MockImageCache.swift in Sources */,
A896998A6784DB6F16E912F4 /* MockMediaLoader.swift in Sources */,
@ -5944,8 +5912,6 @@
6146996D5C4DDD5DA816FC87 /* AuthenticationTextFieldStyle.swift in Sources */,
4AAA8606FBA290E23D15422E /* AvatarHeaderView.swift in Sources */,
D876EC0FED3B6D46C806912A /* AvatarSize.swift in Sources */,
B3066502FA56D9199846C5E7 /* BackgroundTaskProtocol.swift in Sources */,
D798A150BB6569FC07CBEB25 /* BackgroundTaskServiceProtocol.swift in Sources */,
A4B0BAD62A12ED76BD611B79 /* BadgeView.swift in Sources */,
38546A6010A2CF240EC9AF73 /* BindableState.swift in Sources */,
EB9F4688006B52E69DF5358F /* BlankFormCoordinator.swift in Sources */,
@ -6541,8 +6507,6 @@
36AC963F2F04069B7FF1AA0C /* UIConstants.swift in Sources */,
A37EED79941AD3B7140B3822 /* UIDevice.swift in Sources */,
0EE5EBA18BA1FE10254BB489 /* UIFont+AttributedStringBuilder.m in Sources */,
E3E3D645C7F80DD64A86D936 /* UIKitBackgroundTask.swift in Sources */,
CB0C53B67DA62F7E30DDD720 /* UIKitBackgroundTaskService.swift in Sources */,
E96005321849DBD7C72A28F2 /* UITestsAppCoordinator.swift in Sources */,
384D6B9A7DFD7260139D6852 /* UITestsNotificationCenter.swift in Sources */,
22882C710BC99EC34A5024A0 /* UITestsScreenIdentifier.swift in Sources */,

View File

@ -20,7 +20,7 @@ import MatrixRustSDK
import SwiftUI
import Version
class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDelegate, NotificationManagerDelegate, WindowManagerDelegate {
class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDelegate, NotificationManagerDelegate, SecureWindowManagerDelegate {
private let stateMachine: AppCoordinatorStateMachine
private let navigationRootCoordinator: NavigationRootCoordinator
private let userSessionStore: UserSessionStoreProtocol
@ -29,7 +29,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
private let appDelegate: AppDelegate
/// Common background task to continue long-running tasks in the background.
private var backgroundTask: BackgroundTaskProtocol?
private var backgroundTask: UIBackgroundTaskIdentifier?
private var isSuspended = false
@ -50,15 +50,12 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
private var appLockSetupFlowCoordinator: AppLockSetupFlowCoordinator?
private var userSessionFlowCoordinator: UserSessionFlowCoordinator?
private var softLogoutCoordinator: SoftLogoutScreenCoordinator?
private let backgroundTaskService: BackgroundTaskServiceProtocol
private var appDelegateObserver: AnyCancellable?
private var userSessionObserver: AnyCancellable?
private var clientProxyObserver: AnyCancellable?
private var cancellables = Set<AnyCancellable>()
let windowManager: WindowManagerProtocol
let windowManager: SecureWindowManagerProtocol
let notificationManager: NotificationManagerProtocol
private let appRouteURLParser: AppRouteURLParser
@ -103,12 +100,9 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
navigationRootCoordinator.setRootCoordinator(SplashScreenCoordinator())
backgroundTaskService = UIKitBackgroundTaskService(appMediator: appMediator)
let keychainController = KeychainController(service: .sessions,
accessGroup: InfoPlistReader.main.keychainAccessGroupIdentifier)
userSessionStore = UserSessionStore(keychainController: keychainController,
backgroundTaskService: backgroundTaskService)
userSessionStore = UserSessionStore(keychainController: keychainController)
let appLockService = AppLockService(keychainController: keychainController, appSettings: appSettings)
let appLockNavigationCoordinator = NavigationRootCoordinator()
@ -227,7 +221,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
// MARK: - WindowManagerDelegate
func windowManagerDidConfigureWindows(_ windowManager: WindowManagerProtocol) {
func windowManagerDidConfigureWindows(_ windowManager: SecureWindowManagerProtocol) {
windowManager.alternateWindow.rootViewController = UIHostingController(rootView: appLockFlowCoordinator.toPresentable())
ServiceLocator.shared.userIndicatorController.window = windowManager.overlayWindow
}
@ -413,8 +407,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
appMediator: appMediator,
appSettings: appSettings,
analytics: ServiceLocator.shared.analytics,
userIndicatorController: ServiceLocator.shared.userIndicatorController,
orientationManager: windowManager)
userIndicatorController: ServiceLocator.shared.userIndicatorController)
authenticationFlowCoordinator?.delegate = self
authenticationFlowCoordinator?.start()
@ -469,7 +462,6 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
let userSessionFlowCoordinator = UserSessionFlowCoordinator(userSession: userSession,
navigationRootCoordinator: navigationRootCoordinator,
windowManager: windowManager,
appLockService: appLockFlowCoordinator.appLockService,
bugReportService: ServiceLocator.shared.bugReportService,
roomTimelineControllerFactory: RoomTimelineControllerFactory(),
@ -771,13 +763,15 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
return
}
backgroundTask = backgroundTaskService.startBackgroundTask(withName: "SuspendApp: \(UUID().uuidString)") { [weak self] in
backgroundTask = appMediator.beginBackgroundTask { [weak self] in
guard let self else { return }
stopSync()
backgroundTask?.stop()
backgroundTask = nil
if let backgroundTask {
appMediator.endBackgroundTask(backgroundTask)
self.backgroundTask = nil
}
}
isSuspended = true
@ -791,8 +785,10 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
private func applicationDidBecomeActive() {
MXLog.info("Application did become active")
backgroundTask?.stop()
backgroundTask = nil
if let backgroundTask {
appMediator.endBackgroundTask(backgroundTask)
self.backgroundTask = nil
}
if isSuspended {
startSync()

View File

@ -17,6 +17,6 @@
import Foundation
protocol AppCoordinatorProtocol: CoordinatorProtocol {
var windowManager: WindowManagerProtocol { get }
var windowManager: SecureWindowManagerProtocol { get }
@discardableResult func handleDeepLink(_ url: URL, isExternalURL: Bool) -> Bool
}

View File

@ -17,7 +17,7 @@
import UIKit
class AppMediator: AppMediatorProtocol {
private let windowManager: WindowManagerProtocol
let windowManager: WindowManagerProtocol
init(windowManager: WindowManagerProtocol) {
self.windowManager = windowManager
@ -28,7 +28,6 @@ class AppMediator: AppMediatorProtocol {
UIApplication.shared
}
@MainActor
var appState: UIApplication.State {
switch application.applicationState {
case .active:
@ -42,12 +41,8 @@ class AppMediator: AppMediatorProtocol {
}
}
var backgroundTimeRemaining: TimeInterval {
application.backgroundTimeRemaining
}
func beginBackgroundTask(withName taskName: String?, expirationHandler handler: (() -> Void)?) -> UIBackgroundTaskIdentifier {
application.beginBackgroundTask(withName: taskName, expirationHandler: handler)
func beginBackgroundTask(expirationHandler handler: (() -> Void)?) -> UIBackgroundTaskIdentifier {
application.beginBackgroundTask(expirationHandler: handler)
}
func endBackgroundTask(_ identifier: UIBackgroundTaskIdentifier) {

View File

@ -18,12 +18,13 @@ import Foundation
import UIKit
// sourcery: AutoMockable
@MainActor
protocol AppMediatorProtocol {
var windowManager: WindowManagerProtocol { get }
var appState: UIApplication.State { get }
var backgroundTimeRemaining: TimeInterval { get }
func beginBackgroundTask(withName taskName: String?, expirationHandler handler: (() -> Void)?) -> UIBackgroundTaskIdentifier
func beginBackgroundTask(expirationHandler handler: (() -> Void)?) -> UIBackgroundTaskIdentifier
func endBackgroundTask(_ identifier: UIBackgroundTaskIdentifier)

View File

@ -20,7 +20,7 @@ import SwiftUI
///
/// We don't support multiple scenes right now, so the implementation is pretty basic.
class SceneDelegate: NSObject, UIWindowSceneDelegate {
weak static var windowManager: WindowManagerProtocol!
weak static var windowManager: SecureWindowManagerProtocol!
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = scene as? UIWindowScene else { return }

View File

@ -17,10 +17,10 @@
import Combine
import SwiftUI
class WindowManager: WindowManagerProtocol {
class WindowManager: SecureWindowManagerProtocol {
private let appDelegate: AppDelegate
weak var windowScene: UIWindowScene?
weak var delegate: WindowManagerDelegate?
weak var delegate: SecureWindowManagerDelegate?
private(set) var mainWindow: UIWindow!
private(set) var overlayWindow: UIWindow!

View File

@ -16,18 +16,29 @@
import SwiftUI
protocol WindowManagerDelegate: AnyObject {
protocol SecureWindowManagerDelegate: AnyObject {
/// The window manager has configured its windows.
func windowManagerDidConfigureWindows(_ windowManager: WindowManagerProtocol)
func windowManagerDidConfigureWindows(_ windowManager: SecureWindowManagerProtocol)
}
@MainActor
protocol SecureWindowManagerProtocol: WindowManagerProtocol {
var delegate: SecureWindowManagerDelegate? { get set }
/// Configures the window manager to operate on the supplied scene.
func configure(with windowScene: UIWindowScene)
/// Shows the main and overlay window combo, hiding the alternate window.
func switchToMain()
/// Shows the alternate window, hiding the main and overlay combo.
func switchToAlternate()
}
/// A window manager that supports switching between a main app window with an overlay and
/// an alternate window to switch contexts whilst also preserving the main view hierarchy.
/// Heavily inspired by https://www.fivestars.blog/articles/swiftui-windows/
protocol WindowManagerProtocol: AnyObject, OrientationManagerProtocol {
var delegate: WindowManagerDelegate? { get set }
/// The app's main window (we only support a single scene).
var mainWindow: UIWindow! { get }
/// Presented on top of the main window, to display e.g. user indicators.
@ -40,15 +51,6 @@ protocol WindowManagerProtocol: AnyObject, OrientationManagerProtocol {
/// All the windows being managed
var windows: [UIWindow] { get }
/// Configures the window manager to operate on the supplied scene.
func configure(with windowScene: UIWindowScene)
/// Shows the main and overlay window combo, hiding the alternate window.
func switchToMain()
/// Shows the alternate window, hiding the main and overlay combo.
func switchToAlternate()
/// Makes the global search window key. Used to get automatic text field focus.
func showGlobalSearch()

View File

@ -31,7 +31,6 @@ class AuthenticationFlowCoordinator: FlowCoordinatorProtocol {
private let appSettings: AppSettings
private let analytics: AnalyticsService
private let userIndicatorController: UserIndicatorControllerProtocol
private let orientationManager: OrientationManagerProtocol
private var cancellables = Set<AnyCancellable>()
@ -48,8 +47,7 @@ class AuthenticationFlowCoordinator: FlowCoordinatorProtocol {
appMediator: AppMediatorProtocol,
appSettings: AppSettings,
analytics: AnalyticsService,
userIndicatorController: UserIndicatorControllerProtocol,
orientationManager: WindowManagerProtocol) {
userIndicatorController: UserIndicatorControllerProtocol) {
self.authenticationService = authenticationService
self.bugReportService = bugReportService
self.navigationRootCoordinator = navigationRootCoordinator
@ -57,7 +55,6 @@ class AuthenticationFlowCoordinator: FlowCoordinatorProtocol {
self.appSettings = appSettings
self.analytics = analytics
self.userIndicatorController = userIndicatorController
self.orientationManager = orientationManager
navigationStackCoordinator = NavigationStackCoordinator()
}
@ -110,7 +107,7 @@ class AuthenticationFlowCoordinator: FlowCoordinatorProtocol {
private func startQRCodeLogin() {
let coordinator = QRCodeLoginScreenCoordinator(parameters: .init(qrCodeLoginService: QRCodeLoginService(),
orientationManager: orientationManager,
orientationManager: appMediator.windowManager,
appMediator: appMediator))
coordinator.actionsPublisher.sink { [weak self] action in
guard let self else {

View File

@ -50,7 +50,6 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
private let appSettings: AppSettings
private let analytics: AnalyticsService
private let userIndicatorController: UserIndicatorControllerProtocol
private let orientationManager: OrientationManagerProtocol
private var roomProxy: RoomProxyProtocol!
@ -81,8 +80,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
appMediator: AppMediatorProtocol,
appSettings: AppSettings,
analytics: AnalyticsService,
userIndicatorController: UserIndicatorControllerProtocol,
orientationManager: OrientationManagerProtocol) async {
userIndicatorController: UserIndicatorControllerProtocol) async {
self.roomID = roomID
self.userSession = userSession
self.isChildFlow = isChildFlow
@ -93,7 +91,6 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
self.appSettings = appSettings
self.analytics = analytics
self.userIndicatorController = userIndicatorController
self.orientationManager = orientationManager
setupStateMachine()
@ -695,7 +692,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
mediaProvider: userSession.mediaProvider,
navigationStackCoordinator: stackCoordinator,
userIndicatorController: userIndicatorController,
orientationManager: orientationManager)
orientationManager: appMediator.windowManager)
let roomDetailsEditCoordinator = RoomDetailsEditScreenCoordinator(parameters: roomDetailsEditParameters)
roomDetailsEditCoordinator.actions.sink { [weak self] action in
@ -752,7 +749,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
let mediaPickerCoordinator = MediaPickerScreenCoordinator(userIndicatorController: userIndicatorController,
source: source,
orientationManager: orientationManager) { [weak self] action in
orientationManager: appMediator.windowManager) { [weak self] action in
guard let self else {
return
}
@ -1239,8 +1236,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
appMediator: appMediator,
appSettings: appSettings,
analytics: analytics,
userIndicatorController: userIndicatorController,
orientationManager: orientationManager)
userIndicatorController: userIndicatorController)
coordinator.actions.sink { [weak self] action in
guard let self else { return }

View File

@ -28,7 +28,6 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
private let userSession: UserSessionProtocol
private let navigationRootCoordinator: NavigationRootCoordinator
private let navigationSplitCoordinator: NavigationSplitCoordinator
private let windowManager: WindowManagerProtocol
private let bugReportService: BugReportServiceProtocol
private let appMediator: AppMediatorProtocol
private let appSettings: AppSettings
@ -68,7 +67,6 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
init(userSession: UserSessionProtocol,
navigationRootCoordinator: NavigationRootCoordinator,
windowManager: WindowManagerProtocol,
appLockService: AppLockServiceProtocol,
bugReportService: BugReportServiceProtocol,
roomTimelineControllerFactory: RoomTimelineControllerFactoryProtocol,
@ -80,7 +78,6 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
stateMachine = UserSessionFlowCoordinatorStateMachine()
self.userSession = userSession
self.navigationRootCoordinator = navigationRootCoordinator
self.windowManager = windowManager
self.bugReportService = bugReportService
self.roomTimelineControllerFactory = roomTimelineControllerFactory
self.appMediator = appMediator
@ -96,7 +93,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
navigationSplitCoordinator.setSidebarCoordinator(sidebarNavigationStackCoordinator)
settingsFlowCoordinator = SettingsFlowCoordinator(parameters: .init(userSession: userSession,
windowManager: windowManager,
windowManager: appMediator.windowManager,
appLockService: appLockService,
bugReportService: bugReportService,
notificationSettings: userSession.clientProxy.notificationSettings,
@ -427,8 +424,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
appMediator: appMediator,
appSettings: appSettings,
analytics: analytics,
userIndicatorController: ServiceLocator.shared.userIndicatorController,
orientationManager: windowManager)
userIndicatorController: ServiceLocator.shared.userIndicatorController)
coordinator.actions.sink { [weak self] action in
guard let self else { return }
@ -480,7 +476,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
let startChatNavigationStackCoordinator = NavigationStackCoordinator()
let userDiscoveryService = UserDiscoveryService(clientProxy: userSession.clientProxy)
let parameters = StartChatScreenCoordinatorParameters(orientationManager: windowManager,
let parameters = StartChatScreenCoordinatorParameters(orientationManager: appMediator.windowManager,
userSession: userSession,
userIndicatorController: ServiceLocator.shared.userIndicatorController,
navigationStackCoordinator: startChatNavigationStackCoordinator,
@ -609,14 +605,14 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
let hostingController = UIHostingController(rootView: coordinator.toPresentable())
hostingController.view.backgroundColor = .clear
windowManager.globalSearchWindow.rootViewController = hostingController
appMediator.windowManager.globalSearchWindow.rootViewController = hostingController
windowManager.showGlobalSearch()
appMediator.windowManager.showGlobalSearch()
}
private func dismissGlobalSearch() {
windowManager.globalSearchWindow.rootViewController = nil
windowManager.hideGlobalSearch()
appMediator.windowManager.globalSearchWindow.rootViewController = nil
appMediator.windowManager.hideGlobalSearch()
globalSearchScreenCoordinator = nil
}

View File

@ -18,44 +18,11 @@ import UIKit
extension AppMediatorMock {
static var `default`: AppMediatorProtocol {
AppMediatorMock(withState: .active,
backgroundTimeRemaining: 10,
allowTasks: true)
}
let mock = AppMediatorMock()
static var mockBroken: AppMediatorProtocol {
AppMediatorMock(withState: .inactive,
backgroundTimeRemaining: 0,
allowTasks: false)
}
mock.underlyingAppState = .active
mock.underlyingWindowManager = WindowManagerMock()
static var mockAboutToSuspend: AppMediatorProtocol {
AppMediatorMock(withState: .background,
backgroundTimeRemaining: 2,
allowTasks: false)
}
private static var bgTaskIdentifier = 0
convenience init(withState applicationState: UIApplication.State,
backgroundTimeRemaining: TimeInterval,
allowTasks: Bool) {
self.init()
underlyingAppState = applicationState
underlyingBackgroundTimeRemaining = backgroundTimeRemaining
beginBackgroundTaskWithNameExpirationHandlerClosure = { _, handler in
guard allowTasks else {
return .invalid
}
Self.bgTaskIdentifier += 1
let identifier = UIBackgroundTaskIdentifier(rawValue: Self.bgTaskIdentifier)
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
handler?()
}
return identifier
}
return mock
}
}

View File

@ -748,28 +748,28 @@ class AppLockServiceMock: AppLockServiceProtocol {
}
}
class AppMediatorMock: AppMediatorProtocol {
var windowManager: WindowManagerProtocol {
get { return underlyingWindowManager }
set(value) { underlyingWindowManager = value }
}
var underlyingWindowManager: WindowManagerProtocol!
var appState: UIApplication.State {
get { return underlyingAppState }
set(value) { underlyingAppState = value }
}
var underlyingAppState: UIApplication.State!
var backgroundTimeRemaining: TimeInterval {
get { return underlyingBackgroundTimeRemaining }
set(value) { underlyingBackgroundTimeRemaining = value }
}
var underlyingBackgroundTimeRemaining: TimeInterval!
//MARK: - beginBackgroundTask
var beginBackgroundTaskWithNameExpirationHandlerUnderlyingCallsCount = 0
var beginBackgroundTaskWithNameExpirationHandlerCallsCount: Int {
var beginBackgroundTaskExpirationHandlerUnderlyingCallsCount = 0
var beginBackgroundTaskExpirationHandlerCallsCount: Int {
get {
if Thread.isMainThread {
return beginBackgroundTaskWithNameExpirationHandlerUnderlyingCallsCount
return beginBackgroundTaskExpirationHandlerUnderlyingCallsCount
} else {
var returnValue: Int? = nil
DispatchQueue.main.sync {
returnValue = beginBackgroundTaskWithNameExpirationHandlerUnderlyingCallsCount
returnValue = beginBackgroundTaskExpirationHandlerUnderlyingCallsCount
}
return returnValue!
@ -777,27 +777,27 @@ class AppMediatorMock: AppMediatorProtocol {
}
set {
if Thread.isMainThread {
beginBackgroundTaskWithNameExpirationHandlerUnderlyingCallsCount = newValue
beginBackgroundTaskExpirationHandlerUnderlyingCallsCount = newValue
} else {
DispatchQueue.main.sync {
beginBackgroundTaskWithNameExpirationHandlerUnderlyingCallsCount = newValue
beginBackgroundTaskExpirationHandlerUnderlyingCallsCount = newValue
}
}
}
}
var beginBackgroundTaskWithNameExpirationHandlerCalled: Bool {
return beginBackgroundTaskWithNameExpirationHandlerCallsCount > 0
var beginBackgroundTaskExpirationHandlerCalled: Bool {
return beginBackgroundTaskExpirationHandlerCallsCount > 0
}
var beginBackgroundTaskWithNameExpirationHandlerUnderlyingReturnValue: UIBackgroundTaskIdentifier!
var beginBackgroundTaskWithNameExpirationHandlerReturnValue: UIBackgroundTaskIdentifier! {
var beginBackgroundTaskExpirationHandlerUnderlyingReturnValue: UIBackgroundTaskIdentifier!
var beginBackgroundTaskExpirationHandlerReturnValue: UIBackgroundTaskIdentifier! {
get {
if Thread.isMainThread {
return beginBackgroundTaskWithNameExpirationHandlerUnderlyingReturnValue
return beginBackgroundTaskExpirationHandlerUnderlyingReturnValue
} else {
var returnValue: UIBackgroundTaskIdentifier? = nil
DispatchQueue.main.sync {
returnValue = beginBackgroundTaskWithNameExpirationHandlerUnderlyingReturnValue
returnValue = beginBackgroundTaskExpirationHandlerUnderlyingReturnValue
}
return returnValue!
@ -805,22 +805,22 @@ class AppMediatorMock: AppMediatorProtocol {
}
set {
if Thread.isMainThread {
beginBackgroundTaskWithNameExpirationHandlerUnderlyingReturnValue = newValue
beginBackgroundTaskExpirationHandlerUnderlyingReturnValue = newValue
} else {
DispatchQueue.main.sync {
beginBackgroundTaskWithNameExpirationHandlerUnderlyingReturnValue = newValue
beginBackgroundTaskExpirationHandlerUnderlyingReturnValue = newValue
}
}
}
}
var beginBackgroundTaskWithNameExpirationHandlerClosure: ((String?, (() -> Void)?) -> UIBackgroundTaskIdentifier)?
var beginBackgroundTaskExpirationHandlerClosure: (((() -> Void)?) -> UIBackgroundTaskIdentifier)?
func beginBackgroundTask(withName taskName: String?, expirationHandler handler: (() -> Void)?) -> UIBackgroundTaskIdentifier {
beginBackgroundTaskWithNameExpirationHandlerCallsCount += 1
if let beginBackgroundTaskWithNameExpirationHandlerClosure = beginBackgroundTaskWithNameExpirationHandlerClosure {
return beginBackgroundTaskWithNameExpirationHandlerClosure(taskName, handler)
func beginBackgroundTask(expirationHandler handler: (() -> Void)?) -> UIBackgroundTaskIdentifier {
beginBackgroundTaskExpirationHandlerCallsCount += 1
if let beginBackgroundTaskExpirationHandlerClosure = beginBackgroundTaskExpirationHandlerClosure {
return beginBackgroundTaskExpirationHandlerClosure(handler)
} else {
return beginBackgroundTaskWithNameExpirationHandlerReturnValue
return beginBackgroundTaskExpirationHandlerReturnValue
}
}
//MARK: - endBackgroundTask
@ -12976,122 +12976,12 @@ class VoiceMessageRecorderMock: VoiceMessageRecorderProtocol {
}
}
class WindowManagerMock: WindowManagerProtocol {
weak var delegate: WindowManagerDelegate?
var mainWindow: UIWindow!
var overlayWindow: UIWindow!
var globalSearchWindow: UIWindow!
var alternateWindow: UIWindow!
var windows: [UIWindow] = []
//MARK: - configure
var configureWithUnderlyingCallsCount = 0
var configureWithCallsCount: Int {
get {
if Thread.isMainThread {
return configureWithUnderlyingCallsCount
} else {
var returnValue: Int? = nil
DispatchQueue.main.sync {
returnValue = configureWithUnderlyingCallsCount
}
return returnValue!
}
}
set {
if Thread.isMainThread {
configureWithUnderlyingCallsCount = newValue
} else {
DispatchQueue.main.sync {
configureWithUnderlyingCallsCount = newValue
}
}
}
}
var configureWithCalled: Bool {
return configureWithCallsCount > 0
}
var configureWithReceivedWindowScene: UIWindowScene?
var configureWithReceivedInvocations: [UIWindowScene] = []
var configureWithClosure: ((UIWindowScene) -> Void)?
func configure(with windowScene: UIWindowScene) {
configureWithCallsCount += 1
configureWithReceivedWindowScene = windowScene
configureWithReceivedInvocations.append(windowScene)
configureWithClosure?(windowScene)
}
//MARK: - switchToMain
var switchToMainUnderlyingCallsCount = 0
var switchToMainCallsCount: Int {
get {
if Thread.isMainThread {
return switchToMainUnderlyingCallsCount
} else {
var returnValue: Int? = nil
DispatchQueue.main.sync {
returnValue = switchToMainUnderlyingCallsCount
}
return returnValue!
}
}
set {
if Thread.isMainThread {
switchToMainUnderlyingCallsCount = newValue
} else {
DispatchQueue.main.sync {
switchToMainUnderlyingCallsCount = newValue
}
}
}
}
var switchToMainCalled: Bool {
return switchToMainCallsCount > 0
}
var switchToMainClosure: (() -> Void)?
func switchToMain() {
switchToMainCallsCount += 1
switchToMainClosure?()
}
//MARK: - switchToAlternate
var switchToAlternateUnderlyingCallsCount = 0
var switchToAlternateCallsCount: Int {
get {
if Thread.isMainThread {
return switchToAlternateUnderlyingCallsCount
} else {
var returnValue: Int? = nil
DispatchQueue.main.sync {
returnValue = switchToAlternateUnderlyingCallsCount
}
return returnValue!
}
}
set {
if Thread.isMainThread {
switchToAlternateUnderlyingCallsCount = newValue
} else {
DispatchQueue.main.sync {
switchToAlternateUnderlyingCallsCount = newValue
}
}
}
}
var switchToAlternateCalled: Bool {
return switchToAlternateCallsCount > 0
}
var switchToAlternateClosure: (() -> Void)?
func switchToAlternate() {
switchToAlternateCallsCount += 1
switchToAlternateClosure?()
}
//MARK: - showGlobalSearch
var showGlobalSearchUnderlyingCallsCount = 0

View File

@ -1,37 +0,0 @@
//
// Copyright 2022 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
typealias BackgroundTaskExpirationHandler = (BackgroundTaskProtocol) -> Void
/// BackgroundTaskProtocol is the protocol describing a background task regardless of the platform used.
protocol BackgroundTaskProtocol: AnyObject {
/// Name of the background task for debug.
var name: String { get }
/// `true` if the background task is currently running.
var isRunning: Bool { get }
/// Flag indicating the background task is reusable. If reusable, `name` is the key to distinguish background tasks.
var isReusable: Bool { get }
/// Method to be called when a task reused one more time. Should only be valid for reusable tasks.
func reuse()
/// Stop the background task. Cannot be started anymore. For reusable tasks, should be called same number of times `reuse` called.
func stop()
}

View File

@ -1,45 +0,0 @@
//
// Copyright 2022 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
@MainActor
protocol BackgroundTaskServiceProtocol {
func startBackgroundTask(withName name: String,
isReusable: Bool,
expirationHandler: (() -> Void)?) -> BackgroundTaskProtocol?
}
extension BackgroundTaskServiceProtocol {
func startBackgroundTask(withName name: String) -> BackgroundTaskProtocol? {
startBackgroundTask(withName: name,
expirationHandler: nil)
}
func startBackgroundTask(withName name: String,
isReusable: Bool) -> BackgroundTaskProtocol? {
startBackgroundTask(withName: name,
isReusable: isReusable,
expirationHandler: nil)
}
func startBackgroundTask(withName name: String,
expirationHandler: (() -> Void)?) -> BackgroundTaskProtocol? {
startBackgroundTask(withName: name,
isReusable: false,
expirationHandler: expirationHandler)
}
}

View File

@ -1,95 +0,0 @@
//
// Copyright 2022 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 UIKit
class UIKitBackgroundTask: BackgroundTaskProtocol {
let name: String
var isRunning: Bool {
identifier != .invalid
}
let isReusable: Bool
let expirationHandler: BackgroundTaskExpirationHandler?
var elapsedTime: TimeInterval {
Date().timeIntervalSince(startDate) * 1000
}
private let appMediator: AppMediatorProtocol
private var identifier: UIBackgroundTaskIdentifier = .invalid
private var useCounter = 0
private let startDate = Date()
init?(name: String,
isReusable: Bool,
appMediator: AppMediatorProtocol,
expirationHandler: BackgroundTaskExpirationHandler?) {
self.name = name
self.isReusable = isReusable
self.appMediator = appMediator
self.expirationHandler = expirationHandler
identifier = appMediator.beginBackgroundTask(withName: name) { [weak self] in
guard let self else { return }
self.stop()
self.expirationHandler?(self)
}
if identifier == .invalid {
MXLog.error("Do not start background task: \(name), as OS declined")
expirationHandler?(self)
return nil
}
if isReusable {
reuse()
}
MXLog.verbose("Start background task #\(identifier.rawValue) - \(name)")
}
func reuse() {
guard isReusable else {
return
}
useCounter += 1
}
func stop() {
if isReusable {
useCounter -= 1
if useCounter <= 0 {
endTask()
}
} else {
endTask()
}
}
private func endTask() {
if identifier != .invalid {
MXLog.verbose("End background task #\(identifier.rawValue) - \(name) after \(readableElapsedTime)")
appMediator.endBackgroundTask(identifier)
identifier = .invalid
}
}
private var readableElapsedTime: String {
String(format: "%.3fms", elapsedTime)
}
}

View File

@ -1,98 +0,0 @@
//
// Copyright 2022 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 UIKit
/// /// UIKitBackgroundTaskService is a concrete implementation of BackgroundTaskServiceProtocol using a given `ApplicationProtocol` instance.
class UIKitBackgroundTaskService: BackgroundTaskServiceProtocol {
private let appMediator: AppMediatorProtocol
private var reusableTasks = NSMapTable<NSString, UIKitBackgroundTask>(keyOptions: .strongMemory, valueOptions: .weakMemory)
init(appMediator: AppMediatorProtocol) {
self.appMediator = appMediator
}
func startBackgroundTask(withName name: String,
isReusable: Bool,
expirationHandler: (() -> Void)?) -> BackgroundTaskProtocol? {
if shouldAvoidStartingNewTasks() {
MXLog.error("Do not start background task: \(name), as not enough time exists")
// call expiration handler immediately
expirationHandler?()
return nil
}
var created = false
var result: BackgroundTaskProtocol?
if isReusable {
if let oldTask = reusableTasks.object(forKey: name as NSString), oldTask.isRunning {
oldTask.reuse()
result = oldTask
} else {
if let newTask = UIKitBackgroundTask(name: name,
isReusable: isReusable,
appMediator: appMediator,
expirationHandler: { [weak self] task in
guard let self else { return }
self.reusableTasks.removeObject(forKey: task.name as NSString)
expirationHandler?()
}) {
created = true
reusableTasks.setObject(newTask, forKey: name as NSString)
result = newTask
}
}
} else {
if let newTask = UIKitBackgroundTask(name: name,
isReusable: isReusable,
appMediator: appMediator,
expirationHandler: { _ in
expirationHandler?()
}) {
result = newTask
created = true
}
}
let appState = appMediator.appState
let remainingTime = readableBackgroundTimeRemaining(appMediator.backgroundTimeRemaining)
MXLog.verbose("Background task \(name) \(created ? "started" : "reused") with app state: \(appState) and estimated background time remaining: \(remainingTime)")
return result
}
private func readableBackgroundTimeRemaining(_ backgroundTimeRemaining: TimeInterval) -> String {
if backgroundTimeRemaining == .greatestFiniteMagnitude {
return "undetermined"
} else {
return String(format: "%.0f seconds", backgroundTimeRemaining)
}
}
private func shouldAvoidStartingNewTasks() -> Bool {
if appMediator.appState == .background,
appMediator.backgroundTimeRemaining < .backgroundTimeRemainingThresholdToStartTasks {
return true
}
return false
}
}
private extension TimeInterval {
static let backgroundTimeRemainingThresholdToStartTasks: TimeInterval = 5
}

View File

@ -23,7 +23,6 @@ import MatrixRustSDK
class ClientProxy: ClientProxyProtocol {
private let client: ClientProtocol
private let backgroundTaskService: BackgroundTaskServiceProtocol
private let appSettings: AppSettings
private let networkMonitor: NetworkMonitorProtocol
@ -122,11 +121,9 @@ class ClientProxy: ClientProxyProtocol {
}
init(client: ClientProtocol,
backgroundTaskService: BackgroundTaskServiceProtocol,
appSettings: AppSettings,
networkMonitor: NetworkMonitorProtocol) async {
self.client = client
self.backgroundTaskService = backgroundTaskService
self.appSettings = appSettings
self.networkMonitor = networkMonitor
@ -134,8 +131,7 @@ class ClientProxy: ClientProxyProtocol {
mediaLoader = MediaLoader(client: client)
notificationSettings = NotificationSettingsProxy(notificationSettings: client.getNotificationSettings(),
backgroundTaskService: backgroundTaskService)
notificationSettings = NotificationSettingsProxy(notificationSettings: client.getNotificationSettings())
secureBackupController = SecureBackupController(encryption: client.encryption())
@ -425,8 +421,7 @@ class ClientProxy: ClientProxyProtocol {
if let roomListItem, let room {
return await RoomProxy(roomListItem: roomListItem,
room: room,
backgroundTaskService: backgroundTaskService)
room: room)
}
// Else wait for the visible rooms list to go into fully loaded
@ -453,8 +448,7 @@ class ClientProxy: ClientProxyProtocol {
}
return await RoomProxy(roomListItem: roomListItem,
room: room,
backgroundTaskService: backgroundTaskService)
room: room)
}
func roomPreviewForIdentifier(_ identifier: String) async -> Result<RoomPreviewDetails, ClientProxyError> {

View File

@ -20,14 +20,11 @@ import UIKit
struct MediaProvider: MediaProviderProtocol {
private let mediaLoader: MediaLoaderProtocol
private let imageCache: Kingfisher.ImageCache
private let backgroundTaskService: BackgroundTaskServiceProtocol?
init(mediaLoader: MediaLoaderProtocol,
imageCache: Kingfisher.ImageCache,
backgroundTaskService: BackgroundTaskServiceProtocol?) {
imageCache: Kingfisher.ImageCache) {
self.mediaLoader = mediaLoader
self.imageCache = imageCache
self.backgroundTaskService = backgroundTaskService
}
// MARK: Images
@ -45,11 +42,6 @@ struct MediaProvider: MediaProviderProtocol {
return .success(image)
}
let loadImageBgTask = await backgroundTaskService?.startBackgroundTask(withName: "LoadImage: \(source.url.hashValue)")
defer {
loadImageBgTask?.stop()
}
let cacheKey = cacheKeyForURL(source.url, size: size)
if case let .success(cacheResult) = await imageCache.retrieveImage(forKey: cacheKey),
@ -92,9 +84,6 @@ struct MediaProvider: MediaProviderProtocol {
// MARK: Files
func loadFileFromSource(_ source: MediaSourceProxy, body: String?) async -> Result<MediaFileHandleProxy, MediaProviderError> {
let loadFileBgTask = await backgroundTaskService?.startBackgroundTask(withName: "LoadFile: \(source.url.hashValue)")
defer { loadFileBgTask?.stop() }
do {
let file = try await mediaLoader.loadMediaFileForSource(source, body: body)
return .success(file)

View File

@ -36,13 +36,11 @@ private final class WeakNotificationSettingsProxy: NotificationSettingsDelegate
final class NotificationSettingsProxy: NotificationSettingsProxyProtocol {
private(set) var notificationSettings: MatrixRustSDK.NotificationSettingsProtocol
private let backgroundTaskService: BackgroundTaskServiceProtocol?
let callbacks = PassthroughSubject<NotificationSettingsProxyCallback, Never>()
init(notificationSettings: MatrixRustSDK.NotificationSettingsProtocol, backgroundTaskService: BackgroundTaskServiceProtocol?) {
init(notificationSettings: MatrixRustSDK.NotificationSettingsProtocol) {
self.notificationSettings = notificationSettings
self.backgroundTaskService = backgroundTaskService
notificationSettings.setDelegate(delegate: WeakNotificationSettingsProxy(proxy: self))
}
@ -52,9 +50,6 @@ final class NotificationSettingsProxy: NotificationSettingsProxyProtocol {
}
func setNotificationMode(roomId: String, mode: RoomNotificationModeProxy) async throws {
let backgroundTask = await backgroundTaskService?.startBackgroundTask(withName: "setNotificationMode")
defer { backgroundTask?.stop() }
try await notificationSettings.setRoomNotificationMode(roomId: roomId, mode: mode.roomNotificationMode)
await updatedSettings()
}
@ -70,9 +65,6 @@ final class NotificationSettingsProxy: NotificationSettingsProxyProtocol {
}
func setDefaultRoomNotificationMode(isEncrypted: Bool, isOneToOne: Bool, mode: RoomNotificationModeProxy) async throws {
let backgroundTask = await backgroundTaskService?.startBackgroundTask(withName: "setDefaultRoomNotificationMode")
defer { backgroundTask?.stop() }
do {
try await notificationSettings.setDefaultRoomNotificationMode(isEncrypted: isEncrypted, isOneToOne: isOneToOne, mode: mode.roomNotificationMode)
} catch NotificationSettingsError.RuleNotFound(let ruleId) {
@ -86,17 +78,11 @@ final class NotificationSettingsProxy: NotificationSettingsProxyProtocol {
}
func restoreDefaultNotificationMode(roomId: String) async throws {
let backgroundTask = await backgroundTaskService?.startBackgroundTask(withName: "restoreDefaultNotificationMode")
defer { backgroundTask?.stop() }
try await notificationSettings.restoreDefaultRoomNotificationMode(roomId: roomId)
await updatedSettings()
}
func unmuteRoom(roomId: String, isEncrypted: Bool, isOneToOne: Bool) async throws {
let backgroundTask = await backgroundTaskService?.startBackgroundTask(withName: "unmuteRoom")
defer { backgroundTask?.stop() }
try await notificationSettings.unmuteRoom(roomId: roomId, isEncrypted: isEncrypted, isOneToOne: isOneToOne)
await updatedSettings()
}
@ -106,9 +92,6 @@ final class NotificationSettingsProxy: NotificationSettingsProxyProtocol {
}
func setRoomMentionEnabled(enabled: Bool) async throws {
let backgroundTask = await backgroundTaskService?.startBackgroundTask(withName: "setRoomMentionEnabled")
defer { backgroundTask?.stop() }
try await notificationSettings.setRoomMentionEnabled(enabled: enabled)
await updatedSettings()
}
@ -118,9 +101,6 @@ final class NotificationSettingsProxy: NotificationSettingsProxyProtocol {
}
func setCallEnabled(enabled: Bool) async throws {
let backgroundTask = await backgroundTaskService?.startBackgroundTask(withName: "setCallEnabled")
defer { backgroundTask?.stop() }
try await notificationSettings.setCallEnabled(enabled: enabled)
await updatedSettings()
}
@ -130,9 +110,6 @@ final class NotificationSettingsProxy: NotificationSettingsProxyProtocol {
}
func setInviteForMeEnabled(enabled: Bool) async throws {
let backgroundTask = await backgroundTaskService?.startBackgroundTask(withName: "setInviteForMeEnabled")
defer { backgroundTask?.stop() }
try await notificationSettings.setInviteForMeEnabled(enabled: enabled)
await updatedSettings()
}

View File

@ -26,13 +26,9 @@ class RoomProxy: RoomProxyProtocol {
private let roomListItem: RoomListItemProtocol
private let room: RoomProtocol
let timeline: TimelineProxyProtocol
private let backgroundTaskService: BackgroundTaskServiceProtocol
private let backgroundTaskName = "SendRoomEvent"
private let userInitiatedDispatchQueue = DispatchQueue(label: "io.element.elementx.roomproxy.user_initiated", qos: .userInitiated)
private var sendMessageBackgroundTask: BackgroundTaskProtocol?
// periphery:ignore - required for instance retention in the rust codebase
private var roomInfoObservationToken: TaskHandle?
// periphery:ignore - required for instance retention in the rust codebase
@ -60,13 +56,12 @@ class RoomProxy: RoomProxyProtocol {
}
init?(roomListItem: RoomListItemProtocol,
room: RoomProtocol,
backgroundTaskService: BackgroundTaskServiceProtocol) async {
room: RoomProtocol) async {
self.roomListItem = roomListItem
self.room = room
self.backgroundTaskService = backgroundTaskService
do {
timeline = try await TimelineProxy(timeline: room.timeline(), backgroundTaskService: backgroundTaskService)
timeline = try await TimelineProxy(timeline: room.timeline())
} catch {
MXLog.error("Failed creating timeline with error: \(error)")
return nil
@ -165,12 +160,7 @@ class RoomProxy: RoomProxyProtocol {
}
func redact(_ eventID: String) async -> Result<Void, RoomProxyError> {
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer {
sendMessageBackgroundTask?.stop()
}
return await Task.dispatch(on: userInitiatedDispatchQueue) {
await Task.dispatch(on: userInitiatedDispatchQueue) {
do {
try self.room.redact(eventId: eventID, reason: nil)
return .success(())
@ -182,12 +172,7 @@ class RoomProxy: RoomProxyProtocol {
}
func reportContent(_ eventID: String, reason: String?) async -> Result<Void, RoomProxyError> {
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer {
sendMessageBackgroundTask?.stop()
}
return await Task.dispatch(on: userInitiatedDispatchQueue) {
await Task.dispatch(on: userInitiatedDispatchQueue) {
do {
try self.room.reportContent(eventId: eventID, score: nil, reason: reason)
return .success(())
@ -226,11 +211,6 @@ class RoomProxy: RoomProxyProtocol {
return .success(member)
}
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer {
sendMessageBackgroundTask?.stop()
}
do {
let member = try await room.member(userId: userID)
return .success(RoomMemberProxy(member: member))
@ -241,12 +221,7 @@ class RoomProxy: RoomProxyProtocol {
}
func leaveRoom() async -> Result<Void, RoomProxyError> {
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer {
sendMessageBackgroundTask?.stop()
}
return await Task.dispatch(on: .global()) {
await Task.dispatch(on: .global()) {
do {
try self.room.leave()
return .success(())

View File

@ -20,10 +20,7 @@ import MatrixRustSDK
final class TimelineProxy: TimelineProxyProtocol {
private let timeline: Timeline
private var sendMessageBackgroundTask: BackgroundTaskProtocol?
private let backgroundTaskService: BackgroundTaskServiceProtocol
private let backgroundTaskName = "SendRoomEvent"
private let lowPriorityDispatchQueue = DispatchQueue(label: "io.element.elementx.roomproxy.low_priority", qos: .utility)
private let messageSendingDispatchQueue = DispatchQueue(label: "io.element.elementx.roomproxy.message_sending", qos: .userInitiated)
private let userInitiatedDispatchQueue = DispatchQueue(label: "io.element.elementx.roomproxy.user_initiated", qos: .userInitiated)
@ -54,9 +51,8 @@ final class TimelineProxy: TimelineProxyProtocol {
roomTimelineObservationToken?.cancel()
}
init(timeline: Timeline, backgroundTaskService: BackgroundTaskServiceProtocol) {
init(timeline: Timeline) {
self.timeline = timeline
self.backgroundTaskService = backgroundTaskService
}
func subscribeForUpdates() async {
@ -84,11 +80,6 @@ final class TimelineProxy: TimelineProxyProtocol {
func cancelSend(transactionID: String) async {
MXLog.info("Cancelling sending for transaction ID: \(transactionID)")
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer {
sendMessageBackgroundTask?.stop()
}
return await Task.dispatch(on: messageSendingDispatchQueue) {
self.timeline.cancelSend(txnId: transactionID)
MXLog.info("Finished cancelling sending for transaction ID: \(transactionID)")
@ -101,11 +92,6 @@ final class TimelineProxy: TimelineProxyProtocol {
intentionalMentions: IntentionalMentions) async -> Result<Void, TimelineProxyError> {
MXLog.info("Editing message with original event ID: \(eventID)")
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer {
sendMessageBackgroundTask?.stop()
}
let messageContent = buildMessageContentFor(message,
html: html,
intentionalMentions: intentionalMentions.toRustMentions())
@ -198,11 +184,6 @@ final class TimelineProxy: TimelineProxyProtocol {
func retrySend(transactionID: String) async {
MXLog.info("Retrying sending for transactionID: \(transactionID)")
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer {
sendMessageBackgroundTask?.stop()
}
return await Task.dispatch(on: messageSendingDispatchQueue) {
self.timeline.retrySend(txnId: transactionID)
MXLog.info("Finished retrying sending for transactionID: \(transactionID)")
@ -215,11 +196,6 @@ final class TimelineProxy: TimelineProxyProtocol {
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
MXLog.info("Sending audio")
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer {
sendMessageBackgroundTask?.stop()
}
let handle = timeline.sendAudio(url: url.path(percentEncoded: false), audioInfo: audioInfo, caption: nil, formattedCaption: nil, progressWatcher: UploadProgressListener { progress in
progressSubject?.send(progress)
})
@ -245,11 +221,6 @@ final class TimelineProxy: TimelineProxyProtocol {
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
MXLog.info("Sending file")
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer {
sendMessageBackgroundTask?.stop()
}
let handle = timeline.sendFile(url: url.path(percentEncoded: false), fileInfo: fileInfo, progressWatcher: UploadProgressListener { progress in
progressSubject?.send(progress)
})
@ -276,11 +247,6 @@ final class TimelineProxy: TimelineProxyProtocol {
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
MXLog.info("Sending image")
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer {
sendMessageBackgroundTask?.stop()
}
let handle = timeline.sendImage(url: url.path(percentEncoded: false), thumbnailUrl: thumbnailURL.path(percentEncoded: false), imageInfo: imageInfo, caption: nil, formattedCaption: nil, progressWatcher: UploadProgressListener { progress in
progressSubject?.send(progress)
})
@ -307,11 +273,6 @@ final class TimelineProxy: TimelineProxyProtocol {
assetType: AssetType?) async -> Result<Void, TimelineProxyError> {
MXLog.info("Sending location")
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer {
sendMessageBackgroundTask?.stop()
}
return await Task.dispatch(on: messageSendingDispatchQueue) {
self.timeline.sendLocation(body: body,
geoUri: geoURI.string,
@ -334,11 +295,6 @@ final class TimelineProxy: TimelineProxyProtocol {
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
MXLog.info("Sending video")
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer {
sendMessageBackgroundTask?.stop()
}
let handle = timeline.sendVideo(url: url.path(percentEncoded: false), thumbnailUrl: thumbnailURL.path(percentEncoded: false), videoInfo: videoInfo, caption: nil, formattedCaption: nil, progressWatcher: UploadProgressListener { progress in
progressSubject?.send(progress)
})
@ -365,11 +321,6 @@ final class TimelineProxy: TimelineProxyProtocol {
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
MXLog.info("Sending voice message")
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer {
sendMessageBackgroundTask?.stop()
}
let handle = timeline.sendVoiceMessage(url: url.path(percentEncoded: false), audioInfo: audioInfo, waveform: waveform, caption: nil, formattedCaption: nil, progressWatcher: UploadProgressListener { progress in
progressSubject?.send(progress)
})
@ -399,11 +350,6 @@ final class TimelineProxy: TimelineProxyProtocol {
MXLog.info("Sending message")
}
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer {
sendMessageBackgroundTask?.stop()
}
let messageContent = buildMessageContentFor(message,
html: html,
intentionalMentions: intentionalMentions.toRustMentions())
@ -437,11 +383,6 @@ final class TimelineProxy: TimelineProxyProtocol {
func sendMessageEventContent(_ messageContent: RoomMessageEventContentWithoutRelation) async -> Result<Void, TimelineProxyError> {
MXLog.info("Sending message content")
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer {
sendMessageBackgroundTask?.stop()
}
return await Task.dispatch(on: messageSendingDispatchQueue) {
self.timeline.send(msg: messageContent)
@ -456,11 +397,6 @@ final class TimelineProxy: TimelineProxyProtocol {
func sendReadReceipt(for eventID: String, type: ReceiptType) async -> Result<Void, TimelineProxyError> {
MXLog.verbose("Sending read receipt for eventID: \(eventID)")
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer {
sendMessageBackgroundTask?.stop()
}
return await Task.dispatch(on: lowPriorityDispatchQueue) {
do {
try self.timeline.sendReadReceipt(receiptType: type, eventId: eventID)
@ -476,11 +412,6 @@ final class TimelineProxy: TimelineProxyProtocol {
func toggleReaction(_ reaction: String, to eventID: String) async -> Result<Void, TimelineProxyError> {
MXLog.info("Toggling reaction for eventID: \(eventID)")
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer {
sendMessageBackgroundTask?.stop()
}
return await Task.dispatch(on: userInitiatedDispatchQueue) {
do {
try self.timeline.toggleReaction(eventId: eventID, key: reaction)

View File

@ -20,7 +20,6 @@ import MatrixRustSDK
class UserSessionStore: UserSessionStoreProtocol {
private let keychainController: KeychainControllerProtocol
private let backgroundTaskService: BackgroundTaskServiceProtocol
private let matrixSDKStateKey = "matrix-sdk-state"
/// Whether or not there are sessions in the store.
@ -33,9 +32,8 @@ class UserSessionStore: UserSessionStoreProtocol {
var clientSessionDelegate: ClientSessionDelegate { keychainController }
init(keychainController: KeychainControllerProtocol, backgroundTaskService: BackgroundTaskServiceProtocol) {
init(keychainController: KeychainControllerProtocol) {
self.keychainController = keychainController
self.backgroundTaskService = backgroundTaskService
baseDirectory = .sessionsBaseDirectory
MXLog.info("Setup base directory at: \(baseDirectory)")
}
@ -100,11 +98,9 @@ class UserSessionStore: UserSessionStoreProtocol {
private func buildUserSessionWithClient(_ clientProxy: ClientProxyProtocol) -> UserSessionProtocol {
let mediaProvider = MediaProvider(mediaLoader: clientProxy,
imageCache: .onlyInMemory,
backgroundTaskService: backgroundTaskService)
imageCache: .onlyInMemory)
let voiceMessageMediaManager = VoiceMessageMediaManager(mediaProvider: mediaProvider,
backgroundTaskService: backgroundTaskService)
let voiceMessageMediaManager = VoiceMessageMediaManager(mediaProvider: mediaProvider)
return UserSession(clientProxy: clientProxy,
mediaProvider: mediaProvider,
@ -150,7 +146,6 @@ class UserSessionStore: UserSessionStoreProtocol {
private func setupProxyForClient(_ client: Client) async -> ClientProxyProtocol {
await ClientProxy(client: client,
backgroundTaskService: backgroundTaskService,
appSettings: ServiceLocator.shared.settings,
networkMonitor: ServiceLocator.shared.networkMonitor)
}

View File

@ -30,7 +30,6 @@ class VoiceMessageMediaManager: VoiceMessageMediaManagerProtocol {
private let voiceMessageCache: VoiceMessageCacheProtocol
private let audioConverter: AudioConverterProtocol
private let backgroundTaskService: BackgroundTaskServiceProtocol?
private let processingQueue: DispatchQueue
private var conversionRequests = [MediaSourceProxy: VoiceMessageConversionRequest]()
@ -39,13 +38,11 @@ class VoiceMessageMediaManager: VoiceMessageMediaManagerProtocol {
init(mediaProvider: MediaProviderProtocol,
voiceMessageCache: VoiceMessageCacheProtocol = VoiceMessageCache(),
audioConverter: AudioConverterProtocol = AudioConverter(),
processingQueue: DispatchQueue = .global(),
backgroundTaskService: BackgroundTaskServiceProtocol?) {
processingQueue: DispatchQueue = .global()) {
self.mediaProvider = mediaProvider
self.voiceMessageCache = voiceMessageCache
self.audioConverter = audioConverter
self.processingQueue = processingQueue
self.backgroundTaskService = backgroundTaskService
}
deinit {
@ -53,9 +50,6 @@ class VoiceMessageMediaManager: VoiceMessageMediaManagerProtocol {
}
func loadVoiceMessageFromSource(_ source: MediaSourceProxy, body: String?) async throws -> URL {
let loadFileBgTask = await backgroundTaskService?.startBackgroundTask(withName: "LoadFile: \(source.url.hashValue)")
defer { loadFileBgTask?.stop() }
guard let mimeType = source.mimeType, mimeType.starts(with: supportedVoiceMessageMimeType) else {
throw VoiceMessageMediaManagerError.unsupportedMimeTye
}

View File

@ -19,7 +19,7 @@ import MatrixRustSDK
import SwiftUI
import UIKit
class UITestsAppCoordinator: AppCoordinatorProtocol, WindowManagerDelegate {
class UITestsAppCoordinator: AppCoordinatorProtocol, SecureWindowManagerDelegate {
private let navigationRootCoordinator: NavigationRootCoordinator
// periphery:ignore - retaining purpose
@ -28,7 +28,7 @@ class UITestsAppCoordinator: AppCoordinatorProtocol, WindowManagerDelegate {
// periphery:ignore - retaining purpose
private var alternateWindowMockScreen: MockScreen?
let windowManager: WindowManagerProtocol
let windowManager: SecureWindowManagerProtocol
init(appDelegate: AppDelegate) {
windowManager = WindowManager(appDelegate: appDelegate)
@ -70,7 +70,7 @@ class UITestsAppCoordinator: AppCoordinatorProtocol, WindowManagerDelegate {
fatalError("Not implemented.")
}
func windowManagerDidConfigureWindows(_ windowManager: WindowManagerProtocol) {
func windowManagerDidConfigureWindows(_ windowManager: SecureWindowManagerProtocol) {
ServiceLocator.shared.userIndicatorController.window = windowManager.overlayWindow
// Set up the alternate window for the App Lock flow coordinator tests.
@ -92,14 +92,14 @@ class UITestsAppCoordinator: AppCoordinatorProtocol, WindowManagerDelegate {
@MainActor
class MockScreen: Identifiable {
let id: UITestsScreenIdentifier
let windowManager: WindowManagerProtocol
let windowManager: SecureWindowManagerProtocol
let navigationRootCoordinator: NavigationRootCoordinator
private var retainedState = [Any]()
private var cancellables = Set<AnyCancellable>()
init(id: UITestsScreenIdentifier,
windowManager: WindowManagerProtocol,
windowManager: SecureWindowManagerProtocol,
navigationRootCoordinator: NavigationRootCoordinator) {
self.id = id
self.windowManager = windowManager
@ -129,8 +129,7 @@ class MockScreen: Identifiable {
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings,
analytics: ServiceLocator.shared.analytics,
userIndicatorController: ServiceLocator.shared.userIndicatorController,
orientationManager: windowManager)
userIndicatorController: ServiceLocator.shared.userIndicatorController)
flowCoordinator.start()
retainedState.append(flowCoordinator)
return nil
@ -468,7 +467,6 @@ class MockScreen: Identifiable {
let flowCoordinator = UserSessionFlowCoordinator(userSession: MockUserSession(clientProxy: clientProxy, mediaProvider: MockMediaProvider(), voiceMessageMediaManager: VoiceMessageMediaManagerMock()),
navigationRootCoordinator: navigationRootCoordinator,
windowManager: windowManager,
appLockService: AppLockService(keychainController: KeychainControllerMock(),
appSettings: ServiceLocator.shared.settings),
bugReportService: BugReportServiceMock(),

View File

@ -17,7 +17,7 @@
import SwiftUI
class UnitTestsAppCoordinator: AppCoordinatorProtocol {
let windowManager: WindowManagerProtocol
let windowManager: SecureWindowManagerProtocol
init(appDelegate: AppDelegate) {
windowManager = WindowManager(appDelegate: appDelegate)

View File

@ -22,8 +22,7 @@ final class NSEUserSession {
private let notificationClient: NotificationClient
private let userID: String
private(set) lazy var mediaProvider: MediaProviderProtocol = MediaProvider(mediaLoader: MediaLoader(client: baseClient),
imageCache: .onlyOnDisk,
backgroundTaskService: nil)
imageCache: .onlyOnDisk)
private let delegateHandle: TaskHandle?
init(credentials: KeychainCredentials, clientSessionDelegate: ClientSessionDelegate) async throws {

View File

@ -97,8 +97,6 @@ targets:
- path: ../../ElementX/Sources/Other/TestablePreview.swift
- path: ../../ElementX/Sources/Other/Pills/PlainMentionBuilder.swift
- path: ../../ElementX/Sources/Other/Pills/PillConstants.swift
- path: ../../ElementX/Sources/Services/BackgroundTasks/BackgroundTaskProtocol.swift
- path: ../../ElementX/Sources/Services/BackgroundTasks/BackgroundTaskServiceProtocol.swift
- path: ../../ElementX/Sources/Services/Keychain/KeychainController.swift
- path: ../../ElementX/Sources/Services/Keychain/KeychainControllerProtocol.swift
- path: ../../ElementX/Sources/Services/Media/Provider

View File

@ -1,160 +0,0 @@
//
// Copyright 2022 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 XCTest
@testable import ElementX
@MainActor
class BackgroundTaskTests: XCTestCase {
private enum Constants {
static let bgTaskName = "test"
}
func testInitAndStop() {
let service = UIKitBackgroundTaskService(appMediator: AppMediatorMock.default)
guard let task = service.startBackgroundTask(withName: Constants.bgTaskName) else {
XCTFail("Failed to setup test conditions")
return
}
XCTAssertEqual(task.name, Constants.bgTaskName, "Task name should be persisted")
XCTAssertFalse(task.isReusable, "Task should be not reusable by default")
XCTAssertTrue(task.isRunning, "Task should be running")
task.stop()
XCTAssertFalse(task.isRunning, "Task should be stopped")
}
func testNotReusableInit() {
let service = UIKitBackgroundTaskService(appMediator: AppMediatorMock.default)
// create two not reusable task with the same name
guard let task1 = service.startBackgroundTask(withName: Constants.bgTaskName),
let task2 = service.startBackgroundTask(withName: Constants.bgTaskName) else {
XCTFail("Failed to setup test conditions")
return
}
// task1 & task2 should be different instances
XCTAssertFalse(task1 === task2,
"Handler should create different tasks when reusability disabled")
}
func testReusableInit() {
let service = UIKitBackgroundTaskService(appMediator: AppMediatorMock.default)
// create two reusable task with the same name
guard let task1 = service.startBackgroundTask(withName: Constants.bgTaskName, isReusable: true),
let task2 = service.startBackgroundTask(withName: Constants.bgTaskName, isReusable: true) else {
XCTFail("Failed to setup test conditions")
return
}
// task1 and task2 should be the same instance
XCTAssertTrue(task1 === task2,
"Handler should create different tasks when reusability disabled")
XCTAssertEqual(task1.name, Constants.bgTaskName, "Task name should be persisted")
XCTAssertTrue(task1.isReusable, "Task should be reusable")
XCTAssertTrue(task1.isRunning, "Task should be running")
}
func testMultipleStops() {
let service = UIKitBackgroundTaskService(appMediator: AppMediatorMock.default)
// create two reusable task with the same name
guard let task = service.startBackgroundTask(withName: Constants.bgTaskName, isReusable: true),
service.startBackgroundTask(withName: Constants.bgTaskName, isReusable: true) != nil else {
XCTFail("Failed to setup test conditions")
return
}
XCTAssertTrue(task.isRunning, "Task should be running")
task.stop()
XCTAssertTrue(task.isRunning, "Task should be still running after one stop call")
task.stop()
XCTAssertFalse(task.isRunning, "Task should be stopped after two stop calls")
}
func testNotValidReuse() {
let service = UIKitBackgroundTaskService(appMediator: AppMediatorMock.default)
// create two reusable task with the same name
guard let task = service.startBackgroundTask(withName: Constants.bgTaskName, isReusable: true) else {
XCTFail("Failed to setup test conditions")
return
}
XCTAssertTrue(task.isRunning, "Task should be running")
task.stop()
XCTAssertFalse(task.isRunning, "Task should be stopped after stop")
task.reuse()
XCTAssertFalse(task.isRunning, "Task should be stopped after one stop call, even if reuse is called after")
}
func testValidReuse() {
let service = UIKitBackgroundTaskService(appMediator: AppMediatorMock.default)
// create two reusable task with the same name
guard let task = service.startBackgroundTask(withName: Constants.bgTaskName, isReusable: true) else {
XCTFail("Failed to setup test conditions")
return
}
XCTAssertTrue(task.isRunning, "Task should be running")
task.reuse()
XCTAssertTrue(task.isRunning, "Task should be still running")
task.stop()
XCTAssertTrue(task.isRunning, "Task should be still running after one stop call")
task.stop()
XCTAssertFalse(task.isRunning, "Task should be stopped after two stop calls")
}
func testBrokenApp() {
let service = UIKitBackgroundTaskService(appMediator: AppMediatorMock.mockBroken)
// create two reusable task with the same name
let task = service.startBackgroundTask(withName: Constants.bgTaskName)
XCTAssertNil(task, "Task should not be created")
}
func testNoTimeApp() {
let service = UIKitBackgroundTaskService(appMediator: AppMediatorMock.mockAboutToSuspend)
// create two reusable task with the same name
let task = service.startBackgroundTask(withName: Constants.bgTaskName)
XCTAssertNil(task, "Task should not be created")
}
}

View File

@ -22,15 +22,13 @@ import XCTest
final class MediaProviderTests: XCTestCase {
private let mediaLoader = MockMediaLoader()
private var imageCache: MockImageCache!
private var backgroundTaskService = MockBackgroundTaskService()
var mediaProvider: MediaProvider!
override func setUp() {
imageCache = MockImageCache(name: "Test")
mediaProvider = MediaProvider(mediaLoader: mediaLoader,
imageCache: imageCache,
backgroundTaskService: backgroundTaskService)
imageCache: imageCache)
}
func test_whenImageFromSourceWithSourceNil_nilReturned() throws {

View File

@ -1,23 +0,0 @@
//
// Copyright 2022 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.
//
@testable import ElementX
import Foundation
class MockBackgroundTaskService: BackgroundTaskServiceProtocol {
func startBackgroundTask(withName name: String, isReusable: Bool, expirationHandler: (() -> Void)?) -> ElementX.BackgroundTaskProtocol? {
nil
}
}

View File

@ -295,8 +295,7 @@ class RoomFlowCoordinatorTests: XCTestCase {
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings,
analytics: ServiceLocator.shared.analytics,
userIndicatorController: ServiceLocator.shared.userIndicatorController,
orientationManager: OrientationManagerMock())
userIndicatorController: ServiceLocator.shared.userIndicatorController)
}
}

View File

@ -46,7 +46,6 @@ class UserSessionFlowCoordinatorTests: XCTestCase {
userSessionFlowCoordinator = UserSessionFlowCoordinator(userSession: userSession,
navigationRootCoordinator: navigationRootCoordinator,
windowManager: WindowManagerMock(),
appLockService: AppLockServiceMock(),
bugReportService: BugReportServiceMock(),
roomTimelineControllerFactory: MockRoomTimelineControllerFactory(),

View File

@ -32,8 +32,7 @@ class VoiceMessageMediaManagerTests: XCTestCase {
voiceMessageCache = VoiceMessageCacheMock()
mediaProvider = MockMediaProvider()
voiceMessageMediaManager = VoiceMessageMediaManager(mediaProvider: mediaProvider,
voiceMessageCache: voiceMessageCache,
backgroundTaskService: MockBackgroundTaskService())
voiceMessageCache: voiceMessageCache)
}
func testLoadVoiceMessageFromSourceUnsupportedMedia() async throws {
@ -65,8 +64,7 @@ class VoiceMessageMediaManagerTests: XCTestCase {
voiceMessageMediaManager = VoiceMessageMediaManager(mediaProvider: mediaProvider,
voiceMessageCache: voiceMessageCache,
audioConverter: AudioConverterMock(),
backgroundTaskService: MockBackgroundTaskService())
audioConverter: AudioConverterMock())
do {
_ = try await voiceMessageMediaManager.loadVoiceMessageFromSource(mediaSource, body: nil)
@ -119,8 +117,7 @@ class VoiceMessageMediaManagerTests: XCTestCase {
voiceMessageCache.cacheMediaSourceUsingMoveReturnValue = .success(cachedConvertedFileURL)
voiceMessageMediaManager = VoiceMessageMediaManager(mediaProvider: mediaProvider,
voiceMessageCache: voiceMessageCache,
audioConverter: audioConverter,
backgroundTaskService: MockBackgroundTaskService())
audioConverter: audioConverter)
let url = try await voiceMessageMediaManager.loadVoiceMessageFromSource(mediaSource, body: nil)
// The file must have been converted
@ -155,8 +152,7 @@ class VoiceMessageMediaManagerTests: XCTestCase {
voiceMessageMediaManager = VoiceMessageMediaManager(mediaProvider: mediaProvider,
voiceMessageCache: voiceMessageCache,
audioConverter: audioConverter,
backgroundTaskService: MockBackgroundTaskService())
audioConverter: audioConverter)
let mediaSource = MediaSourceProxy(url: someURL, mimeType: audioOGGMimeType)
for _ in 0..<10 {