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
This commit is contained in:
Adam Brown 2021-11-17 09:39:46 +00:00 committed by GitHub
parent 2a051a146c
commit 10a460bf0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 24 additions and 22 deletions

1
changelog.d/4480.bugfix Normal file
View File

@ -0,0 +1 @@
Fixes intermittent crash on sign out due to the session being incorrectly recreated whilst being closed

View File

@ -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)
}
}

View File

@ -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<Session.Listener>()
@ -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)
}

View File

@ -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)
}
}