From b1b526a5162acb285d2857b2d8a14607e9e825df Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 17 Apr 2019 15:48:59 +0200 Subject: [PATCH] Clear cache and rework Signout --- .../matrix/android/api/failure/Failure.kt | 2 +- .../matrix/android/api/failure/MatrixError.kt | 1 + .../matrix/android/api/session/Session.kt | 10 +++- .../android/api/session/cache/CacheService.kt | 31 +++++++++++++ .../api/session/room/model/RoomSummary.kt | 2 +- .../api/util/MatrixCallbackDelegate.kt | 33 +++++++++++++ .../internal/session/DefaultSession.kt | 29 +++++++++--- .../android/internal/session/SessionModule.kt | 12 +++++ .../session/cache/RealmCacheService.kt | 33 +++++++++++++ .../session/cache/RealmClearCacheTask.kt | 39 ++++++++++++++++ .../internal/session/room/DefaultRoom.kt | 9 +++- .../internal/session/signout/SignOutTask.kt | 1 - .../internal/session/sync/SyncModule.kt | 2 +- .../android/internal/session/sync/SyncTask.kt | 17 ++++++- .../internal/session/sync/job/SyncThread.kt | 16 ++++++- .../riotredesign/features/MainActivity.kt | 46 ++++++++++++++++++- .../features/home/HomeActivityViewModel.kt | 17 ++++++- .../VectorSettingsPreferencesFragment.kt | 6 +-- .../workers/signout/SignOutUiWorker.kt | 27 ++--------- 19 files changed, 289 insertions(+), 44 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/cache/CacheService.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/api/util/MatrixCallbackDelegate.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/cache/RealmCacheService.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/cache/RealmClearCacheTask.kt diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/failure/Failure.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/failure/Failure.kt index 50713d48..94e3776e 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/failure/Failure.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/failure/Failure.kt @@ -19,7 +19,7 @@ package im.vector.matrix.android.api.failure import java.io.IOException /** - * This class allows to expose differents kind of error to be then handled by the application. + * This class allows to expose different kinds of error to be then handled by the application. * As it is a sealed class, you typically use it like that : * when(failure) { * is NetworkConnection -> Unit diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/failure/MatrixError.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/failure/MatrixError.kt index b6aa3f68..92cba3b8 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/failure/MatrixError.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/failure/MatrixError.kt @@ -33,6 +33,7 @@ data class MatrixError( const val FORBIDDEN = "M_FORBIDDEN" const val UNKNOWN = "M_UNKNOWN" const val UNKNOWN_TOKEN = "M_UNKNOWN_TOKEN" + const val MISSING_TOKEN = "M_MISSING_TOKEN" const val BAD_JSON = "M_BAD_JSON" const val NOT_JSON = "M_NOT_JSON" const val NOT_FOUND = "M_NOT_FOUND" diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt index bdf1d670..742adb90 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt @@ -18,6 +18,7 @@ package im.vector.matrix.android.api.session import androidx.annotation.MainThread import im.vector.matrix.android.api.auth.data.SessionParams +import im.vector.matrix.android.api.session.cache.CacheService import im.vector.matrix.android.api.session.content.ContentUploadStateTracker import im.vector.matrix.android.api.session.content.ContentUrlResolver import im.vector.matrix.android.api.session.crypto.CryptoService @@ -36,6 +37,7 @@ interface Session : GroupService, UserService, CryptoService, + CacheService, SignOutService, FilterService { @@ -93,7 +95,11 @@ interface Session : /** * A global session listener to get notified for some events. */ - // Not used at the moment - interface Listener + interface Listener { + /** + * The access token is not valid anymore + */ + fun onInvalidToken() + } } \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/cache/CacheService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/cache/CacheService.kt new file mode 100644 index 00000000..43ab78b5 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/cache/CacheService.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2019 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.matrix.android.api.session.cache + +import im.vector.matrix.android.api.MatrixCallback + +/** + * This interface defines a method to sign out. It's implemented at the session level. + */ +interface CacheService { + + /** + * Clear the whole cached data, except credentials. Once done, the session is closed and has to be opened again + */ + fun clearCache(callback: MatrixCallback) + +} \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomSummary.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomSummary.kt index bda5a54c..429d7882 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomSummary.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomSummary.kt @@ -28,7 +28,7 @@ data class RoomSummary( val displayName: String = "", val topic: String = "", val avatarUrl: String = "", - val isDirect: Boolean, + val isDirect: Boolean = false, val lastMessage: Event? = null, val otherMemberIds: List = emptyList(), var notificationCount: Int = 0, diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/util/MatrixCallbackDelegate.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/util/MatrixCallbackDelegate.kt new file mode 100644 index 00000000..f98cf5a3 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/util/MatrixCallbackDelegate.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2019 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.matrix.android.api.util + +import im.vector.matrix.android.api.MatrixCallback + +/** + * Simple MatrixCallback implementation which delegate its calls to another callback + */ +open class MatrixCallbackDelegate(private val callback: MatrixCallback) : MatrixCallback { + + override fun onSuccess(data: T) { + callback.onSuccess(data) + } + + override fun onFailure(failure: Throwable) { + callback.onFailure(failure) + } +} \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt index 8ac7811c..42e5d8ed 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt @@ -23,6 +23,7 @@ import com.zhuinden.monarchy.Monarchy import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.auth.data.SessionParams import im.vector.matrix.android.api.session.Session +import im.vector.matrix.android.api.session.cache.CacheService import im.vector.matrix.android.api.session.content.ContentUploadStateTracker import im.vector.matrix.android.api.session.content.ContentUrlResolver import im.vector.matrix.android.api.session.group.Group @@ -36,6 +37,7 @@ import im.vector.matrix.android.api.session.signout.SignOutService import im.vector.matrix.android.api.session.sync.FilterService import im.vector.matrix.android.api.session.user.UserService import im.vector.matrix.android.api.session.user.model.User +import im.vector.matrix.android.api.util.MatrixCallbackDelegate import im.vector.matrix.android.internal.database.LiveEntityObserver import im.vector.matrix.android.internal.di.MatrixKoinComponent import im.vector.matrix.android.internal.di.MatrixKoinHolder @@ -65,6 +67,7 @@ internal class DefaultSession(override val sessionParams: SessionParams) : Sessi private val groupService by inject() private val userService by inject() private val filterService by inject() + private val cacheService by inject() private val signOutService by inject() private val syncThread by inject() private val contentUrlResolver by inject() @@ -118,17 +121,18 @@ internal class DefaultSession(override val sessionParams: SessionParams) : Sessi @MainThread override fun signOut(callback: MatrixCallback) { assert(isOpen) + syncThread.kill() + return signOutService.signOut(object : MatrixCallback { override fun onSuccess(data: Unit) { - // Close the session - stopSync() - close() - - callback.onSuccess(data) + // Clear the cache + cacheService.clearCache(object : MatrixCallbackDelegate(callback) {}) } override fun onFailure(failure: Throwable) { - callback.onFailure(failure) + // Ignore failure + onSuccess(Unit) + // callback.onFailure(failure) } }) } @@ -184,6 +188,19 @@ internal class DefaultSession(override val sessionParams: SessionParams) : Sessi return filterService.setFilter(filterPreset) } + override fun clearCache(callback: MatrixCallback) { + assert(isOpen) + syncThread.pause() + cacheService.clearCache(object : MatrixCallbackDelegate(callback) { + override fun onSuccess(data: Unit) { + // Restart the sync + syncThread.restart() + + super.onSuccess(data) + } + }) + } + // USER SERVICE override fun getUser(userId: String): User? { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt index 43e0b8a7..accb91ec 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt @@ -19,6 +19,7 @@ package im.vector.matrix.android.internal.session import android.content.Context import com.zhuinden.monarchy.Monarchy import im.vector.matrix.android.api.auth.data.SessionParams +import im.vector.matrix.android.api.session.cache.CacheService import im.vector.matrix.android.api.session.group.GroupService import im.vector.matrix.android.api.session.room.RoomService import im.vector.matrix.android.api.session.signout.SignOutService @@ -26,6 +27,9 @@ import im.vector.matrix.android.api.session.sync.FilterService import im.vector.matrix.android.api.session.user.UserService import im.vector.matrix.android.internal.database.LiveEntityObserver import im.vector.matrix.android.internal.database.model.SessionRealmModule +import im.vector.matrix.android.internal.session.cache.ClearCacheTask +import im.vector.matrix.android.internal.session.cache.RealmCacheService +import im.vector.matrix.android.internal.session.cache.RealmClearCacheTask import im.vector.matrix.android.internal.session.filter.* import im.vector.matrix.android.internal.session.group.DefaultGroupService import im.vector.matrix.android.internal.session.group.GroupSummaryUpdater @@ -110,6 +114,14 @@ internal class SessionModule(private val sessionParams: SessionParams) { DefaultSignOutService(get(), get()) as SignOutService } + scope(DefaultSession.SCOPE) { + RealmCacheService(get(), get()) as CacheService + } + + scope(DefaultSession.SCOPE) { + RealmClearCacheTask(get()) as ClearCacheTask + } + scope(DefaultSession.SCOPE) { DefaultUserService(get()) as UserService } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/cache/RealmCacheService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/cache/RealmCacheService.kt new file mode 100644 index 00000000..7af01b7e --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/cache/RealmCacheService.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2019 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.matrix.android.internal.session.cache + +import im.vector.matrix.android.api.MatrixCallback +import im.vector.matrix.android.api.session.cache.CacheService +import im.vector.matrix.android.internal.task.TaskExecutor +import im.vector.matrix.android.internal.task.configureWith + +internal class RealmCacheService(private val clearCacheTask: ClearCacheTask, + private val taskExecutor: TaskExecutor) : CacheService { + + override fun clearCache(callback: MatrixCallback) { + clearCacheTask + .configureWith(Unit) + .dispatchTo(callback) + .executeBy(taskExecutor) + } +} \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/cache/RealmClearCacheTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/cache/RealmClearCacheTask.kt new file mode 100644 index 00000000..4fdddf81 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/cache/RealmClearCacheTask.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2019 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.matrix.android.internal.session.cache + +import arrow.core.Try +import im.vector.matrix.android.internal.task.Task +import io.realm.Realm +import io.realm.RealmConfiguration + +internal interface ClearCacheTask : Task + +internal class RealmClearCacheTask(val realmConfiguration: RealmConfiguration) : ClearCacheTask { + + override fun execute(params: Unit): Try { + return Try { + val realm = Realm.getInstance(realmConfiguration) + + realm.executeTransaction { + it.deleteAll() + } + + realm.close() + } + } +} \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoom.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoom.kt index d67072d1..6c2ab00f 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoom.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoom.kt @@ -52,7 +52,14 @@ internal class DefaultRoom( RoomSummaryEntity.where(realm, roomId).isNotEmpty(RoomSummaryEntityFields.DISPLAY_NAME) } Transformations.map(liveRealmData) { results -> - results.map { it.asDomain() }.first() + val roomSummaries = results.map { it.asDomain() } + + if (roomSummaries.isEmpty()) { + // Create a dummy RoomSummary to avoid Crash during Sign Out or clear cache + RoomSummary(roomId) + } else { + roomSummaries.first() + } } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/signout/SignOutTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/signout/SignOutTask.kt index 6ca971e3..84cb1f2d 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/signout/SignOutTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/signout/SignOutTask.kt @@ -31,7 +31,6 @@ internal class DefaultSignOutTask(private val signOutAPI: SignOutAPI, return executeRequest { apiCall = signOutAPI.signOut() }.flatMap { - // TODO Clear DB, media cache, etc. sessionParamsStore.delete() } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncModule.kt index 83272c1b..d0f60405 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncModule.kt @@ -56,7 +56,7 @@ internal class SyncModule { } scope(DefaultSession.SCOPE) { - DefaultSyncTask(get(), get(), get()) as SyncTask + DefaultSyncTask(get(), get(), get(), get()) as SyncTask } scope(DefaultSession.SCOPE) { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncTask.kt index 6c5a35cc..9e6d65a5 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncTask.kt @@ -17,6 +17,11 @@ package im.vector.matrix.android.internal.session.sync import arrow.core.Try +import arrow.core.failure +import arrow.core.recoverWith +import im.vector.matrix.android.api.failure.Failure +import im.vector.matrix.android.api.failure.MatrixError +import im.vector.matrix.android.internal.auth.SessionParamsStore import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.session.filter.FilterRepository import im.vector.matrix.android.internal.session.sync.model.SyncResponse @@ -30,7 +35,8 @@ internal interface SyncTask : Task { internal class DefaultSyncTask(private val syncAPI: SyncAPI, private val filterRepository: FilterRepository, - private val syncResponseHandler: SyncResponseHandler + private val syncResponseHandler: SyncResponseHandler, + private val sessionParamsStore: SessionParamsStore ) : SyncTask { @@ -46,6 +52,15 @@ internal class DefaultSyncTask(private val syncAPI: SyncAPI, return executeRequest { apiCall = syncAPI.sync(requestParams) + }.recoverWith { throwable -> + // Intercept 401 + if (throwable is Failure.ServerError + && throwable.error.code == MatrixError.UNKNOWN_TOKEN) { + sessionParamsStore.delete() + } + + // Transmit the throwable + throwable.failure() }.flatMap { syncResponse -> syncResponseHandler.handleResponse(syncResponse, params.token, false) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/job/SyncThread.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/job/SyncThread.kt index d70b1b21..929b67d6 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/job/SyncThread.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/job/SyncThread.kt @@ -19,6 +19,7 @@ package im.vector.matrix.android.internal.session.sync.job import com.squareup.moshi.JsonEncodingException import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.failure.Failure +import im.vector.matrix.android.api.failure.MatrixError import im.vector.matrix.android.api.util.Cancelable import im.vector.matrix.android.internal.network.NetworkConnectivityChecker import im.vector.matrix.android.internal.session.sync.SyncTask @@ -59,7 +60,11 @@ internal class SyncThread(private val syncTask: SyncTask, if (state != State.PAUSED) { return@synchronized } - Timber.v("Unpause sync...") + Timber.v("Resume sync...") + + // Retrieve the last token, it may have been deleted in case of a clear cache + nextBatch = syncTokenStore.getLastToken() + state = State.RUNNING lock.notify() } @@ -97,7 +102,7 @@ internal class SyncThread(private val syncTask: SyncTask, lock.wait() } } else { - Timber.v("Execute sync request...") + Timber.v("Execute sync request with token $nextBatch") val latch = CountDownLatch(1) val params = SyncTask.Params(nextBatch) cancelableTask = syncTask.configureWith(params) @@ -124,6 +129,13 @@ internal class SyncThread(private val syncTask: SyncTask, // Wait 10s before retrying sleep(RETRY_WAIT_TIME_MS) } + + if (failure is Failure.ServerError + && (failure.error.code == MatrixError.UNKNOWN_TOKEN || failure.error.code == MatrixError.MISSING_TOKEN)) { + // No token or invalid token, stop the thread + state = State.KILLING + } + latch.countDown() } diff --git a/vector/src/main/java/im/vector/riotredesign/features/MainActivity.kt b/vector/src/main/java/im/vector/riotredesign/features/MainActivity.kt index 44614b7c..c26a940b 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/MainActivity.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/MainActivity.kt @@ -16,8 +16,11 @@ package im.vector.riotredesign.features +import android.app.Activity +import android.content.Intent import android.os.Bundle import im.vector.matrix.android.api.Matrix +import im.vector.matrix.android.api.MatrixCallback import im.vector.riotredesign.core.platform.VectorBaseActivity import im.vector.riotredesign.features.home.HomeActivity import im.vector.riotredesign.features.login.LoginActivity @@ -25,10 +28,52 @@ import im.vector.riotredesign.features.login.LoginActivity class MainActivity : VectorBaseActivity() { + companion object { + private const val EXTRA_CLEAR_CACHE = "EXTRA_CLEAR_CACHE" + private const val EXTRA_CLEAR_CREDENTIALS = "EXTRA_CLEAR_CREDENTIALS" + + // Special action to clear cache and/or clear credentials + fun restartApp(activity: Activity, clearCache: Boolean = false, clearCredentials: Boolean = false) { + val intent = Intent(activity, MainActivity::class.java) + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK) + + intent.putExtra(EXTRA_CLEAR_CACHE, clearCache) + intent.putExtra(EXTRA_CLEAR_CREDENTIALS, clearCredentials) + activity.startActivity(intent) + } + } + private val authenticator = Matrix.getInstance().authenticator() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + + val session = Matrix.getInstance().currentSession + + val clearCache = intent.getBooleanExtra(EXTRA_CLEAR_CACHE, false) + val clearCredentials = intent.getBooleanExtra(EXTRA_CLEAR_CREDENTIALS, false) + + if (session == null) { + start() + } else { + // Handle some wanted cleanup + when { + clearCredentials -> session.signOut(object : MatrixCallback { + override fun onSuccess(data: Unit) { + start() + } + }) + clearCache -> session.clearCache(object : MatrixCallback { + override fun onSuccess(data: Unit) { + start() + } + }) + else -> start() + } + } + } + + private fun start() { val intent = if (authenticator.hasActiveSessions()) { HomeActivity.newIntent(this) } else { @@ -37,5 +82,4 @@ class MainActivity : VectorBaseActivity() { startActivity(intent) finish() } - } \ No newline at end of file diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/HomeActivityViewModel.kt b/vector/src/main/java/im/vector/riotredesign/features/home/HomeActivityViewModel.kt index 610f4119..7d385006 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/HomeActivityViewModel.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/HomeActivityViewModel.kt @@ -38,7 +38,7 @@ class EmptyState : MvRxState class HomeActivityViewModel(state: EmptyState, private val session: Session, roomSelectionRepository: RoomSelectionRepository -) : VectorViewModel(state) { +) : VectorViewModel(state), Session.Listener { companion object : MvRxViewModelFactory { @@ -59,6 +59,8 @@ class HomeActivityViewModel(state: EmptyState, get() = _openRoomLiveData init { + session.addListener(this) + // TODO Move this else where, it's too late when we are here to change the filter session.setFilter(FilterService.FilterPreset.RiotFilter) @@ -100,5 +102,18 @@ class HomeActivityViewModel(state: EmptyState, }) } + override fun onCleared() { + super.onCleared() + + session.removeListener(this) + } + + /* ========================================================================================== + * Session listener + * ========================================================================================== */ + + override fun onInvalidToken() { + + } } \ No newline at end of file diff --git a/vector/src/main/java/im/vector/riotredesign/features/settings/VectorSettingsPreferencesFragment.kt b/vector/src/main/java/im/vector/riotredesign/features/settings/VectorSettingsPreferencesFragment.kt index fc214faf..d124af6b 100755 --- a/vector/src/main/java/im/vector/riotredesign/features/settings/VectorSettingsPreferencesFragment.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/settings/VectorSettingsPreferencesFragment.kt @@ -53,6 +53,7 @@ import im.vector.riotredesign.core.preference.ProgressBarPreference import im.vector.riotredesign.core.preference.UserAvatarPreference import im.vector.riotredesign.core.preference.VectorPreference import im.vector.riotredesign.core.utils.* +import im.vector.riotredesign.features.MainActivity import im.vector.riotredesign.features.themes.ThemeUtils import org.koin.android.ext.android.inject import java.lang.ref.WeakReference @@ -751,9 +752,8 @@ class VectorSettingsPreferencesFragment : VectorPreferenceFragment(), SharedPref */ it.onPreferenceClickListener = Preference.OnPreferenceClickListener { - notImplemented() - // displayLoadingView() - // TODO Matrix.getInstance(appContext).reloadSessions(appContext) + displayLoadingView() + MainActivity.restartApp(activity!!, clearCache = true, clearCredentials = false) false } } diff --git a/vector/src/main/java/im/vector/riotredesign/features/workers/signout/SignOutUiWorker.kt b/vector/src/main/java/im/vector/riotredesign/features/workers/signout/SignOutUiWorker.kt index cf67cbfd..81f80b9f 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/workers/signout/SignOutUiWorker.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/workers/signout/SignOutUiWorker.kt @@ -16,9 +16,7 @@ package im.vector.riotredesign.features.workers.signout -import android.content.Intent import androidx.appcompat.app.AlertDialog -import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.session.Session import im.vector.riotredesign.R import im.vector.riotredesign.core.platform.VectorBaseActivity @@ -30,7 +28,7 @@ class SignOutUiWorker(val activity: VectorBaseActivity) { if (SignOutViewModel.doYouNeedToBeDisplayed(session)) { val signOutDialog = SignOutBottomSheetDialogFragment.newInstance(session.sessionParams.credentials.userId) signOutDialog.onSignOut = Runnable { - doSignOut(session) + doSignOut() } signOutDialog.show(activity.supportFragmentManager, "SO") } else { @@ -39,31 +37,14 @@ class SignOutUiWorker(val activity: VectorBaseActivity) { .setTitle(R.string.action_sign_out) .setMessage(R.string.action_sign_out_confirmation_simple) .setPositiveButton(R.string.action_sign_out) { _, _ -> - doSignOut(session) + doSignOut() } .setNegativeButton(R.string.cancel, null) .show() } } - private fun doSignOut(session: Session) { - // TODO showWaitingView() - - session.signOut(object : MatrixCallback { - - override fun onSuccess(data: Unit) { - // Start MainActivity in a new task - val intent = Intent(activity, MainActivity::class.java) - intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK - - activity.startActivity(intent) - } - - override fun onFailure(failure: Throwable) { - // TODO Notify user, or ignore? - } - - }) - + private fun doSignOut() { + MainActivity.restartApp(activity, clearCache = true, clearCredentials = true) } }