mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-15 01:35:07 +08:00
Fix clear cache issue: sometimes, after a clear cache, there is still a token, so the init sync service is not started.
Migratiing to supend methods fixes the problem, I'm not sure why...
This commit is contained in:
parent
68f422e498
commit
4709002429
@ -8,7 +8,7 @@ Improvements 🙌:
|
||||
-
|
||||
|
||||
Bugfix 🐛:
|
||||
-
|
||||
- Fix clear cache issue: sometimes, after a clear cache, there is still a token, so the init sync service is not started.
|
||||
|
||||
Translations 🗣:
|
||||
-
|
||||
|
@ -16,8 +16,6 @@
|
||||
|
||||
package org.matrix.android.sdk.api.session.cache
|
||||
|
||||
import org.matrix.android.sdk.api.MatrixCallback
|
||||
|
||||
/**
|
||||
* This interface defines a method to clear the cache. It's implemented at the session level.
|
||||
*/
|
||||
@ -26,5 +24,5 @@ interface CacheService {
|
||||
/**
|
||||
* Clear the whole cached data, except credentials. Once done, the sync has to be restarted by the sdk user.
|
||||
*/
|
||||
fun clearCache(callback: MatrixCallback<Unit>)
|
||||
suspend fun clearCache()
|
||||
}
|
||||
|
@ -16,9 +16,7 @@
|
||||
|
||||
package org.matrix.android.sdk.api.session.signout
|
||||
|
||||
import org.matrix.android.sdk.api.MatrixCallback
|
||||
import org.matrix.android.sdk.api.auth.data.Credentials
|
||||
import org.matrix.android.sdk.api.util.Cancelable
|
||||
|
||||
/**
|
||||
* This interface defines a method to sign out, or to renew the token. It's implemented at the session level.
|
||||
@ -29,19 +27,16 @@ interface SignOutService {
|
||||
* Ask the homeserver for a new access token.
|
||||
* The same deviceId will be used
|
||||
*/
|
||||
fun signInAgain(password: String,
|
||||
callback: MatrixCallback<Unit>): Cancelable
|
||||
suspend fun signInAgain(password: String)
|
||||
|
||||
/**
|
||||
* Update the session with credentials received after SSO
|
||||
*/
|
||||
fun updateCredentials(credentials: Credentials,
|
||||
callback: MatrixCallback<Unit>): Cancelable
|
||||
suspend fun updateCredentials(credentials: Credentials)
|
||||
|
||||
/**
|
||||
* Sign out, and release the session, clear all the session data, including crypto data
|
||||
* @param signOutFromHomeserver true if the sign out request has to be done
|
||||
*/
|
||||
fun signOut(signOutFromHomeserver: Boolean,
|
||||
callback: MatrixCallback<Unit>): Cancelable
|
||||
suspend fun signOut(signOutFromHomeserver: Boolean)
|
||||
}
|
||||
|
@ -217,13 +217,13 @@ internal class DefaultSession @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
override fun clearCache(callback: MatrixCallback<Unit>) {
|
||||
override suspend fun clearCache() {
|
||||
stopSync()
|
||||
stopAnyBackgroundSync()
|
||||
uiHandler.post {
|
||||
lifecycleObservers.forEach { it.onClearCache() }
|
||||
}
|
||||
cacheService.get().clearCache(callback)
|
||||
cacheService.get().clearCache()
|
||||
workManagerProvider.cancelAllWorks()
|
||||
}
|
||||
|
||||
|
@ -16,23 +16,18 @@
|
||||
|
||||
package org.matrix.android.sdk.internal.session.cache
|
||||
|
||||
import org.matrix.android.sdk.api.MatrixCallback
|
||||
import org.matrix.android.sdk.api.session.cache.CacheService
|
||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||
import org.matrix.android.sdk.internal.task.TaskExecutor
|
||||
import org.matrix.android.sdk.internal.task.configureWith
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class DefaultCacheService @Inject constructor(@SessionDatabase
|
||||
private val clearCacheTask: ClearCacheTask,
|
||||
private val taskExecutor: TaskExecutor) : CacheService {
|
||||
private val taskExecutor: TaskExecutor
|
||||
) : CacheService {
|
||||
|
||||
override fun clearCache(callback: MatrixCallback<Unit>) {
|
||||
override suspend fun clearCache() {
|
||||
taskExecutor.cancelAll()
|
||||
clearCacheTask
|
||||
.configureWith {
|
||||
this.callback = callback
|
||||
}
|
||||
.executeBy(taskExecutor)
|
||||
clearCacheTask.execute(Unit)
|
||||
}
|
||||
}
|
||||
|
@ -16,45 +16,25 @@
|
||||
|
||||
package org.matrix.android.sdk.internal.session.signout
|
||||
|
||||
import org.matrix.android.sdk.api.MatrixCallback
|
||||
import org.matrix.android.sdk.api.auth.data.Credentials
|
||||
import org.matrix.android.sdk.api.session.signout.SignOutService
|
||||
import org.matrix.android.sdk.api.util.Cancelable
|
||||
import org.matrix.android.sdk.internal.auth.SessionParamsStore
|
||||
import org.matrix.android.sdk.internal.task.TaskExecutor
|
||||
import org.matrix.android.sdk.internal.task.configureWith
|
||||
import org.matrix.android.sdk.internal.task.launchToCallback
|
||||
import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class DefaultSignOutService @Inject constructor(private val signOutTask: SignOutTask,
|
||||
private val signInAgainTask: SignInAgainTask,
|
||||
private val sessionParamsStore: SessionParamsStore,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
private val taskExecutor: TaskExecutor) : SignOutService {
|
||||
private val sessionParamsStore: SessionParamsStore
|
||||
) : SignOutService {
|
||||
|
||||
override fun signInAgain(password: String,
|
||||
callback: MatrixCallback<Unit>): Cancelable {
|
||||
return signInAgainTask
|
||||
.configureWith(SignInAgainTask.Params(password)) {
|
||||
this.callback = callback
|
||||
}
|
||||
.executeBy(taskExecutor)
|
||||
override suspend fun signInAgain(password: String) {
|
||||
signInAgainTask.execute(SignInAgainTask.Params(password))
|
||||
}
|
||||
|
||||
override fun updateCredentials(credentials: Credentials,
|
||||
callback: MatrixCallback<Unit>): Cancelable {
|
||||
return taskExecutor.executorScope.launchToCallback(coroutineDispatchers.main, callback) {
|
||||
sessionParamsStore.updateCredentials(credentials)
|
||||
}
|
||||
override suspend fun updateCredentials(credentials: Credentials) {
|
||||
sessionParamsStore.updateCredentials(credentials)
|
||||
}
|
||||
|
||||
override fun signOut(signOutFromHomeserver: Boolean,
|
||||
callback: MatrixCallback<Unit>): Cancelable {
|
||||
return signOutTask
|
||||
.configureWith(SignOutTask.Params(signOutFromHomeserver)) {
|
||||
this.callback = callback
|
||||
}
|
||||
.executeBy(taskExecutor)
|
||||
override suspend fun signOut(signOutFromHomeserver: Boolean) {
|
||||
return signOutTask.execute(SignOutTask.Params(signOutFromHomeserver))
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 im.vector.app.core.platform
|
||||
|
||||
import com.airbnb.mvrx.MvRxState
|
||||
|
||||
data class EmptyState(
|
||||
val dummy: Int = 0
|
||||
) : MvRxState
|
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 im.vector.app.core.platform
|
||||
|
||||
/**
|
||||
* Mainly used to get a viewModelScope
|
||||
*/
|
||||
class EmptyViewModel(initialState: EmptyState) : VectorViewModel<EmptyState, EmptyAction, EmptyViewEvents>(initialState) {
|
||||
override fun handle(action: EmptyAction) {
|
||||
// N/A
|
||||
}
|
||||
}
|
@ -22,12 +22,15 @@ import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.airbnb.mvrx.viewModel
|
||||
import com.bumptech.glide.Glide
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.di.ActiveSessionHolder
|
||||
import im.vector.app.core.di.ScreenComponent
|
||||
import im.vector.app.core.error.ErrorFormatter
|
||||
import im.vector.app.core.extensions.startSyncing
|
||||
import im.vector.app.core.platform.EmptyViewModel
|
||||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
import im.vector.app.core.utils.deleteAllFiles
|
||||
import im.vector.app.databinding.FragmentLoadingBinding
|
||||
@ -45,10 +48,8 @@ import im.vector.app.features.signout.soft.SoftLogoutActivity
|
||||
import im.vector.app.features.ui.UiStateRepository
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.matrix.android.sdk.api.MatrixCallback
|
||||
import org.matrix.android.sdk.api.failure.GlobalError
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
@ -82,6 +83,8 @@ class MainActivity : VectorBaseActivity<FragmentLoadingBinding>(), UnlockedActiv
|
||||
}
|
||||
}
|
||||
|
||||
private val emptyViewModel: EmptyViewModel by viewModel()
|
||||
|
||||
override fun getBinding() = FragmentLoadingBinding.inflate(layoutInflater)
|
||||
|
||||
private lateinit var args: MainActivityArgs
|
||||
@ -147,38 +150,41 @@ class MainActivity : VectorBaseActivity<FragmentLoadingBinding>(), UnlockedActiv
|
||||
}
|
||||
when {
|
||||
args.isAccountDeactivated -> {
|
||||
// Just do the local cleanup
|
||||
Timber.w("Account deactivated, start app")
|
||||
sessionHolder.clearActiveSession()
|
||||
doLocalCleanup(clearPreferences = true)
|
||||
startNextActivityAndFinish()
|
||||
emptyViewModel.viewModelScope.launch {
|
||||
// Just do the local cleanup
|
||||
Timber.w("Account deactivated, start app")
|
||||
sessionHolder.clearActiveSession()
|
||||
doLocalCleanup(clearPreferences = true)
|
||||
startNextActivityAndFinish()
|
||||
}
|
||||
}
|
||||
args.clearCredentials -> {
|
||||
emptyViewModel.viewModelScope.launch {
|
||||
try {
|
||||
session.signOut(!args.isUserLoggedOut)
|
||||
Timber.w("SIGN_OUT: success, start app")
|
||||
sessionHolder.clearActiveSession()
|
||||
doLocalCleanup(clearPreferences = true)
|
||||
startNextActivityAndFinish()
|
||||
} catch (failure: Throwable) {
|
||||
displayError(failure)
|
||||
}
|
||||
}
|
||||
}
|
||||
args.clearCache -> {
|
||||
emptyViewModel.viewModelScope.launch {
|
||||
try {
|
||||
session.clearCache()
|
||||
Timber.e("CACHE success")
|
||||
doLocalCleanup(clearPreferences = false)
|
||||
session.startSyncing(applicationContext)
|
||||
startNextActivityAndFinish()
|
||||
} catch (failure: Throwable) {
|
||||
Timber.e("CACHE failure")
|
||||
displayError(failure)
|
||||
}
|
||||
}
|
||||
}
|
||||
args.clearCredentials -> session.signOut(
|
||||
!args.isUserLoggedOut,
|
||||
object : MatrixCallback<Unit> {
|
||||
override fun onSuccess(data: Unit) {
|
||||
Timber.w("SIGN_OUT: success, start app")
|
||||
sessionHolder.clearActiveSession()
|
||||
doLocalCleanup(clearPreferences = true)
|
||||
startNextActivityAndFinish()
|
||||
}
|
||||
|
||||
override fun onFailure(failure: Throwable) {
|
||||
displayError(failure)
|
||||
}
|
||||
})
|
||||
args.clearCache -> session.clearCache(
|
||||
object : MatrixCallback<Unit> {
|
||||
override fun onSuccess(data: Unit) {
|
||||
doLocalCleanup(clearPreferences = false)
|
||||
session.startSyncing(applicationContext)
|
||||
startNextActivityAndFinish()
|
||||
}
|
||||
|
||||
override fun onFailure(failure: Throwable) {
|
||||
displayError(failure)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -187,24 +193,22 @@ class MainActivity : VectorBaseActivity<FragmentLoadingBinding>(), UnlockedActiv
|
||||
Timber.w("Ignoring invalid token global error")
|
||||
}
|
||||
|
||||
private fun doLocalCleanup(clearPreferences: Boolean) {
|
||||
GlobalScope.launch(Dispatchers.Main) {
|
||||
// On UI Thread
|
||||
Glide.get(this@MainActivity).clearMemory()
|
||||
private suspend fun doLocalCleanup(clearPreferences: Boolean) {
|
||||
// On UI Thread
|
||||
Glide.get(this@MainActivity).clearMemory()
|
||||
|
||||
if (clearPreferences) {
|
||||
vectorPreferences.clearPreferences()
|
||||
uiStateRepository.reset()
|
||||
pinLocker.unlock()
|
||||
pinCodeStore.deleteEncodedPin()
|
||||
}
|
||||
withContext(Dispatchers.IO) {
|
||||
// On BG thread
|
||||
Glide.get(this@MainActivity).clearDiskCache()
|
||||
if (clearPreferences) {
|
||||
vectorPreferences.clearPreferences()
|
||||
uiStateRepository.reset()
|
||||
pinLocker.unlock()
|
||||
pinCodeStore.deleteEncodedPin()
|
||||
}
|
||||
withContext(Dispatchers.IO) {
|
||||
// On BG thread
|
||||
Glide.get(this@MainActivity).clearDiskCache()
|
||||
|
||||
// Also clear cache (Logs, etc...)
|
||||
deleteAllFiles(this@MainActivity.cacheDir)
|
||||
}
|
||||
// Also clear cache (Logs, etc...)
|
||||
deleteAllFiles(this@MainActivity.cacheDir)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,10 +19,13 @@ package im.vector.app.features.link
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.airbnb.mvrx.viewModel
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.di.ActiveSessionHolder
|
||||
import im.vector.app.core.di.ScreenComponent
|
||||
import im.vector.app.core.error.ErrorFormatter
|
||||
import im.vector.app.core.platform.EmptyViewModel
|
||||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
import im.vector.app.core.utils.toast
|
||||
import im.vector.app.databinding.ActivityProgressBinding
|
||||
@ -30,7 +33,7 @@ import im.vector.app.features.login.LoginActivity
|
||||
import im.vector.app.features.login.LoginConfig
|
||||
import im.vector.app.features.permalink.PermalinkHandler
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import org.matrix.android.sdk.api.MatrixCallback
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.api.session.permalinks.PermalinkService
|
||||
import timber.log.Timber
|
||||
import java.util.concurrent.TimeUnit
|
||||
@ -45,6 +48,8 @@ class LinkHandlerActivity : VectorBaseActivity<ActivityProgressBinding>() {
|
||||
@Inject lateinit var errorFormatter: ErrorFormatter
|
||||
@Inject lateinit var permalinkHandler: PermalinkHandler
|
||||
|
||||
private val emptyViewModel: EmptyViewModel by viewModel()
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
injector.inject(this)
|
||||
}
|
||||
@ -139,23 +144,30 @@ class LinkHandlerActivity : VectorBaseActivity<ActivityProgressBinding>() {
|
||||
.setTitle(R.string.dialog_title_warning)
|
||||
.setMessage(R.string.error_user_already_logged_in)
|
||||
.setCancelable(false)
|
||||
.setPositiveButton(R.string.logout) { _, _ ->
|
||||
sessionHolder.getSafeActiveSession()?.signOut(true, object : MatrixCallback<Unit> {
|
||||
override fun onFailure(failure: Throwable) {
|
||||
displayError(failure)
|
||||
}
|
||||
|
||||
override fun onSuccess(data: Unit) {
|
||||
Timber.d("## displayAlreadyLoginPopup(): logout succeeded")
|
||||
sessionHolder.clearActiveSession()
|
||||
startLoginActivity(uri)
|
||||
}
|
||||
}) ?: finish()
|
||||
}
|
||||
.setPositiveButton(R.string.logout) { _, _ -> safeSignout(uri) }
|
||||
.setNegativeButton(R.string.cancel) { _, _ -> finish() }
|
||||
.show()
|
||||
}
|
||||
|
||||
private fun safeSignout(uri: Uri) {
|
||||
val session = sessionHolder.getSafeActiveSession()
|
||||
if(session == null) {
|
||||
// Should not happen
|
||||
startLoginActivity(uri)
|
||||
} else {
|
||||
emptyViewModel.viewModelScope.launch {
|
||||
try {
|
||||
session.signOut(true)
|
||||
Timber.d("## displayAlreadyLoginPopup(): logout succeeded")
|
||||
sessionHolder.clearActiveSession()
|
||||
startLoginActivity(uri)
|
||||
} catch (failure: Throwable) {
|
||||
displayError(failure)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun displayError(failure: Throwable) {
|
||||
AlertDialog.Builder(this)
|
||||
.setTitle(R.string.dialog_title_error)
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
package im.vector.app.features.signout.soft
|
||||
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.airbnb.mvrx.ActivityViewModelContext
|
||||
import com.airbnb.mvrx.Fail
|
||||
import com.airbnb.mvrx.Loading
|
||||
@ -30,6 +31,7 @@ import im.vector.app.core.di.ActiveSessionHolder
|
||||
import im.vector.app.core.extensions.hasUnsavedKeys
|
||||
import im.vector.app.core.platform.VectorViewModel
|
||||
import im.vector.app.features.login.LoginMode
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.api.MatrixCallback
|
||||
import org.matrix.android.sdk.api.auth.AuthenticationService
|
||||
import org.matrix.android.sdk.api.auth.data.LoginFlowResult
|
||||
@ -174,22 +176,19 @@ class SoftLogoutViewModel @AssistedInject constructor(
|
||||
asyncLoginAction = Loading()
|
||||
)
|
||||
}
|
||||
currentTask = session.updateCredentials(action.credentials,
|
||||
object : MatrixCallback<Unit> {
|
||||
override fun onFailure(failure: Throwable) {
|
||||
_viewEvents.post(SoftLogoutViewEvents.Failure(failure))
|
||||
setState {
|
||||
copy(
|
||||
asyncLoginAction = Uninitialized
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSuccess(data: Unit) {
|
||||
onSessionRestored()
|
||||
}
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
session.updateCredentials(action.credentials)
|
||||
onSessionRestored()
|
||||
} catch (failure: Throwable) {
|
||||
_viewEvents.post(SoftLogoutViewEvents.Failure(failure))
|
||||
setState {
|
||||
copy(
|
||||
asyncLoginAction = Uninitialized
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -202,21 +201,18 @@ class SoftLogoutViewModel @AssistedInject constructor(
|
||||
passwordShown = false
|
||||
)
|
||||
}
|
||||
currentTask = session.signInAgain(action.password,
|
||||
object : MatrixCallback<Unit> {
|
||||
override fun onFailure(failure: Throwable) {
|
||||
setState {
|
||||
copy(
|
||||
asyncLoginAction = Fail(failure)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSuccess(data: Unit) {
|
||||
onSessionRestored()
|
||||
}
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
session.signInAgain(action.password)
|
||||
onSessionRestored()
|
||||
} catch (failure: Throwable) {
|
||||
setState {
|
||||
copy(
|
||||
asyncLoginAction = Fail(failure)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun onSessionRestored() {
|
||||
|
Loading…
Reference in New Issue
Block a user