Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 210b958f authored by Alejandro Nijamkin's avatar Alejandro Nijamkin
Browse files

More eagerly collect isSimpleUserSwitcher.

This is a blind attempt to fix the attached bug. The hypothesis is that
there's a race condition between when this is queried by the large
screen bouncer user switching drop-down and the coroutine job that
hydrates this flow with values.

The approach in this CL is to sacrifice some startup performance to make
the value available as early as possible as to avoid the race condition.

Bug: 256698234
Test: all existing user-related unit and integration tests pass locally
Test: manually verified on both small and large screen devices that the
popup and full-screen user switcher, respectively, show up
Test: manually verified, on large screen, that the bouncer
user-switching drop-down shows up and works

Change-Id: I431dbace23f8472a296b374739729a9867efe8ea
parent d504771e
Loading
Loading
Loading
Loading
+22 −22
Original line number Original line Diff line number Diff line
@@ -47,12 +47,14 @@ import kotlinx.coroutines.asExecutor
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import kotlinx.coroutines.withContext
@@ -120,9 +122,25 @@ constructor(
    featureFlags: FeatureFlags,
    featureFlags: FeatureFlags,
) : UserRepository {
) : UserRepository {


    private val _userSwitcherSettings = MutableStateFlow(runBlocking { getSettings() })
    private val _userSwitcherSettings: StateFlow<UserSwitcherSettingsModel> =
    override val userSwitcherSettings: Flow<UserSwitcherSettingsModel> =
        globalSettings
        _userSwitcherSettings.asStateFlow().filterNotNull()
            .observerFlow(
                names =
                    arrayOf(
                        SETTING_SIMPLE_USER_SWITCHER,
                        Settings.Global.ADD_USERS_WHEN_LOCKED,
                        Settings.Global.USER_SWITCHER_ENABLED,
                    ),
                userId = UserHandle.USER_SYSTEM,
            )
            .onStart { emit(Unit) } // Forces an initial update.
            .map { getSettings() }
            .stateIn(
                scope = applicationScope,
                started = SharingStarted.Eagerly,
                initialValue = runBlocking { getSettings() },
            )
    override val userSwitcherSettings: Flow<UserSwitcherSettingsModel> = _userSwitcherSettings


    private val _userInfos = MutableStateFlow<List<UserInfo>?>(null)
    private val _userInfos = MutableStateFlow<List<UserInfo>?>(null)
    override val userInfos: Flow<List<UserInfo>> = _userInfos.filterNotNull()
    override val userInfos: Flow<List<UserInfo>> = _userInfos.filterNotNull()
@@ -154,7 +172,6 @@ constructor(


    init {
    init {
        observeSelectedUser()
        observeSelectedUser()
        observeUserSettings()
        if (featureFlags.isEnabled(FACE_AUTH_REFACTOR)) {
        if (featureFlags.isEnabled(FACE_AUTH_REFACTOR)) {
            observeUserSwitching()
            observeUserSwitching()
        }
        }
@@ -237,23 +254,6 @@ constructor(
            .launchIn(applicationScope)
            .launchIn(applicationScope)
    }
    }


    private fun observeUserSettings() {
        globalSettings
            .observerFlow(
                names =
                    arrayOf(
                        SETTING_SIMPLE_USER_SWITCHER,
                        Settings.Global.ADD_USERS_WHEN_LOCKED,
                        Settings.Global.USER_SWITCHER_ENABLED,
                    ),
                userId = UserHandle.USER_SYSTEM,
            )
            .onStart { emit(Unit) } // Forces an initial update.
            .map { getSettings() }
            .onEach { _userSwitcherSettings.value = it }
            .launchIn(applicationScope)
    }

    private suspend fun getSettings(): UserSwitcherSettingsModel {
    private suspend fun getSettings(): UserSwitcherSettingsModel {
        return withContext(backgroundDispatcher) {
        return withContext(backgroundDispatcher) {
            val isSimpleUserSwitcher =
            val isSimpleUserSwitcher =