From 210b958f161437798caab1a5becc9e24d06c79f9 Mon Sep 17 00:00:00 2001 From: Alejandro Nijamkin Date: Wed, 8 Feb 2023 07:31:36 -0800 Subject: [PATCH] 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 --- .../user/data/repository/UserRepository.kt | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt b/packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt index e5ab47325229d..ad1e5fe086196 100644 --- a/packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt @@ -47,12 +47,14 @@ import kotlinx.coroutines.asExecutor import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow 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.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onStart +import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext @@ -120,9 +122,25 @@ constructor( featureFlags: FeatureFlags, ) : UserRepository { - private val _userSwitcherSettings = MutableStateFlow(runBlocking { getSettings() }) - override val userSwitcherSettings: Flow = - _userSwitcherSettings.asStateFlow().filterNotNull() + private val _userSwitcherSettings: StateFlow = + 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() } + .stateIn( + scope = applicationScope, + started = SharingStarted.Eagerly, + initialValue = runBlocking { getSettings() }, + ) + override val userSwitcherSettings: Flow = _userSwitcherSettings private val _userInfos = MutableStateFlow?>(null) override val userInfos: Flow> = _userInfos.filterNotNull() @@ -154,7 +172,6 @@ constructor( init { observeSelectedUser() - observeUserSettings() if (featureFlags.isEnabled(FACE_AUTH_REFACTOR)) { observeUserSwitching() } @@ -237,23 +254,6 @@ constructor( .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 { return withContext(backgroundDispatcher) { val isSimpleUserSwitcher =