diff --git a/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt index 57aa598dc5..733485fcef 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt @@ -44,6 +44,7 @@ import io.element.android.appnav.root.RootPresenter import io.element.android.appnav.root.RootView import io.element.android.features.login.api.oidc.OidcAction import io.element.android.features.login.api.oidc.OidcActionFlow +import io.element.android.features.preferences.api.CacheService import io.element.android.features.rageshake.api.bugreport.BugReportEntryPoint import io.element.android.libraries.architecture.BackstackNode import io.element.android.libraries.architecture.animation.rememberDefaultTransitionHandler @@ -67,6 +68,7 @@ class RootFlowNode @AssistedInject constructor( @Assisted val buildContext: BuildContext, @Assisted plugins: List, private val authenticationService: MatrixAuthenticationService, + private val cacheService: CacheService, private val matrixClientsHolder: MatrixClientsHolder, private val presenter: RootPresenter, private val bugReportEntryPoint: BugReportEntryPoint, @@ -91,7 +93,7 @@ class RootFlowNode @AssistedInject constructor( authenticationService.isLoggedIn() .distinctUntilChanged() .combine( - authenticationService.cacheIndex().onEach { + cacheService.cacheIndex().onEach { Timber.v("cacheIndex=$it") matrixClientsHolder.removeAll() } @@ -245,7 +247,7 @@ class RootFlowNode @AssistedInject constructor( } private suspend fun attachSession(sessionId: SessionId): LoggedInFlowNode { - val cacheIndex = authenticationService.cacheIndex().first() + val cacheIndex = cacheService.cacheIndex().first() return attachChild { backstack.newRoot(NavTarget.LoggedInFlow(sessionId, cacheIndex)) } diff --git a/features/preferences/api/src/main/kotlin/io/element/android/features/preferences/api/CacheService.kt b/features/preferences/api/src/main/kotlin/io/element/android/features/preferences/api/CacheService.kt new file mode 100644 index 0000000000..0bc9285853 --- /dev/null +++ b/features/preferences/api/src/main/kotlin/io/element/android/features/preferences/api/CacheService.kt @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023 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. + */ + +package io.element.android.features.preferences.api + +import kotlinx.coroutines.flow.Flow + +interface CacheService { + /** + * Returns a flow of the current cache index, can let the app to know when the + * cache has been cleared, for instance to restart the app. + * Will be a flow of Int, starting from 0, and incrementing each time the cache is cleared. + */ + fun cacheIndex(): Flow +} diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/DefaultCacheService.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/DefaultCacheService.kt new file mode 100644 index 0000000000..7675ec3dd6 --- /dev/null +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/DefaultCacheService.kt @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023 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. + */ + +package io.element.android.features.preferences.impl + +import com.squareup.anvil.annotations.ContributesBinding +import io.element.android.features.preferences.api.CacheService +import io.element.android.libraries.di.AppScope +import io.element.android.libraries.di.SingleIn +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import javax.inject.Inject + +@SingleIn(AppScope::class) +@ContributesBinding(AppScope::class) +class DefaultCacheService @Inject constructor() : CacheService { + private val cacheIndexState = MutableStateFlow(0) + + override fun cacheIndex(): Flow { + return cacheIndexState + } + + fun incrementCacheIndex() { + cacheIndexState.value++ + } +} 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 68ed41babd..f7b0d01130 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 @@ -22,11 +22,11 @@ import android.content.Context import coil.Coil import coil.annotation.ExperimentalCoilApi import com.squareup.anvil.annotations.ContributesBinding +import io.element.android.features.preferences.impl.DefaultCacheService import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.di.ApplicationContext import io.element.android.libraries.di.SessionScope import io.element.android.libraries.matrix.api.MatrixClient -import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService import kotlinx.coroutines.withContext import okhttp3.OkHttpClient import javax.inject.Inject @@ -41,7 +41,7 @@ class DefaultClearCacheUseCase @Inject constructor( @ApplicationContext private val context: Context, private val matrixClient: MatrixClient, private val coroutineDispatchers: CoroutineDispatchers, - private val authenticationService: MatrixAuthenticationService, + private val defaultCacheIndexProvider: DefaultCacheService, private val okHttpClient: Provider, ) : ClearCacheUseCase { override suspend fun invoke() = withContext(coroutineDispatchers.io) { @@ -57,6 +57,6 @@ class DefaultClearCacheUseCase @Inject constructor( // Clear app cache context.cacheDir.deleteRecursively() // Ensure the app is restarted - authenticationService.incrementCacheIndex() + defaultCacheIndexProvider.incrementCacheIndex() } } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/auth/MatrixAuthenticationService.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/auth/MatrixAuthenticationService.kt index d1e2362da6..c15153876c 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/auth/MatrixAuthenticationService.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/auth/MatrixAuthenticationService.kt @@ -29,13 +29,6 @@ interface MatrixAuthenticationService { suspend fun setHomeserver(homeserver: String): Result suspend fun login(username: String, password: String): Result - /* - * Cache index - */ - - fun cacheIndex(): Flow - fun incrementCacheIndex() - /* * OIDC part. */ diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt index ac239d83c1..d599029923 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt @@ -58,8 +58,6 @@ class RustMatrixAuthenticationService @Inject constructor( private val clock: SystemClock, ) : MatrixAuthenticationService { - private val cacheIndexState = MutableStateFlow(0) - private val authService: RustAuthenticationService = RustAuthenticationService( basePath = baseDirectory.absolutePath, passphrase = null, @@ -73,14 +71,6 @@ class RustMatrixAuthenticationService @Inject constructor( return sessionStore.isLoggedIn() } - override fun incrementCacheIndex() { - cacheIndexState.value++ - } - - override fun cacheIndex(): Flow { - return cacheIndexState - } - override suspend fun getLatestSessionId(): SessionId? = withContext(coroutineDispatchers.io) { sessionStore.getLatestSession()?.userId?.let { SessionId(it) } } diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/auth/FakeAuthenticationService.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/auth/FakeAuthenticationService.kt index b40dd766ff..81fa3b677c 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/auth/FakeAuthenticationService.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/auth/FakeAuthenticationService.kt @@ -65,16 +65,6 @@ class FakeAuthenticationService : MatrixAuthenticationService { loginError?.let { Result.failure(it) } ?: Result.success(A_USER_ID) } - private val cacheIndexFlow = MutableStateFlow(0) - - override fun cacheIndex(): Flow { - return cacheIndexFlow - } - - override fun incrementCacheIndex() { - cacheIndexFlow.value++ - } - override suspend fun getOidcUrl(): Result = simulateLongTask { oidcError?.let { Result.failure(it) } ?: Result.success(A_OIDC_DATA) }