Launching the sending of the client info in a dedicated coroutine to avoid ANR on application start

This commit is contained in:
Maxime NATUREL 2022-11-17 17:11:16 +01:00 committed by SpiritCroc
parent 4ed5669696
commit e8d470f249
3 changed files with 17 additions and 6 deletions

View File

@ -112,11 +112,9 @@ class ActiveSessionHolder @Inject constructor(
} }
?: sessionInitializer.tryInitialize(readCurrentSession = { activeSessionReference.get() }) { session -> ?: sessionInitializer.tryInitialize(readCurrentSession = { activeSessionReference.get() }) { session ->
setActiveSession(session) setActiveSession(session)
runBlocking {
configureAndStartSessionUseCase.execute(session, startSyncing = startSync) configureAndStartSessionUseCase.execute(session, startSyncing = startSync)
} }
} }
}
fun isWaitingForSessionInitialization() = activeSessionReference.get() == null && authenticationService.hasAuthenticatedSessions() fun isWaitingForSessionInitialization() = activeSessionReference.get() == null && authenticationService.hasAuthenticatedSessions()

View File

@ -22,7 +22,9 @@ import im.vector.app.core.extensions.startSyncing
import im.vector.app.core.notification.EnableNotificationsSettingUpdater import im.vector.app.core.notification.EnableNotificationsSettingUpdater
import im.vector.app.core.session.clientinfo.UpdateMatrixClientInfoUseCase import im.vector.app.core.session.clientinfo.UpdateMatrixClientInfoUseCase
import im.vector.app.features.call.webrtc.WebRtcCallManager import im.vector.app.features.call.webrtc.WebRtcCallManager
import im.vector.app.features.session.coroutineScope
import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.settings.VectorPreferences
import kotlinx.coroutines.launch
import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.sync.FilterService import org.matrix.android.sdk.api.session.sync.FilterService
import timber.log.Timber import timber.log.Timber
@ -36,7 +38,7 @@ class ConfigureAndStartSessionUseCase @Inject constructor(
private val enableNotificationsSettingUpdater: EnableNotificationsSettingUpdater, private val enableNotificationsSettingUpdater: EnableNotificationsSettingUpdater,
) { ) {
suspend fun execute(session: Session, startSyncing: Boolean = true) { fun execute(session: Session, startSyncing: Boolean = true) {
Timber.i("Configure and start session for ${session.myUserId}. startSyncing: $startSyncing") Timber.i("Configure and start session for ${session.myUserId}. startSyncing: $startSyncing")
session.open() session.open()
session.filterService().setFilter(FilterService.FilterPreset.ElementFilter) session.filterService().setFilter(FilterService.FilterPreset.ElementFilter)
@ -45,9 +47,11 @@ class ConfigureAndStartSessionUseCase @Inject constructor(
} }
session.pushersService().refreshPushers() session.pushersService().refreshPushers()
webRtcCallManager.checkForProtocolsSupportIfNeeded() webRtcCallManager.checkForProtocolsSupportIfNeeded()
session.coroutineScope.launch {
if (vectorPreferences.isClientInfoRecordingEnabled()) { if (vectorPreferences.isClientInfoRecordingEnabled()) {
updateMatrixClientInfoUseCase.execute(session) updateMatrixClientInfoUseCase.execute(session)
} }
}
enableNotificationsSettingUpdater.onSessionsStarted(session) enableNotificationsSettingUpdater.onSessionsStarted(session)
} }
} }

View File

@ -18,6 +18,7 @@ package im.vector.app.core.session
import im.vector.app.core.extensions.startSyncing import im.vector.app.core.extensions.startSyncing
import im.vector.app.core.session.clientinfo.UpdateMatrixClientInfoUseCase import im.vector.app.core.session.clientinfo.UpdateMatrixClientInfoUseCase
import im.vector.app.features.session.coroutineScope
import im.vector.app.test.fakes.FakeContext import im.vector.app.test.fakes.FakeContext
import im.vector.app.test.fakes.FakeEnableNotificationsSettingUpdater import im.vector.app.test.fakes.FakeEnableNotificationsSettingUpdater
import im.vector.app.test.fakes.FakeSession import im.vector.app.test.fakes.FakeSession
@ -32,6 +33,7 @@ import io.mockk.mockkStatic
import io.mockk.runs import io.mockk.runs
import io.mockk.unmockkAll import io.mockk.unmockkAll
import io.mockk.verify import io.mockk.verify
import kotlinx.coroutines.test.advanceUntilIdle
import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before
@ -57,6 +59,7 @@ class ConfigureAndStartSessionUseCaseTest {
@Before @Before
fun setup() { fun setup() {
mockkStatic("im.vector.app.core.extensions.SessionKt") mockkStatic("im.vector.app.core.extensions.SessionKt")
mockkStatic("im.vector.app.features.session.SessionCoroutineScopesKt")
} }
@After @After
@ -68,6 +71,7 @@ class ConfigureAndStartSessionUseCaseTest {
fun `given start sync needed and client info recording enabled when execute then it should be configured properly`() = runTest { fun `given start sync needed and client info recording enabled when execute then it should be configured properly`() = runTest {
// Given // Given
val fakeSession = givenASession() val fakeSession = givenASession()
every { fakeSession.coroutineScope } returns this
fakeWebRtcCallManager.givenCheckForProtocolsSupportIfNeededSucceeds() fakeWebRtcCallManager.givenCheckForProtocolsSupportIfNeededSucceeds()
coJustRun { fakeUpdateMatrixClientInfoUseCase.execute(any()) } coJustRun { fakeUpdateMatrixClientInfoUseCase.execute(any()) }
fakeVectorPreferences.givenIsClientInfoRecordingEnabled(isEnabled = true) fakeVectorPreferences.givenIsClientInfoRecordingEnabled(isEnabled = true)
@ -75,6 +79,7 @@ class ConfigureAndStartSessionUseCaseTest {
// When // When
configureAndStartSessionUseCase.execute(fakeSession, startSyncing = true) configureAndStartSessionUseCase.execute(fakeSession, startSyncing = true)
advanceUntilIdle()
// Then // Then
verify { fakeSession.startSyncing(fakeContext.instance) } verify { fakeSession.startSyncing(fakeContext.instance) }
@ -88,6 +93,7 @@ class ConfigureAndStartSessionUseCaseTest {
fun `given start sync needed and client info recording disabled when execute then it should be configured properly`() = runTest { fun `given start sync needed and client info recording disabled when execute then it should be configured properly`() = runTest {
// Given // Given
val fakeSession = givenASession() val fakeSession = givenASession()
every { fakeSession.coroutineScope } returns this
fakeWebRtcCallManager.givenCheckForProtocolsSupportIfNeededSucceeds() fakeWebRtcCallManager.givenCheckForProtocolsSupportIfNeededSucceeds()
coJustRun { fakeUpdateMatrixClientInfoUseCase.execute(any()) } coJustRun { fakeUpdateMatrixClientInfoUseCase.execute(any()) }
fakeVectorPreferences.givenIsClientInfoRecordingEnabled(isEnabled = false) fakeVectorPreferences.givenIsClientInfoRecordingEnabled(isEnabled = false)
@ -95,6 +101,7 @@ class ConfigureAndStartSessionUseCaseTest {
// When // When
configureAndStartSessionUseCase.execute(fakeSession, startSyncing = true) configureAndStartSessionUseCase.execute(fakeSession, startSyncing = true)
advanceUntilIdle()
// Then // Then
verify { fakeSession.startSyncing(fakeContext.instance) } verify { fakeSession.startSyncing(fakeContext.instance) }
@ -108,6 +115,7 @@ class ConfigureAndStartSessionUseCaseTest {
fun `given a session and no start sync needed when execute then it should be configured properly`() = runTest { fun `given a session and no start sync needed when execute then it should be configured properly`() = runTest {
// Given // Given
val fakeSession = givenASession() val fakeSession = givenASession()
every { fakeSession.coroutineScope } returns this
fakeWebRtcCallManager.givenCheckForProtocolsSupportIfNeededSucceeds() fakeWebRtcCallManager.givenCheckForProtocolsSupportIfNeededSucceeds()
coJustRun { fakeUpdateMatrixClientInfoUseCase.execute(any()) } coJustRun { fakeUpdateMatrixClientInfoUseCase.execute(any()) }
fakeVectorPreferences.givenIsClientInfoRecordingEnabled(isEnabled = true) fakeVectorPreferences.givenIsClientInfoRecordingEnabled(isEnabled = true)
@ -115,6 +123,7 @@ class ConfigureAndStartSessionUseCaseTest {
// When // When
configureAndStartSessionUseCase.execute(fakeSession, startSyncing = false) configureAndStartSessionUseCase.execute(fakeSession, startSyncing = false)
advanceUntilIdle()
// Then // Then
verify(inverse = true) { fakeSession.startSyncing(fakeContext.instance) } verify(inverse = true) { fakeSession.startSyncing(fakeContext.instance) }