Merge "[User Switcher] Fix IllegalStateException in..." into tm-qpr-dev am: d78c69f781

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20505235

Change-Id: Ic479250330b591408071f7de0d2b7bbca93f0e26
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Aaron Liu
2022-11-19 03:52:37 +00:00
committed by Automerger Merge Worker
2 changed files with 64 additions and 44 deletions

View File

@@ -66,7 +66,6 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
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
@@ -138,18 +137,12 @@ constructor(
/** The currently-selected user. */ /** The currently-selected user. */
val selectedUser: Flow<UserModel> val selectedUser: Flow<UserModel>
get() = get() =
combine( repository.selectedUserInfo.map { selectedUserInfo ->
repository.selectedUserInfo,
repository.userSwitcherSettings,
) { selectedUserInfo, settings ->
val selectedUserId = selectedUserInfo.id val selectedUserId = selectedUserInfo.id
checkNotNull( toUserModel(
toUserModel( userInfo = selectedUserInfo,
userInfo = selectedUserInfo, selectedUserId = selectedUserId,
selectedUserId = selectedUserId, canSwitchUsers = canSwitchUsers(selectedUserId)
canSwitchUsers = canSwitchUsers(selectedUserId),
isUserSwitcherEnabled = settings.isUserSwitcherEnabled,
)
) )
} }
@@ -629,7 +622,7 @@ constructor(
// The guest user should go in the last position. // The guest user should go in the last position.
.sortedBy { it.isGuest } .sortedBy { it.isGuest }
.mapNotNull { userInfo -> .mapNotNull { userInfo ->
toUserModel( filterAndMapToUserModel(
userInfo = userInfo, userInfo = userInfo,
selectedUserId = selectedUserId, selectedUserId = selectedUserId,
canSwitchUsers = canSwitchUsers, canSwitchUsers = canSwitchUsers,
@@ -638,51 +631,65 @@ constructor(
} }
} }
private suspend fun toUserModel( /**
* Maps UserInfo to UserModel based on some parameters and return null under certain conditions
* to be filtered out.
*/
private suspend fun filterAndMapToUserModel(
userInfo: UserInfo, userInfo: UserInfo,
selectedUserId: Int, selectedUserId: Int,
canSwitchUsers: Boolean, canSwitchUsers: Boolean,
isUserSwitcherEnabled: Boolean, isUserSwitcherEnabled: Boolean,
): UserModel? { ): UserModel? {
val userId = userInfo.id
val isSelected = userId == selectedUserId
return when { return when {
// When the user switcher is not enabled in settings, we only show the primary user. // When the user switcher is not enabled in settings, we only show the primary user.
!isUserSwitcherEnabled && !userInfo.isPrimary -> null !isUserSwitcherEnabled && !userInfo.isPrimary -> null
// We avoid showing disabled users. // We avoid showing disabled users.
!userInfo.isEnabled -> null !userInfo.isEnabled -> null
userInfo.isGuest -> // We meet the conditions to return the UserModel.
UserModel( userInfo.isGuest || userInfo.supportsSwitchToByUser() ->
id = userId, toUserModel(userInfo, selectedUserId, canSwitchUsers)
name = Text.Loaded(userInfo.name),
image =
getUserImage(
isGuest = true,
userId = userId,
),
isSelected = isSelected,
isSelectable = canSwitchUsers,
isGuest = true,
)
userInfo.supportsSwitchToByUser() ->
UserModel(
id = userId,
name = Text.Loaded(userInfo.name),
image =
getUserImage(
isGuest = false,
userId = userId,
),
isSelected = isSelected,
isSelectable = canSwitchUsers || isSelected,
isGuest = false,
)
else -> null else -> null
} }
} }
/** Maps UserInfo to UserModel based on some parameters. */
private suspend fun toUserModel(
userInfo: UserInfo,
selectedUserId: Int,
canSwitchUsers: Boolean
): UserModel {
val userId = userInfo.id
val isSelected = userId == selectedUserId
return if (userInfo.isGuest) {
UserModel(
id = userId,
name = Text.Loaded(userInfo.name),
image =
getUserImage(
isGuest = true,
userId = userId,
),
isSelected = isSelected,
isSelectable = canSwitchUsers,
isGuest = true,
)
} else {
UserModel(
id = userId,
name = Text.Loaded(userInfo.name),
image =
getUserImage(
isGuest = false,
userId = userId,
),
isSelected = isSelected,
isSelectable = canSwitchUsers || isSelected,
isGuest = false,
)
}
}
private suspend fun canSwitchUsers(selectedUserId: Int): Boolean { private suspend fun canSwitchUsers(selectedUserId: Int): Boolean {
return withContext(backgroundDispatcher) { return withContext(backgroundDispatcher) {
manager.getUserSwitchability(UserHandle.of(selectedUserId)) manager.getUserSwitchability(UserHandle.of(selectedUserId))

View File

@@ -793,6 +793,19 @@ class UserInteractorTest : SysuiTestCase() {
job.cancel() job.cancel()
} }
@Test
fun `current user is not primary and user switcher is disabled`() =
runBlocking(IMMEDIATE) {
val userInfos = createUserInfos(count = 2, includeGuest = false)
userRepository.setUserInfos(userInfos)
userRepository.setSelectedUserInfo(userInfos[1])
userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = false))
var selectedUser: UserModel? = null
val job = underTest.selectedUser.onEach { selectedUser = it }.launchIn(this)
assertThat(selectedUser).isNotNull()
job.cancel()
}
private fun assertUsers( private fun assertUsers(
models: List<UserModel>?, models: List<UserModel>?,
count: Int, count: Int,