From d8095faa432de68bc18c4974079a522e807a8abb Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 17 Jun 2025 16:26:33 +0200 Subject: [PATCH] Ensure that the battery optimization banner is not displayed after an internal clear cache. --- .../preferences/impl/tasks/ClearCacheUseCase.kt | 1 + .../impl/tasks/DefaultClearCacheUseCaseTest.kt | 5 ++++- .../android/libraries/push/api/PushService.kt | 5 +++++ .../libraries/push/impl/DefaultPushService.kt | 6 ++++++ .../impl/push/MutableBatteryOptimizationStore.kt | 5 +++++ .../push/impl/DefaultPushServiceTest.kt | 16 ++++++++++++++++ .../push/FakeMutableBatteryOptimizationStore.kt | 5 +++++ .../libraries/push/test/FakePushService.kt | 5 +++++ 8 files changed, 47 insertions(+), 1 deletion(-) 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/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/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/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..bf0dddd788 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 @@ -14,6 +14,8 @@ import io.element.android.libraries.matrix.test.AN_EXCEPTION 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.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 +285,18 @@ 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() + } + private fun createDefaultPushService( testPush: TestPush = FakeTestPush(), userPushStoreFactory: UserPushStoreFactory = FakeUserPushStoreFactory(), @@ -291,6 +305,7 @@ class DefaultPushServiceTest { sessionObserver: SessionObserver = NoOpSessionObserver(), pushClientSecretStore: PushClientSecretStore = InMemoryPushClientSecretStore(), pushDataStore: PushDataStore = InMemoryPushDataStore(), + mutableBatteryOptimizationStore: MutableBatteryOptimizationStore = FakeMutableBatteryOptimizationStore(), ): DefaultPushService { return DefaultPushService( testPush = testPush, @@ -300,6 +315,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/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/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() + } }