diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/tasks/ClearCacheUseCase.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/tasks/ClearCacheUseCase.kt index 5662e4fd46..9b90c8ba53 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/tasks/ClearCacheUseCase.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/tasks/ClearCacheUseCase.kt @@ -59,6 +59,7 @@ class DefaultClearCacheUseCase @Inject constructor( seenInvitesStore.clear() // Ensure any error will be displayed again pushService.setIgnoreRegistrationError(matrixClient.sessionId, false) + pushService.resetBatteryOptimizationState() // Ensure the app is restarted defaultCacheService.onClearedCache(matrixClient.sessionId) } diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/tasks/DefaultClearCacheUseCaseTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/tasks/DefaultClearCacheUseCaseTest.kt index ab391bfc62..cfdc63984c 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/tasks/DefaultClearCacheUseCaseTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/tasks/DefaultClearCacheUseCaseTest.kt @@ -46,8 +46,10 @@ class DefaultClearCacheUseCaseTest { resetLambda = resetFtueLambda, ) val setIgnoreRegistrationErrorLambda = lambdaRecorder { _, _ -> } + val resetBatteryOptimizationStateResult = lambdaRecorder { } val pushService = FakePushService( - setIgnoreRegistrationErrorLambda = setIgnoreRegistrationErrorLambda + setIgnoreRegistrationErrorLambda = setIgnoreRegistrationErrorLambda, + resetBatteryOptimizationStateResult = resetBatteryOptimizationStateResult, ) val seenInvitesStore = InMemorySeenInvitesStore(setOf(A_ROOM_ID)) assertThat(seenInvitesStore.seenRoomIds().first()).isNotEmpty() @@ -68,6 +70,7 @@ class DefaultClearCacheUseCaseTest { resetFtueLambda.assertions().isCalledOnce() setIgnoreRegistrationErrorLambda.assertions().isCalledOnce() .with(value(matrixClient.sessionId), value(false)) + resetBatteryOptimizationStateResult.assertions().isCalledOnce() assertThat(awaitItem()).isEqualTo(matrixClient.sessionId) assertThat(seenInvitesStore.seenRoomIds().first()).isEmpty() assertThat(activeRoomsHolder.getActiveRoom(A_SESSION_ID)).isNull() diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/notification/NotificationData.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/notification/NotificationData.kt index 338193ed44..f90b70171e 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/notification/NotificationData.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/notification/NotificationData.kt @@ -68,6 +68,7 @@ sealed interface NotificationContent { ) : MessageLike data object RoomEncrypted : MessageLike + data object UnableToResolve : MessageLike data class RoomMessage( val senderId: UserId, val messageType: MessageType diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationService.kt index bab7cdea02..b88b53454a 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationService.kt @@ -12,6 +12,7 @@ import io.element.android.libraries.core.extensions.runCatchingExceptions import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.SessionId +import io.element.android.libraries.matrix.api.notification.NotificationContent import io.element.android.libraries.matrix.api.notification.NotificationData import io.element.android.libraries.matrix.api.notification.NotificationService import io.element.android.services.toolbox.api.systemclock.SystemClock @@ -24,7 +25,7 @@ class RustNotificationService( private val sessionId: SessionId, private val notificationClient: NotificationClient, private val dispatchers: CoroutineDispatchers, - clock: SystemClock, + private val clock: SystemClock, ) : NotificationService { private val notificationMapper: NotificationMapper = NotificationMapper(clock) @@ -43,11 +44,32 @@ class RustNotificationService( val eventIds = requests.flatMap { it.eventIds } for (eventId in eventIds) { val item = items[eventId] + val roomId = RoomId(requests.find { it.eventIds.contains(eventId) }?.roomId!!) if (item != null) { - val roomId = RoomId(requests.find { it.eventIds.contains(eventId) }?.roomId!!) put(EventId(eventId), notificationMapper.map(sessionId, EventId(eventId), roomId, item)) } else { Timber.e("Could not retrieve event for notification with $eventId") + put( + EventId(eventId), + NotificationData( + sessionId = sessionId, + eventId = EventId(eventId), + threadId = null, + roomId = roomId, + senderAvatarUrl = null, + senderDisplayName = null, + senderIsNameAmbiguous = false, + roomAvatarUrl = null, + roomDisplayName = null, + isDirect = false, + isDm = false, + isEncrypted = false, + isNoisy = false, + timestamp = clock.epochMillis(), + content = NotificationContent.MessageLike.UnableToResolve, + hasMention = false + ) + ) } } } diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiNotificationClient.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiNotificationClient.kt index ec244ede74..180da9cc89 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiNotificationClient.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiNotificationClient.kt @@ -14,8 +14,11 @@ import org.matrix.rustcomponents.sdk.NotificationItemsRequest class FakeFfiNotificationClient( var notificationItemResult: Map = emptyMap(), + val closeResult: () -> Unit = { } ) : NotificationClient(NoPointer) { override suspend fun getNotifications(requests: List): Map { return notificationItemResult } + + override fun close() = closeResult() } diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationServiceTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationServiceTest.kt index c0d7ddf09b..3166acc891 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationServiceTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationServiceTest.kt @@ -19,6 +19,7 @@ import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.A_USER_ID_2 import io.element.android.services.toolbox.api.systemclock.SystemClock import io.element.android.services.toolbox.test.systemclock.FakeSystemClock +import io.element.android.tests.testutils.lambda.lambdaRecorder import io.element.android.tests.testutils.testCoroutineDispatchers import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest @@ -47,6 +48,33 @@ class RustNotificationServiceTest { ) } + @Test + fun `test unable to resolve event`() = runTest { + val notificationClient = FakeFfiNotificationClient( + notificationItemResult = emptyMap(), + ) + val sut = createRustNotificationService( + notificationClient = notificationClient, + ) + val result = sut.getNotifications(mapOf(A_ROOM_ID to listOf(AN_EVENT_ID))).getOrThrow()[AN_EVENT_ID]!! + assertThat(result.content).isEqualTo( + NotificationContent.MessageLike.UnableToResolve + ) + } + + @Test + fun `close should invoke the close method of the service`() = runTest { + val closeResult = lambdaRecorder { } + val notificationClient = FakeFfiNotificationClient( + closeResult = closeResult, + ) + val sut = createRustNotificationService( + notificationClient = notificationClient, + ) + sut.close() + closeResult.assertions().isCalledOnce() + } + private fun TestScope.createRustNotificationService( notificationClient: NotificationClient = FakeFfiNotificationClient(), clock: SystemClock = FakeSystemClock(), diff --git a/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/PushService.kt b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/PushService.kt index f9a0496efb..fb1bd14404 100644 --- a/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/PushService.kt +++ b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/PushService.kt @@ -67,4 +67,9 @@ interface PushService { * Reset the push history, including the push counter. */ suspend fun resetPushHistory() + + /** + * Reset the battery optimization state. + */ + suspend fun resetBatteryOptimizationState() } diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/DefaultPushService.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/DefaultPushService.kt index 498b461110..d628f7153e 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/DefaultPushService.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/DefaultPushService.kt @@ -15,6 +15,7 @@ import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.push.api.GetCurrentPushProvider import io.element.android.libraries.push.api.PushService import io.element.android.libraries.push.api.history.PushHistoryItem +import io.element.android.libraries.push.impl.push.MutableBatteryOptimizationStore import io.element.android.libraries.push.impl.store.PushDataStore import io.element.android.libraries.push.impl.test.TestPush import io.element.android.libraries.pushproviders.api.Distributor @@ -37,6 +38,7 @@ class DefaultPushService @Inject constructor( private val sessionObserver: SessionObserver, private val pushClientSecretStore: PushClientSecretStore, private val pushDataStore: PushDataStore, + private val mutableBatteryOptimizationStore: MutableBatteryOptimizationStore, ) : PushService, SessionListener { init { observeSessions() @@ -138,4 +140,8 @@ class DefaultPushService @Inject constructor( override suspend fun resetPushHistory() { pushDataStore.reset() } + + override suspend fun resetBatteryOptimizationState() { + mutableBatteryOptimizationStore.reset() + } } diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt index d5eef83564..9a6b119a26 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt @@ -225,6 +225,11 @@ class DefaultNotifiableEventResolver @Inject constructor( val fallbackNotifiableEvent = fallbackNotifiableEvent(userId, roomId, eventId) ResolvedPushEvent.Event(fallbackNotifiableEvent) } + NotificationContent.MessageLike.UnableToResolve -> { + Timber.tag(loggerTag.value).w("Unable to resolve notification -> fallback") + val fallbackNotifiableEvent = fallbackNotifiableEvent(userId, roomId, eventId) + ResolvedPushEvent.Event(fallbackNotifiableEvent) + } is NotificationContent.MessageLike.RoomRedaction -> { // Note: this case will be handled below val redactedEventId = content.redactedEventId diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandler.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandler.kt index d42ca28c88..4d9e390690 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandler.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandler.kt @@ -25,6 +25,7 @@ import io.element.android.libraries.push.impl.history.onUnableToRetrieveSession import io.element.android.libraries.push.impl.notifications.NotificationEventRequest import io.element.android.libraries.push.impl.notifications.NotificationResolverQueue import io.element.android.libraries.push.impl.notifications.channels.NotificationChannels +import io.element.android.libraries.push.impl.notifications.model.FallbackNotifiableEvent import io.element.android.libraries.push.impl.notifications.model.NotifiableEvent import io.element.android.libraries.push.impl.notifications.model.NotifiableRingingCallEvent import io.element.android.libraries.push.impl.notifications.model.ResolvedPushEvent @@ -87,13 +88,24 @@ class DefaultPushHandler @Inject constructor( } else { result.fold( onSuccess = { - pushHistoryService.onSuccess( - providerInfo = request.providerInfo, - eventId = request.eventId, - roomId = request.roomId, - sessionId = request.sessionId, - comment = "Push handled successfully", - ) + if (it is ResolvedPushEvent.Event && it.notifiableEvent is FallbackNotifiableEvent) { + pushHistoryService.onUnableToResolveEvent( + providerInfo = request.providerInfo, + eventId = request.eventId, + roomId = request.roomId, + sessionId = request.sessionId, + reason = "Showing fallback notification", + ) + mutableBatteryOptimizationStore.showBatteryOptimizationBanner() + } else { + pushHistoryService.onSuccess( + providerInfo = request.providerInfo, + eventId = request.eventId, + roomId = request.roomId, + sessionId = request.sessionId, + comment = "Push handled successfully", + ) + } }, onFailure = { exception -> pushHistoryService.onUnableToResolveEvent( diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/MutableBatteryOptimizationStore.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/MutableBatteryOptimizationStore.kt index 1c1d9186f6..14e2cfd97b 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/MutableBatteryOptimizationStore.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/MutableBatteryOptimizationStore.kt @@ -15,6 +15,7 @@ import javax.inject.Inject interface MutableBatteryOptimizationStore { suspend fun showBatteryOptimizationBanner() suspend fun onOptimizationBannerDismissed() + suspend fun reset() } @ContributesBinding(AppScope::class) @@ -28,4 +29,8 @@ class DefaultMutableBatteryOptimizationStore @Inject constructor( override suspend fun onOptimizationBannerDismissed() { defaultPushDataStore.setBatteryOptimizationBannerState(DefaultPushDataStore.BATTERY_OPTIMIZATION_BANNER_STATE_DISMISSED) } + + override suspend fun reset() { + defaultPushDataStore.setBatteryOptimizationBannerState(DefaultPushDataStore.BATTERY_OPTIMIZATION_BANNER_STATE_INIT) + } } diff --git a/libraries/push/impl/src/main/res/values/localazy.xml b/libraries/push/impl/src/main/res/values/localazy.xml index 9860c8bef7..069183a3a2 100644 --- a/libraries/push/impl/src/main/res/values/localazy.xml +++ b/libraries/push/impl/src/main/res/values/localazy.xml @@ -13,7 +13,7 @@ "%d notification" "%d notifications" - "Notification" + "You have new messages." "📹 Incoming call" "** Failed to send - please open room" "Join" diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/DefaultPushServiceTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/DefaultPushServiceTest.kt index f3333e84f7..5ae8ab261e 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/DefaultPushServiceTest.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/DefaultPushServiceTest.kt @@ -7,13 +7,19 @@ package io.element.android.libraries.push.impl +import app.cash.turbine.test import com.google.common.truth.Truth.assertThat import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.SessionId +import io.element.android.libraries.matrix.test.AN_EVENT_ID import io.element.android.libraries.matrix.test.AN_EXCEPTION +import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.push.api.GetCurrentPushProvider +import io.element.android.libraries.push.api.history.PushHistoryItem +import io.element.android.libraries.push.impl.push.FakeMutableBatteryOptimizationStore +import io.element.android.libraries.push.impl.push.MutableBatteryOptimizationStore import io.element.android.libraries.push.impl.store.InMemoryPushDataStore import io.element.android.libraries.push.impl.store.PushDataStore import io.element.android.libraries.push.impl.test.FakeTestPush @@ -283,6 +289,53 @@ class DefaultPushServiceTest { assertThat(userPushStore.getPushProviderName()).isEqualTo(aPushProvider.name) } + @Test + fun `resetBatteryOptimizationState invokes the store method`() = runTest { + val resetResult = lambdaRecorder { } + val defaultPushService = createDefaultPushService( + mutableBatteryOptimizationStore = FakeMutableBatteryOptimizationStore( + resetResult = resetResult, + ), + ) + defaultPushService.resetBatteryOptimizationState() + resetResult.assertions().isCalledOnce() + } + + @Test + fun `resetPushHistory invokes the store method`() = runTest { + val resetResult = lambdaRecorder { } + val defaultPushService = createDefaultPushService( + pushDataStore = InMemoryPushDataStore( + resetResult = resetResult + ), + ) + defaultPushService.resetPushHistory() + resetResult.assertions().isCalledOnce() + } + + @Test + fun `getPushHistoryItemsFlow invokes the store method`() = runTest { + val store = InMemoryPushDataStore() + val aPushHistoryItem = PushHistoryItem( + pushDate = 0L, + formattedDate = "formattedDate", + providerInfo = "providerInfo", + eventId = AN_EVENT_ID, + roomId = A_ROOM_ID, + sessionId = A_SESSION_ID, + hasBeenResolved = false, + comment = null, + ) + val defaultPushService = createDefaultPushService( + pushDataStore = store, + ) + defaultPushService.getPushHistoryItemsFlow().test { + assertThat(awaitItem().isEmpty()).isTrue() + store.emitPushHistoryItems(listOf(aPushHistoryItem)) + assertThat(awaitItem().first()).isEqualTo(aPushHistoryItem) + } + } + private fun createDefaultPushService( testPush: TestPush = FakeTestPush(), userPushStoreFactory: UserPushStoreFactory = FakeUserPushStoreFactory(), @@ -291,6 +344,7 @@ class DefaultPushServiceTest { sessionObserver: SessionObserver = NoOpSessionObserver(), pushClientSecretStore: PushClientSecretStore = InMemoryPushClientSecretStore(), pushDataStore: PushDataStore = InMemoryPushDataStore(), + mutableBatteryOptimizationStore: MutableBatteryOptimizationStore = FakeMutableBatteryOptimizationStore(), ): DefaultPushService { return DefaultPushService( testPush = testPush, @@ -300,6 +354,7 @@ class DefaultPushServiceTest { sessionObserver = sessionObserver, pushClientSecretStore = pushClientSecretStore, pushDataStore = pushDataStore, + mutableBatteryOptimizationStore = mutableBatteryOptimizationStore, ) } } diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolverTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolverTest.kt index 2ba00156c7..5b93e90064 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolverTest.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolverTest.kt @@ -608,7 +608,32 @@ class DefaultNotifiableEventResolverTest { roomId = A_ROOM_ID, eventId = AN_EVENT_ID, editedEventId = null, - description = "Notification", + description = "You have new messages.", + canBeReplaced = true, + isRedacted = false, + isUpdated = false, + timestamp = A_FAKE_TIMESTAMP, + ) + ) + assertThat(result.getEvent(request)).isEqualTo(Result.success(expectedResult)) + } + + @Test + fun `resolve UnableToResolve`() = runTest { + val sut = createDefaultNotifiableEventResolver( + notificationResult = Result.success( + mapOf(AN_EVENT_ID to aNotificationData(content = NotificationContent.MessageLike.UnableToResolve)) + ) + ) + val request = NotificationEventRequest(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID, "firebase") + val result = sut.resolveEvents(A_SESSION_ID, listOf(request)) + val expectedResult = ResolvedPushEvent.Event( + FallbackNotifiableEvent( + sessionId = A_SESSION_ID, + roomId = A_ROOM_ID, + eventId = AN_EVENT_ID, + editedEventId = null, + description = "You have new messages.", canBeReplaced = true, isRedacted = false, isUpdated = false, diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/push/FakeMutableBatteryOptimizationStore.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/push/FakeMutableBatteryOptimizationStore.kt index 9e526debbb..d4d3992f1e 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/push/FakeMutableBatteryOptimizationStore.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/push/FakeMutableBatteryOptimizationStore.kt @@ -12,6 +12,7 @@ import io.element.android.tests.testutils.lambda.lambdaError class FakeMutableBatteryOptimizationStore( private val showBatteryOptimizationBannerResult: () -> Unit = { lambdaError() }, private val onOptimizationBannerDismissedResult: () -> Unit = { lambdaError() }, + private val resetResult: () -> Unit = { lambdaError() }, ) : MutableBatteryOptimizationStore { override suspend fun showBatteryOptimizationBanner() { showBatteryOptimizationBannerResult() @@ -20,4 +21,8 @@ class FakeMutableBatteryOptimizationStore( override suspend fun onOptimizationBannerDismissed() { onOptimizationBannerDismissedResult() } + + override suspend fun reset() { + resetResult() + } } diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/store/InMemoryPushDataStore.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/store/InMemoryPushDataStore.kt index 4f710e09b6..41b0546f33 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/store/InMemoryPushDataStore.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/store/InMemoryPushDataStore.kt @@ -31,6 +31,10 @@ class InMemoryPushDataStore( return mutablePushHistoryItemsFlow.asStateFlow() } + suspend fun emitPushHistoryItems(items: List) { + mutablePushHistoryItemsFlow.emit(items) + } + override suspend fun reset() { resetResult() } diff --git a/libraries/push/test/src/main/kotlin/io/element/android/libraries/push/test/FakePushService.kt b/libraries/push/test/src/main/kotlin/io/element/android/libraries/push/test/FakePushService.kt index 5c3c01e8e8..553ac09465 100644 --- a/libraries/push/test/src/main/kotlin/io/element/android/libraries/push/test/FakePushService.kt +++ b/libraries/push/test/src/main/kotlin/io/element/android/libraries/push/test/FakePushService.kt @@ -28,6 +28,7 @@ class FakePushService( private val selectPushProviderLambda: suspend (SessionId, PushProvider) -> Unit = { _, _ -> lambdaError() }, private val setIgnoreRegistrationErrorLambda: (SessionId, Boolean) -> Unit = { _, _ -> lambdaError() }, private val resetPushHistoryResult: () -> Unit = { lambdaError() }, + private val resetBatteryOptimizationStateResult: () -> Unit = { lambdaError() }, ) : PushService { override suspend fun getCurrentPushProvider(): PushProvider? { return registeredPushProvider ?: currentPushProvider() @@ -92,4 +93,8 @@ class FakePushService( override suspend fun resetPushHistory() = simulateLongTask { resetPushHistoryResult() } + + override suspend fun resetBatteryOptimizationState() { + resetBatteryOptimizationStateResult() + } }