From 10a460bf0c17f2644f183dfefebe331258693396 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Wed, 17 Nov 2021 09:39:46 +0000 Subject: [PATCH] Sign out crash - Realm configuration mismatch (#4480) Dispatching session events to a specified session instance instead of always querying the session manager - fixes the close session flow causing the session to be recreated --- changelog.d/4480.bugfix | 1 + .../sdk/internal/session/DefaultSession.kt | 16 ++++++------- .../sdk/internal/session/SessionListeners.kt | 23 ++++++++----------- .../session/sync/SyncResponseHandler.kt | 6 ++++- 4 files changed, 24 insertions(+), 22 deletions(-) create mode 100644 changelog.d/4480.bugfix diff --git a/changelog.d/4480.bugfix b/changelog.d/4480.bugfix new file mode 100644 index 0000000000..5769fb4efa --- /dev/null +++ b/changelog.d/4480.bugfix @@ -0,0 +1 @@ +Fixes intermittent crash on sign out due to the session being incorrectly recreated whilst being closed \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt index c52462612a..53e8690aec 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt @@ -174,8 +174,8 @@ internal class DefaultSession @Inject constructor( lifecycleObservers.forEach { it.onSessionStarted(this) } - sessionListeners.dispatch { _, listener -> - listener.onSessionStarted(this) + dispatchTo(sessionListeners) { session, listener -> + listener.onSessionStarted(session) } } } @@ -217,8 +217,8 @@ internal class DefaultSession @Inject constructor( // timelineEventDecryptor.destroy() uiHandler.post { lifecycleObservers.forEach { it.onSessionStopped(this) } - sessionListeners.dispatch { _, listener -> - listener.onSessionStopped(this) + dispatchTo(sessionListeners) { session, listener -> + listener.onSessionStopped(session) } } cryptoService.get().close() @@ -249,8 +249,8 @@ internal class DefaultSession @Inject constructor( lifecycleObservers.forEach { it.onClearCache(this) } - sessionListeners.dispatch { _, listener -> - listener.onClearCache(this) + dispatchTo(sessionListeners) { session, listener -> + listener.onClearCache(session) } } withContext(NonCancellable) { @@ -260,8 +260,8 @@ internal class DefaultSession @Inject constructor( } override fun onGlobalError(globalError: GlobalError) { - sessionListeners.dispatch { _, listener -> - listener.onGlobalError(this, globalError) + dispatchTo(sessionListeners) { session, listener -> + listener.onGlobalError(session, globalError) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionListeners.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionListeners.kt index d5c661b1e4..756b9cef83 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionListeners.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionListeners.kt @@ -18,15 +18,11 @@ package org.matrix.android.sdk.internal.session import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.internal.SessionManager -import org.matrix.android.sdk.internal.di.SessionId import timber.log.Timber import javax.inject.Inject @SessionScope -internal class SessionListeners @Inject constructor( - @SessionId private val sessionId: String, - private val sessionManager: SessionManager) { +internal class SessionListeners @Inject constructor() { private val listeners = mutableSetOf() @@ -42,18 +38,19 @@ internal class SessionListeners @Inject constructor( } } - fun dispatch(block: (Session, Session.Listener) -> Unit) { + fun dispatch(session: Session, block: (Session, Session.Listener) -> Unit) { synchronized(listeners) { - val session = getSession() ?: return Unit.also { - Timber.w("You don't have any attached session") - } listeners.forEach { tryOrNull { block(session, it) } } } } - - private fun getSession(): Session? { - return sessionManager.getSessionComponent(sessionId)?.session() - } +} + +internal fun Session?.dispatchTo(sessionListeners: SessionListeners, block: (Session, Session.Listener) -> Unit) { + if (this == null) { + Timber.w("You don't have any attached session") + return + } + sessionListeners.dispatch(this, block) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt index 335f619623..8fd969e373 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt @@ -24,11 +24,13 @@ import org.matrix.android.sdk.api.session.initsync.InitSyncStep import org.matrix.android.sdk.api.session.sync.model.GroupsSyncResponse import org.matrix.android.sdk.api.session.sync.model.RoomsSyncResponse import org.matrix.android.sdk.api.session.sync.model.SyncResponse +import org.matrix.android.sdk.internal.SessionManager import org.matrix.android.sdk.internal.crypto.DefaultCryptoService import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.di.SessionId import org.matrix.android.sdk.internal.di.WorkManagerProvider import org.matrix.android.sdk.internal.session.SessionListeners +import org.matrix.android.sdk.internal.session.dispatchTo import org.matrix.android.sdk.internal.session.group.GetGroupDataWorker import org.matrix.android.sdk.internal.session.initsync.ProgressReporter import org.matrix.android.sdk.internal.session.initsync.reportSubtask @@ -51,6 +53,7 @@ private const val GET_GROUP_DATA_WORKER = "GET_GROUP_DATA_WORKER" internal class SyncResponseHandler @Inject constructor( @SessionDatabase private val monarchy: Monarchy, @SessionId private val sessionId: String, + private val sessionManager: SessionManager, private val sessionListeners: SessionListeners, private val workManagerProvider: WorkManagerProvider, private val roomSyncHandler: RoomSyncHandler, @@ -158,8 +161,9 @@ internal class SyncResponseHandler @Inject constructor( } private fun dispatchInvitedRoom(roomsSyncResponse: RoomsSyncResponse) { + val session = sessionManager.getSessionComponent(sessionId)?.session() roomsSyncResponse.invite.keys.forEach { roomId -> - sessionListeners.dispatch { session, listener -> + session.dispatchTo(sessionListeners) { session, listener -> listener.onNewInvitedRoom(session, roomId) } }