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 { lifecycleObservers.forEach {
it.onSessionStarted(this) it.onSessionStarted(this)
} }
sessionListeners.dispatch { _, listener -> dispatchTo(sessionListeners) { session, listener ->
listener.onSessionStarted(this) listener.onSessionStarted(session)
} }
} }
} }
@ -217,8 +217,8 @@ internal class DefaultSession @Inject constructor(
// timelineEventDecryptor.destroy() // timelineEventDecryptor.destroy()
uiHandler.post { uiHandler.post {
lifecycleObservers.forEach { it.onSessionStopped(this) } lifecycleObservers.forEach { it.onSessionStopped(this) }
sessionListeners.dispatch { _, listener -> dispatchTo(sessionListeners) { session, listener ->
listener.onSessionStopped(this) listener.onSessionStopped(session)
} }
} }
cryptoService.get().close() cryptoService.get().close()
@ -249,8 +249,8 @@ internal class DefaultSession @Inject constructor(
lifecycleObservers.forEach { lifecycleObservers.forEach {
it.onClearCache(this) it.onClearCache(this)
} }
sessionListeners.dispatch { _, listener -> dispatchTo(sessionListeners) { session, listener ->
listener.onClearCache(this) listener.onClearCache(session)
} }
} }
withContext(NonCancellable) { withContext(NonCancellable) {
@ -260,8 +260,8 @@ internal class DefaultSession @Inject constructor(
} }
override fun onGlobalError(globalError: GlobalError) { override fun onGlobalError(globalError: GlobalError) {
sessionListeners.dispatch { _, listener -> dispatchTo(sessionListeners) { session, listener ->
listener.onGlobalError(this, globalError) 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.extensions.tryOrNull
import org.matrix.android.sdk.api.session.Session 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 timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
@SessionScope @SessionScope
internal class SessionListeners @Inject constructor( internal class SessionListeners @Inject constructor() {
@SessionId private val sessionId: String,
private val sessionManager: SessionManager) {
private val listeners = mutableSetOf<Session.Listener>() 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) { synchronized(listeners) {
val session = getSession() ?: return Unit.also {
Timber.w("You don't have any attached session")
}
listeners.forEach { listeners.forEach {
tryOrNull { block(session, it) } tryOrNull { block(session, it) }
} }
} }
} }
}
private fun getSession(): Session? { internal fun Session?.dispatchTo(sessionListeners: SessionListeners, block: (Session, Session.Listener) -> Unit) {
return sessionManager.getSessionComponent(sessionId)?.session() 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.GroupsSyncResponse
import org.matrix.android.sdk.api.session.sync.model.RoomsSyncResponse 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.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.crypto.DefaultCryptoService
import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.di.SessionDatabase
import org.matrix.android.sdk.internal.di.SessionId import org.matrix.android.sdk.internal.di.SessionId
import org.matrix.android.sdk.internal.di.WorkManagerProvider import org.matrix.android.sdk.internal.di.WorkManagerProvider
import org.matrix.android.sdk.internal.session.SessionListeners 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.group.GetGroupDataWorker
import org.matrix.android.sdk.internal.session.initsync.ProgressReporter import org.matrix.android.sdk.internal.session.initsync.ProgressReporter
import org.matrix.android.sdk.internal.session.initsync.reportSubtask 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( internal class SyncResponseHandler @Inject constructor(
@SessionDatabase private val monarchy: Monarchy, @SessionDatabase private val monarchy: Monarchy,
@SessionId private val sessionId: String, @SessionId private val sessionId: String,
private val sessionManager: SessionManager,
private val sessionListeners: SessionListeners, private val sessionListeners: SessionListeners,
private val workManagerProvider: WorkManagerProvider, private val workManagerProvider: WorkManagerProvider,
private val roomSyncHandler: RoomSyncHandler, private val roomSyncHandler: RoomSyncHandler,
@ -158,8 +161,9 @@ internal class SyncResponseHandler @Inject constructor(
} }
private fun dispatchInvitedRoom(roomsSyncResponse: RoomsSyncResponse) { private fun dispatchInvitedRoom(roomsSyncResponse: RoomsSyncResponse) {
val session = sessionManager.getSessionComponent(sessionId)?.session()
roomsSyncResponse.invite.keys.forEach { roomId -> roomsSyncResponse.invite.keys.forEach { roomId ->
sessionListeners.dispatch { session, listener -> session.dispatchTo(sessionListeners) { session, listener ->
listener.onNewInvitedRoom(session, roomId) listener.onNewInvitedRoom(session, roomId)
} }
} }