Merge changes Ib3989fc2,I053eec01,Ib0cbb23d into tm-qpr-dev

* changes:
  Sorts users in switchers by creation time.
  Fix bug where switching users didn't dismiss UI.
  Fix bug where switching to guest didn't work.
This commit is contained in:
Ale Nijamkin
2022-10-11 17:21:33 +00:00
committed by Android (Google) Code Review
6 changed files with 124 additions and 16 deletions

View File

@@ -30,7 +30,6 @@ import com.android.systemui.qs.user.UserSwitchDialogController
import com.android.systemui.user.data.source.UserRecord import com.android.systemui.user.data.source.UserRecord
import com.android.systemui.user.domain.interactor.GuestUserInteractor import com.android.systemui.user.domain.interactor.GuestUserInteractor
import com.android.systemui.user.domain.interactor.UserInteractor import com.android.systemui.user.domain.interactor.UserInteractor
import com.android.systemui.user.legacyhelper.data.LegacyUserDataHelper
import com.android.systemui.user.legacyhelper.ui.LegacyUserUiHelper import com.android.systemui.user.legacyhelper.ui.LegacyUserUiHelper
import dagger.Lazy import dagger.Lazy
import java.io.PrintWriter import java.io.PrintWriter
@@ -118,7 +117,7 @@ constructor(
dialogShower: UserSwitchDialogController.DialogShower? dialogShower: UserSwitchDialogController.DialogShower?
) { ) {
if (useInteractor) { if (useInteractor) {
userInteractor.selectUser(userId) userInteractor.selectUser(userId, dialogShower)
} else { } else {
_oldImpl.onUserSelected(userId, dialogShower) _oldImpl.onUserSelected(userId, dialogShower)
} }
@@ -203,11 +202,7 @@ constructor(
dialogShower: UserSwitchDialogController.DialogShower?, dialogShower: UserSwitchDialogController.DialogShower?,
) { ) {
if (useInteractor) { if (useInteractor) {
if (LegacyUserDataHelper.isUser(record)) { userInteractor.onRecordSelected(record, dialogShower)
userInteractor.selectUser(record.resolveId())
} else {
userInteractor.executeAction(LegacyUserDataHelper.toUserActionModel(record))
}
} else { } else {
_oldImpl.onUserListItemClicked(record, dialogShower) _oldImpl.onUserListItemClicked(record, dialogShower)
} }

View File

@@ -220,7 +220,7 @@ constructor(
val result = withContext(backgroundDispatcher) { manager.aliveUsers } val result = withContext(backgroundDispatcher) { manager.aliveUsers }
if (result != null) { if (result != null) {
_userInfos.value = result _userInfos.value = result.sortedBy { it.creationTime }
} }
} }
} }

View File

@@ -43,6 +43,7 @@ import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.qs.user.UserSwitchDialogController
import com.android.systemui.statusbar.policy.UserSwitcherController import com.android.systemui.statusbar.policy.UserSwitcherController
import com.android.systemui.telephony.domain.interactor.TelephonyInteractor import com.android.systemui.telephony.domain.interactor.TelephonyInteractor
import com.android.systemui.user.data.repository.UserRepository import com.android.systemui.user.data.repository.UserRepository
@@ -390,9 +391,24 @@ constructor(
guestUserInteractor.onDeviceBootCompleted() guestUserInteractor.onDeviceBootCompleted()
} }
/** Switches to the user or executes the action represented by the given record. */
fun onRecordSelected(
record: UserRecord,
dialogShower: UserSwitchDialogController.DialogShower? = null,
) {
if (LegacyUserDataHelper.isUser(record)) {
// It's safe to use checkNotNull around record.info because isUser only returns true
// if record.info is not null.
selectUser(checkNotNull(record.info).id, dialogShower)
} else {
executeAction(LegacyUserDataHelper.toUserActionModel(record), dialogShower)
}
}
/** Switches to the user with the given user ID. */ /** Switches to the user with the given user ID. */
fun selectUser( fun selectUser(
newlySelectedUserId: Int, newlySelectedUserId: Int,
dialogShower: UserSwitchDialogController.DialogShower? = null,
) { ) {
if (isNewImpl) { if (isNewImpl) {
val currentlySelectedUserInfo = repository.getSelectedUserInfo() val currentlySelectedUserInfo = repository.getSelectedUserInfo()
@@ -428,22 +444,28 @@ constructor(
return return
} }
dialogShower?.dismiss()
switchUser(newlySelectedUserId) switchUser(newlySelectedUserId)
} else { } else {
controller.onUserSelected(newlySelectedUserId, /* dialogShower= */ null) controller.onUserSelected(newlySelectedUserId, dialogShower)
} }
} }
/** Executes the given action. */ /** Executes the given action. */
fun executeAction(action: UserActionModel) { fun executeAction(
action: UserActionModel,
dialogShower: UserSwitchDialogController.DialogShower? = null,
) {
if (isNewImpl) { if (isNewImpl) {
when (action) { when (action) {
UserActionModel.ENTER_GUEST_MODE -> UserActionModel.ENTER_GUEST_MODE ->
guestUserInteractor.createAndSwitchTo( guestUserInteractor.createAndSwitchTo(
this::showDialog, this::showDialog,
this::dismissDialog, this::dismissDialog,
this::selectUser, ) { userId ->
) selectUser(userId, dialogShower)
}
UserActionModel.ADD_USER -> { UserActionModel.ADD_USER -> {
val currentUser = repository.getSelectedUserInfo() val currentUser = repository.getSelectedUserInfo()
showDialog( showDialog(
@@ -575,7 +597,7 @@ constructor(
} }
private fun switchUser(userId: Int) { private fun switchUser(userId: Int) {
// TODO(b/246631653): track jank and lantecy like in the old impl. // TODO(b/246631653): track jank and latency like in the old impl.
refreshUsersScheduler.pause() refreshUsersScheduler.pause()
try { try {
activityManager.switchUser(userId) activityManager.switchUser(userId)

View File

@@ -120,6 +120,27 @@ class UserRepositoryImplRefactoredTest : UserRepositoryImplTest() {
assertThat(underTest.lastSelectedNonGuestUserId).isEqualTo(selectedNonGuestUserId) assertThat(underTest.lastSelectedNonGuestUserId).isEqualTo(selectedNonGuestUserId)
} }
@Test
fun `refreshUsers - sorts by creation time`() = runSelfCancelingTest {
underTest = create(this)
val unsortedUsers =
setUpUsers(
count = 3,
selectedIndex = 0,
)
unsortedUsers[0].creationTime = 900
unsortedUsers[1].creationTime = 700
unsortedUsers[2].creationTime = 999
val expectedUsers = listOf(unsortedUsers[1], unsortedUsers[0], unsortedUsers[2])
var userInfos: List<UserInfo>? = null
var selectedUserInfo: UserInfo? = null
underTest.userInfos.onEach { userInfos = it }.launchIn(this)
underTest.selectedUserInfo.onEach { selectedUserInfo = it }.launchIn(this)
underTest.refreshUsers()
assertThat(userInfos).isEqualTo(expectedUsers)
}
private fun setUpUsers( private fun setUpUsers(
count: Int, count: Int,
hasGuest: Boolean = false, hasGuest: Boolean = false,

View File

@@ -47,7 +47,9 @@ import org.junit.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.junit.runners.JUnit4 import org.junit.runners.JUnit4
import org.mockito.ArgumentMatchers.anyBoolean
import org.mockito.ArgumentMatchers.anyInt import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mockito.never
import org.mockito.Mockito.verify import org.mockito.Mockito.verify
@SmallTest @SmallTest
@@ -72,6 +74,66 @@ class UserInteractorRefactoredTest : UserInteractorTest() {
whenever(manager.canAddMoreUsers(any())).thenReturn(true) whenever(manager.canAddMoreUsers(any())).thenReturn(true)
} }
@Test
fun `onRecordSelected - user`() =
runBlocking(IMMEDIATE) {
val userInfos = createUserInfos(count = 3, includeGuest = false)
userRepository.setUserInfos(userInfos)
userRepository.setSelectedUserInfo(userInfos[0])
userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
underTest.onRecordSelected(UserRecord(info = userInfos[1]), dialogShower)
verify(dialogShower).dismiss()
verify(activityManager).switchUser(userInfos[1].id)
Unit
}
@Test
fun `onRecordSelected - switch to guest user`() =
runBlocking(IMMEDIATE) {
val userInfos = createUserInfos(count = 3, includeGuest = true)
userRepository.setUserInfos(userInfos)
userRepository.setSelectedUserInfo(userInfos[0])
userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
underTest.onRecordSelected(UserRecord(info = userInfos.last()))
verify(activityManager).switchUser(userInfos.last().id)
Unit
}
@Test
fun `onRecordSelected - enter guest mode`() =
runBlocking(IMMEDIATE) {
val userInfos = createUserInfos(count = 3, includeGuest = false)
userRepository.setUserInfos(userInfos)
userRepository.setSelectedUserInfo(userInfos[0])
userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
val guestUserInfo = createUserInfo(id = 1337, name = "guest", isGuest = true)
whenever(manager.createGuest(any())).thenReturn(guestUserInfo)
underTest.onRecordSelected(UserRecord(isGuest = true), dialogShower)
verify(dialogShower).dismiss()
verify(manager).createGuest(any())
Unit
}
@Test
fun `onRecordSelected - action`() =
runBlocking(IMMEDIATE) {
val userInfos = createUserInfos(count = 3, includeGuest = true)
userRepository.setUserInfos(userInfos)
userRepository.setSelectedUserInfo(userInfos[0])
userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
underTest.onRecordSelected(UserRecord(isAddSupervisedUser = true), dialogShower)
verify(dialogShower, never()).dismiss()
verify(activityStarter).startActivity(any(), anyBoolean())
}
@Test @Test
fun `users - switcher enabled`() = fun `users - switcher enabled`() =
runBlocking(IMMEDIATE) { runBlocking(IMMEDIATE) {
@@ -336,10 +398,14 @@ class UserInteractorRefactoredTest : UserInteractorTest() {
var dialogRequest: ShowDialogRequestModel? = null var dialogRequest: ShowDialogRequestModel? = null
val job = underTest.dialogShowRequests.onEach { dialogRequest = it }.launchIn(this) val job = underTest.dialogShowRequests.onEach { dialogRequest = it }.launchIn(this)
underTest.selectUser(newlySelectedUserId = guestUserInfo.id) underTest.selectUser(
newlySelectedUserId = guestUserInfo.id,
dialogShower = dialogShower,
)
assertThat(dialogRequest) assertThat(dialogRequest)
.isInstanceOf(ShowDialogRequestModel.ShowExitGuestDialog::class.java) .isInstanceOf(ShowDialogRequestModel.ShowExitGuestDialog::class.java)
verify(dialogShower, never()).dismiss()
job.cancel() job.cancel()
} }
@@ -355,10 +421,11 @@ class UserInteractorRefactoredTest : UserInteractorTest() {
var dialogRequest: ShowDialogRequestModel? = null var dialogRequest: ShowDialogRequestModel? = null
val job = underTest.dialogShowRequests.onEach { dialogRequest = it }.launchIn(this) val job = underTest.dialogShowRequests.onEach { dialogRequest = it }.launchIn(this)
underTest.selectUser(newlySelectedUserId = userInfos[0].id) underTest.selectUser(newlySelectedUserId = userInfos[0].id, dialogShower = dialogShower)
assertThat(dialogRequest) assertThat(dialogRequest)
.isInstanceOf(ShowDialogRequestModel.ShowExitGuestDialog::class.java) .isInstanceOf(ShowDialogRequestModel.ShowExitGuestDialog::class.java)
verify(dialogShower, never()).dismiss()
job.cancel() job.cancel()
} }
@@ -372,10 +439,11 @@ class UserInteractorRefactoredTest : UserInteractorTest() {
var dialogRequest: ShowDialogRequestModel? = null var dialogRequest: ShowDialogRequestModel? = null
val job = underTest.dialogShowRequests.onEach { dialogRequest = it }.launchIn(this) val job = underTest.dialogShowRequests.onEach { dialogRequest = it }.launchIn(this)
underTest.selectUser(newlySelectedUserId = userInfos[1].id) underTest.selectUser(newlySelectedUserId = userInfos[1].id, dialogShower = dialogShower)
assertThat(dialogRequest).isNull() assertThat(dialogRequest).isNull()
verify(activityManager).switchUser(userInfos[1].id) verify(activityManager).switchUser(userInfos[1].id)
verify(dialogShower).dismiss()
job.cancel() job.cancel()
} }

View File

@@ -27,6 +27,7 @@ import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.qs.user.UserSwitchDialogController
import com.android.systemui.statusbar.policy.DeviceProvisionedController import com.android.systemui.statusbar.policy.DeviceProvisionedController
import com.android.systemui.statusbar.policy.UserSwitcherController import com.android.systemui.statusbar.policy.UserSwitcherController
import com.android.systemui.telephony.data.repository.FakeTelephonyRepository import com.android.systemui.telephony.data.repository.FakeTelephonyRepository
@@ -46,6 +47,7 @@ abstract class UserInteractorTest : SysuiTestCase() {
@Mock protected lateinit var deviceProvisionedController: DeviceProvisionedController @Mock protected lateinit var deviceProvisionedController: DeviceProvisionedController
@Mock protected lateinit var devicePolicyManager: DevicePolicyManager @Mock protected lateinit var devicePolicyManager: DevicePolicyManager
@Mock protected lateinit var uiEventLogger: UiEventLogger @Mock protected lateinit var uiEventLogger: UiEventLogger
@Mock protected lateinit var dialogShower: UserSwitchDialogController.DialogShower
protected lateinit var underTest: UserInteractor protected lateinit var underTest: UserInteractor