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:
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user