Fixes user switcher dialog animations.
The user switcher dialog uses a chain of dialogs linked through common CUJs to morph-animate dialogs into one another as the user goes through flows that require showing a second dialog after the first. ag/20259287 was an overzealous fix for b/254704051; a bug where the user switcher dialog was still visible above the "add supervised user" activity. The fix addressed the problem but introduced a regression because it was dismissing the user switcher dialog each time any item in the dialog was clicked. This CL basically reverts ag/20259287 and re-does the fix more surgically in a lower layer. UserInteractor will ask to dismiss the dialog if it wants to start the activity for the specific action of adding a supervised user. Fix: 262743114 Test: modified UserInteractorTest (and also modernized it all) Test: manually verified that the dialogs morph-animate Test: manually verified that starting the "add supervised user" activity causes the user switcher dialog to be dismissed Test: all tested on handheld device (phone) Change-Id: Ia33c8644ca891879f36c62c0257ebdc897623c40
This commit is contained in:
committed by
Ale Nijamkin
parent
b425997d1f
commit
637af6858e
@@ -204,15 +204,6 @@ public class UserDetailView extends PseudoGridView {
|
||||
Trace.endSection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserListItemClicked(@NonNull UserRecord record,
|
||||
@Nullable UserSwitchDialogController.DialogShower dialogShower) {
|
||||
if (dialogShower != null) {
|
||||
mDialogShower.dismiss();
|
||||
}
|
||||
super.onUserListItemClicked(record, dialogShower);
|
||||
}
|
||||
|
||||
public void linkToViewGroup(ViewGroup viewGroup) {
|
||||
PseudoGridView.ViewGroupAdapterBridge.link(viewGroup, this);
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ protected constructor(
|
||||
* animation to and from the parent dialog.
|
||||
*/
|
||||
@JvmOverloads
|
||||
open fun onUserListItemClicked(
|
||||
fun onUserListItemClicked(
|
||||
record: UserRecord,
|
||||
dialogShower: DialogShower? = null,
|
||||
) {
|
||||
|
||||
@@ -455,6 +455,7 @@ constructor(
|
||||
}
|
||||
UserActionModel.ADD_SUPERVISED_USER -> {
|
||||
uiEventLogger.log(MultiUserActionsEvent.CREATE_RESTRICTED_USER_FROM_USER_SWITCHER)
|
||||
dismissDialog()
|
||||
activityStarter.startActivity(
|
||||
Intent()
|
||||
.setAction(UserManager.ACTION_CREATE_SUPERVISED_USER)
|
||||
|
||||
@@ -66,12 +66,6 @@ constructor(
|
||||
private fun startHandlingDialogShowRequests() {
|
||||
applicationScope.get().launch {
|
||||
interactor.get().dialogShowRequests.filterNotNull().collect { request ->
|
||||
currentDialog?.let {
|
||||
if (it.isShowing) {
|
||||
it.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
val (dialog, dialogCuj) =
|
||||
when (request) {
|
||||
is ShowDialogRequestModel.ShowAddUserDialog ->
|
||||
|
||||
@@ -30,7 +30,6 @@ import com.android.systemui.R
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.classifier.FalsingManagerFake
|
||||
import com.android.systemui.qs.QSUserSwitcherEvent
|
||||
import com.android.systemui.qs.user.UserSwitchDialogController
|
||||
import com.android.systemui.statusbar.policy.UserSwitcherController
|
||||
import com.android.systemui.user.data.source.UserRecord
|
||||
import org.junit.Assert.assertEquals
|
||||
@@ -42,7 +41,6 @@ import org.mockito.ArgumentMatchers.any
|
||||
import org.mockito.ArgumentMatchers.anyBoolean
|
||||
import org.mockito.ArgumentMatchers.anyInt
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.mock
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.Mockito.`when`
|
||||
import org.mockito.MockitoAnnotations
|
||||
@@ -152,15 +150,6 @@ class UserDetailViewAdapterTest : SysuiTestCase() {
|
||||
assertNull(adapter.users.find { it.isManageUsers })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun clickDismissDialog() {
|
||||
val shower: UserSwitchDialogController.DialogShower =
|
||||
mock(UserSwitchDialogController.DialogShower::class.java)
|
||||
adapter.injectDialogShower(shower)
|
||||
adapter.onUserListItemClicked(createUserRecord(current = true, guest = false), shower)
|
||||
verify(shower).dismiss()
|
||||
}
|
||||
|
||||
private fun createUserRecord(current: Boolean, guest: Boolean) =
|
||||
UserRecord(
|
||||
UserInfo(0 /* id */, "name", 0 /* flags */),
|
||||
|
||||
@@ -36,6 +36,7 @@ import com.android.systemui.R
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.animation.Expandable
|
||||
import com.android.systemui.common.shared.model.Text
|
||||
import com.android.systemui.coroutines.collectLastValue
|
||||
import com.android.systemui.flags.FakeFeatureFlags
|
||||
import com.android.systemui.flags.Flags
|
||||
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
|
||||
@@ -61,12 +62,12 @@ import com.android.systemui.util.mockito.mock
|
||||
import com.android.systemui.util.mockito.nullable
|
||||
import com.android.systemui.util.mockito.whenever
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.test.TestCoroutineScope
|
||||
import kotlinx.coroutines.test.advanceUntilIdle
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.test.StandardTestDispatcher
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.runCurrent
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
@@ -74,11 +75,13 @@ import org.junit.runners.JUnit4
|
||||
import org.mockito.ArgumentMatchers.anyBoolean
|
||||
import org.mockito.ArgumentMatchers.anyInt
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.atLeastOnce
|
||||
import org.mockito.Mockito.never
|
||||
import org.mockito.Mockito.times
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.MockitoAnnotations
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@SmallTest
|
||||
@RunWith(JUnit4::class)
|
||||
class UserInteractorTest : SysuiTestCase() {
|
||||
@@ -95,7 +98,7 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
|
||||
private lateinit var underTest: UserInteractor
|
||||
|
||||
private lateinit var testCoroutineScope: TestCoroutineScope
|
||||
private lateinit var testScope: TestScope
|
||||
private lateinit var userRepository: FakeUserRepository
|
||||
private lateinit var keyguardRepository: FakeKeyguardRepository
|
||||
private lateinit var telephonyRepository: FakeTelephonyRepository
|
||||
@@ -119,11 +122,12 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
userRepository = FakeUserRepository()
|
||||
keyguardRepository = FakeKeyguardRepository()
|
||||
telephonyRepository = FakeTelephonyRepository()
|
||||
testCoroutineScope = TestCoroutineScope()
|
||||
val testDispatcher = StandardTestDispatcher()
|
||||
testScope = TestScope(testDispatcher)
|
||||
val refreshUsersScheduler =
|
||||
RefreshUsersScheduler(
|
||||
applicationScope = testCoroutineScope,
|
||||
mainDispatcher = IMMEDIATE,
|
||||
applicationScope = testScope.backgroundScope,
|
||||
mainDispatcher = testDispatcher,
|
||||
repository = userRepository,
|
||||
)
|
||||
underTest =
|
||||
@@ -136,21 +140,21 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
repository = keyguardRepository,
|
||||
),
|
||||
manager = manager,
|
||||
applicationScope = testCoroutineScope,
|
||||
applicationScope = testScope.backgroundScope,
|
||||
telephonyInteractor =
|
||||
TelephonyInteractor(
|
||||
repository = telephonyRepository,
|
||||
),
|
||||
broadcastDispatcher = fakeBroadcastDispatcher,
|
||||
backgroundDispatcher = IMMEDIATE,
|
||||
backgroundDispatcher = testDispatcher,
|
||||
activityManager = activityManager,
|
||||
refreshUsersScheduler = refreshUsersScheduler,
|
||||
guestUserInteractor =
|
||||
GuestUserInteractor(
|
||||
applicationContext = context,
|
||||
applicationScope = testCoroutineScope,
|
||||
mainDispatcher = IMMEDIATE,
|
||||
backgroundDispatcher = IMMEDIATE,
|
||||
applicationScope = testScope.backgroundScope,
|
||||
mainDispatcher = testDispatcher,
|
||||
backgroundDispatcher = testDispatcher,
|
||||
manager = manager,
|
||||
repository = userRepository,
|
||||
deviceProvisionedController = deviceProvisionedController,
|
||||
@@ -167,7 +171,7 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun `onRecordSelected - user`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
val userInfos = createUserInfos(count = 3, includeGuest = false)
|
||||
userRepository.setUserInfos(userInfos)
|
||||
userRepository.setSelectedUserInfo(userInfos[0])
|
||||
@@ -184,7 +188,7 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun `onRecordSelected - switch to guest user`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
val userInfos = createUserInfos(count = 3, includeGuest = true)
|
||||
userRepository.setUserInfos(userInfos)
|
||||
userRepository.setSelectedUserInfo(userInfos[0])
|
||||
@@ -200,7 +204,7 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun `onRecordSelected - switch to restricted user`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
var userInfos = createUserInfos(count = 2, includeGuest = false).toMutableList()
|
||||
userInfos.add(
|
||||
UserInfo(
|
||||
@@ -225,7 +229,7 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun `onRecordSelected - enter guest mode`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
val userInfos = createUserInfos(count = 3, includeGuest = false)
|
||||
userRepository.setUserInfos(userInfos)
|
||||
userRepository.setSelectedUserInfo(userInfos[0])
|
||||
@@ -234,6 +238,7 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
whenever(manager.createGuest(any())).thenReturn(guestUserInfo)
|
||||
|
||||
underTest.onRecordSelected(UserRecord(isGuest = true), dialogShower)
|
||||
runCurrent()
|
||||
|
||||
verify(uiEventLogger, times(1))
|
||||
.log(MultiUserActionsEvent.CREATE_GUEST_FROM_USER_SWITCHER)
|
||||
@@ -244,7 +249,7 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun `onRecordSelected - action`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
val userInfos = createUserInfos(count = 3, includeGuest = true)
|
||||
userRepository.setUserInfos(userInfos)
|
||||
userRepository.setSelectedUserInfo(userInfos[0])
|
||||
@@ -260,81 +265,72 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun `users - switcher enabled`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
val userInfos = createUserInfos(count = 3, includeGuest = true)
|
||||
userRepository.setUserInfos(userInfos)
|
||||
userRepository.setSelectedUserInfo(userInfos[0])
|
||||
userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
|
||||
|
||||
var value: List<UserModel>? = null
|
||||
val job = underTest.users.onEach { value = it }.launchIn(this)
|
||||
assertUsers(models = value, count = 3, includeGuest = true)
|
||||
val value = collectLastValue(underTest.users)
|
||||
|
||||
job.cancel()
|
||||
assertUsers(models = value(), count = 3, includeGuest = true)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `users - switches to second user`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
val userInfos = createUserInfos(count = 2, includeGuest = false)
|
||||
userRepository.setUserInfos(userInfos)
|
||||
userRepository.setSelectedUserInfo(userInfos[0])
|
||||
userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
|
||||
|
||||
var value: List<UserModel>? = null
|
||||
val job = underTest.users.onEach { value = it }.launchIn(this)
|
||||
val value = collectLastValue(underTest.users)
|
||||
userRepository.setSelectedUserInfo(userInfos[1])
|
||||
|
||||
assertUsers(models = value, count = 2, selectedIndex = 1)
|
||||
job.cancel()
|
||||
assertUsers(models = value(), count = 2, selectedIndex = 1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `users - switcher not enabled`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
val userInfos = createUserInfos(count = 2, includeGuest = false)
|
||||
userRepository.setUserInfos(userInfos)
|
||||
userRepository.setSelectedUserInfo(userInfos[0])
|
||||
userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = false))
|
||||
|
||||
var value: List<UserModel>? = null
|
||||
val job = underTest.users.onEach { value = it }.launchIn(this)
|
||||
assertUsers(models = value, count = 1)
|
||||
|
||||
job.cancel()
|
||||
val value = collectLastValue(underTest.users)
|
||||
assertUsers(models = value(), count = 1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun selectedUser() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
val userInfos = createUserInfos(count = 2, includeGuest = false)
|
||||
userRepository.setUserInfos(userInfos)
|
||||
userRepository.setSelectedUserInfo(userInfos[0])
|
||||
userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
|
||||
|
||||
var value: UserModel? = null
|
||||
val job = underTest.selectedUser.onEach { value = it }.launchIn(this)
|
||||
assertUser(value, id = 0, isSelected = true)
|
||||
val value = collectLastValue(underTest.selectedUser)
|
||||
assertUser(value(), id = 0, isSelected = true)
|
||||
|
||||
userRepository.setSelectedUserInfo(userInfos[1])
|
||||
assertUser(value, id = 1, isSelected = true)
|
||||
|
||||
job.cancel()
|
||||
assertUser(value(), id = 1, isSelected = true)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `actions - device unlocked`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
val userInfos = createUserInfos(count = 2, includeGuest = false)
|
||||
|
||||
userRepository.setUserInfos(userInfos)
|
||||
userRepository.setSelectedUserInfo(userInfos[0])
|
||||
userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
|
||||
keyguardRepository.setKeyguardShowing(false)
|
||||
var value: List<UserActionModel>? = null
|
||||
val job = underTest.actions.onEach { value = it }.launchIn(this)
|
||||
val value = collectLastValue(underTest.actions)
|
||||
|
||||
assertThat(value)
|
||||
runCurrent()
|
||||
|
||||
assertThat(value())
|
||||
.isEqualTo(
|
||||
listOf(
|
||||
UserActionModel.ENTER_GUEST_MODE,
|
||||
@@ -343,13 +339,11 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
UserActionModel.NAVIGATE_TO_USER_MANAGEMENT,
|
||||
)
|
||||
)
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `actions - device unlocked - full screen`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
featureFlags.set(Flags.FULL_SCREEN_USER_SWITCHER, true)
|
||||
val userInfos = createUserInfos(count = 2, includeGuest = false)
|
||||
|
||||
@@ -357,10 +351,9 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
userRepository.setSelectedUserInfo(userInfos[0])
|
||||
userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
|
||||
keyguardRepository.setKeyguardShowing(false)
|
||||
var value: List<UserActionModel>? = null
|
||||
val job = underTest.actions.onEach { value = it }.launchIn(this)
|
||||
val value = collectLastValue(underTest.actions)
|
||||
|
||||
assertThat(value)
|
||||
assertThat(value())
|
||||
.isEqualTo(
|
||||
listOf(
|
||||
UserActionModel.ADD_USER,
|
||||
@@ -369,46 +362,38 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
UserActionModel.NAVIGATE_TO_USER_MANAGEMENT,
|
||||
)
|
||||
)
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `actions - device unlocked user not primary - empty list`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
val userInfos = createUserInfos(count = 2, includeGuest = false)
|
||||
userRepository.setUserInfos(userInfos)
|
||||
userRepository.setSelectedUserInfo(userInfos[1])
|
||||
userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
|
||||
keyguardRepository.setKeyguardShowing(false)
|
||||
var value: List<UserActionModel>? = null
|
||||
val job = underTest.actions.onEach { value = it }.launchIn(this)
|
||||
val value = collectLastValue(underTest.actions)
|
||||
|
||||
assertThat(value).isEqualTo(emptyList<UserActionModel>())
|
||||
|
||||
job.cancel()
|
||||
assertThat(value()).isEqualTo(emptyList<UserActionModel>())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `actions - device unlocked user is guest - empty list`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
val userInfos = createUserInfos(count = 2, includeGuest = true)
|
||||
assertThat(userInfos[1].isGuest).isTrue()
|
||||
userRepository.setUserInfos(userInfos)
|
||||
userRepository.setSelectedUserInfo(userInfos[1])
|
||||
userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
|
||||
keyguardRepository.setKeyguardShowing(false)
|
||||
var value: List<UserActionModel>? = null
|
||||
val job = underTest.actions.onEach { value = it }.launchIn(this)
|
||||
val value = collectLastValue(underTest.actions)
|
||||
|
||||
assertThat(value).isEqualTo(emptyList<UserActionModel>())
|
||||
|
||||
job.cancel()
|
||||
assertThat(value()).isEqualTo(emptyList<UserActionModel>())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `actions - device locked add from lockscreen set - full list`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
val userInfos = createUserInfos(count = 2, includeGuest = false)
|
||||
userRepository.setUserInfos(userInfos)
|
||||
userRepository.setSelectedUserInfo(userInfos[0])
|
||||
@@ -419,10 +404,9 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
)
|
||||
)
|
||||
keyguardRepository.setKeyguardShowing(false)
|
||||
var value: List<UserActionModel>? = null
|
||||
val job = underTest.actions.onEach { value = it }.launchIn(this)
|
||||
val value = collectLastValue(underTest.actions)
|
||||
|
||||
assertThat(value)
|
||||
assertThat(value())
|
||||
.isEqualTo(
|
||||
listOf(
|
||||
UserActionModel.ENTER_GUEST_MODE,
|
||||
@@ -431,13 +415,11 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
UserActionModel.NAVIGATE_TO_USER_MANAGEMENT,
|
||||
)
|
||||
)
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `actions - device locked add from lockscreen set - full list - full screen`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
featureFlags.set(Flags.FULL_SCREEN_USER_SWITCHER, true)
|
||||
val userInfos = createUserInfos(count = 2, includeGuest = false)
|
||||
userRepository.setUserInfos(userInfos)
|
||||
@@ -449,10 +431,9 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
)
|
||||
)
|
||||
keyguardRepository.setKeyguardShowing(false)
|
||||
var value: List<UserActionModel>? = null
|
||||
val job = underTest.actions.onEach { value = it }.launchIn(this)
|
||||
val value = collectLastValue(underTest.actions)
|
||||
|
||||
assertThat(value)
|
||||
assertThat(value())
|
||||
.isEqualTo(
|
||||
listOf(
|
||||
UserActionModel.ADD_USER,
|
||||
@@ -461,42 +442,35 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
UserActionModel.NAVIGATE_TO_USER_MANAGEMENT,
|
||||
)
|
||||
)
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `actions - device locked - only manage user is shown`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
val userInfos = createUserInfos(count = 2, includeGuest = false)
|
||||
userRepository.setUserInfos(userInfos)
|
||||
userRepository.setSelectedUserInfo(userInfos[0])
|
||||
userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
|
||||
keyguardRepository.setKeyguardShowing(true)
|
||||
var value: List<UserActionModel>? = null
|
||||
val job = underTest.actions.onEach { value = it }.launchIn(this)
|
||||
val value = collectLastValue(underTest.actions)
|
||||
|
||||
assertThat(value).isEqualTo(listOf(UserActionModel.NAVIGATE_TO_USER_MANAGEMENT))
|
||||
|
||||
job.cancel()
|
||||
assertThat(value()).isEqualTo(listOf(UserActionModel.NAVIGATE_TO_USER_MANAGEMENT))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `executeAction - add user - dialog shown`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
val userInfos = createUserInfos(count = 2, includeGuest = false)
|
||||
userRepository.setUserInfos(userInfos)
|
||||
userRepository.setSelectedUserInfo(userInfos[0])
|
||||
keyguardRepository.setKeyguardShowing(false)
|
||||
var dialogRequest: ShowDialogRequestModel? = null
|
||||
val job = underTest.dialogShowRequests.onEach { dialogRequest = it }.launchIn(this)
|
||||
val dialogRequest = collectLastValue(underTest.dialogShowRequests)
|
||||
val dialogShower: UserSwitchDialogController.DialogShower = mock()
|
||||
|
||||
underTest.executeAction(UserActionModel.ADD_USER, dialogShower)
|
||||
|
||||
verify(uiEventLogger, times(1))
|
||||
.log(MultiUserActionsEvent.CREATE_USER_FROM_USER_SWITCHER)
|
||||
assertThat(dialogRequest)
|
||||
assertThat(dialogRequest())
|
||||
.isEqualTo(
|
||||
ShowDialogRequestModel.ShowAddUserDialog(
|
||||
userHandle = userInfos[0].userHandle,
|
||||
@@ -507,14 +481,12 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
)
|
||||
|
||||
underTest.onDialogShown()
|
||||
assertThat(dialogRequest).isNull()
|
||||
|
||||
job.cancel()
|
||||
assertThat(dialogRequest()).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `executeAction - add supervised user - starts activity`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
fun `executeAction - add supervised user - dismisses dialog and starts activity`() =
|
||||
testScope.runTest {
|
||||
underTest.executeAction(UserActionModel.ADD_SUPERVISED_USER)
|
||||
|
||||
verify(uiEventLogger, times(1))
|
||||
@@ -528,7 +500,7 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun `executeAction - navigate to manage users`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
underTest.executeAction(UserActionModel.NAVIGATE_TO_USER_MANAGEMENT)
|
||||
|
||||
val intentCaptor = kotlinArgumentCaptor<Intent>()
|
||||
@@ -538,7 +510,7 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun `executeAction - guest mode`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
val userInfos = createUserInfos(count = 2, includeGuest = false)
|
||||
userRepository.setUserInfos(userInfos)
|
||||
userRepository.setSelectedUserInfo(userInfos[0])
|
||||
@@ -546,25 +518,24 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
val guestUserInfo = createUserInfo(id = 1337, name = "guest", isGuest = true)
|
||||
whenever(manager.createGuest(any())).thenReturn(guestUserInfo)
|
||||
val dialogRequests = mutableListOf<ShowDialogRequestModel?>()
|
||||
val showDialogsJob =
|
||||
underTest.dialogShowRequests
|
||||
.onEach {
|
||||
dialogRequests.add(it)
|
||||
if (it != null) {
|
||||
underTest.onDialogShown()
|
||||
}
|
||||
backgroundScope.launch {
|
||||
underTest.dialogShowRequests.collect {
|
||||
dialogRequests.add(it)
|
||||
if (it != null) {
|
||||
underTest.onDialogShown()
|
||||
}
|
||||
.launchIn(this)
|
||||
val dismissDialogsJob =
|
||||
underTest.dialogDismissRequests
|
||||
.onEach {
|
||||
if (it != null) {
|
||||
underTest.onDialogDismissed()
|
||||
}
|
||||
}
|
||||
}
|
||||
backgroundScope.launch {
|
||||
underTest.dialogDismissRequests.collect {
|
||||
if (it != null) {
|
||||
underTest.onDialogDismissed()
|
||||
}
|
||||
.launchIn(this)
|
||||
}
|
||||
}
|
||||
|
||||
underTest.executeAction(UserActionModel.ENTER_GUEST_MODE)
|
||||
runCurrent()
|
||||
|
||||
verify(uiEventLogger, times(1))
|
||||
.log(MultiUserActionsEvent.CREATE_GUEST_FROM_USER_SWITCHER)
|
||||
@@ -573,85 +544,79 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
ShowDialogRequestModel.ShowUserCreationDialog(isGuest = true),
|
||||
)
|
||||
verify(activityManager).switchUser(guestUserInfo.id)
|
||||
|
||||
showDialogsJob.cancel()
|
||||
dismissDialogsJob.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `selectUser - already selected guest re-selected - exit guest dialog`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
val userInfos = createUserInfos(count = 2, includeGuest = true)
|
||||
val guestUserInfo = userInfos[1]
|
||||
assertThat(guestUserInfo.isGuest).isTrue()
|
||||
userRepository.setUserInfos(userInfos)
|
||||
userRepository.setSelectedUserInfo(guestUserInfo)
|
||||
userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
|
||||
var dialogRequest: ShowDialogRequestModel? = null
|
||||
val job = underTest.dialogShowRequests.onEach { dialogRequest = it }.launchIn(this)
|
||||
val dialogRequest = collectLastValue(underTest.dialogShowRequests)
|
||||
|
||||
underTest.selectUser(
|
||||
newlySelectedUserId = guestUserInfo.id,
|
||||
dialogShower = dialogShower,
|
||||
)
|
||||
|
||||
assertThat(dialogRequest)
|
||||
assertThat(dialogRequest())
|
||||
.isInstanceOf(ShowDialogRequestModel.ShowExitGuestDialog::class.java)
|
||||
verify(dialogShower, never()).dismiss()
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `selectUser - currently guest non-guest selected - exit guest dialog`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
val userInfos = createUserInfos(count = 2, includeGuest = true)
|
||||
val guestUserInfo = userInfos[1]
|
||||
assertThat(guestUserInfo.isGuest).isTrue()
|
||||
userRepository.setUserInfos(userInfos)
|
||||
userRepository.setSelectedUserInfo(guestUserInfo)
|
||||
userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
|
||||
var dialogRequest: ShowDialogRequestModel? = null
|
||||
val job = underTest.dialogShowRequests.onEach { dialogRequest = it }.launchIn(this)
|
||||
val dialogRequest = collectLastValue(underTest.dialogShowRequests)
|
||||
|
||||
underTest.selectUser(newlySelectedUserId = userInfos[0].id, dialogShower = dialogShower)
|
||||
|
||||
assertThat(dialogRequest)
|
||||
assertThat(dialogRequest())
|
||||
.isInstanceOf(ShowDialogRequestModel.ShowExitGuestDialog::class.java)
|
||||
verify(dialogShower, never()).dismiss()
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `selectUser - not currently guest - switches users`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
val userInfos = createUserInfos(count = 2, includeGuest = false)
|
||||
userRepository.setUserInfos(userInfos)
|
||||
userRepository.setSelectedUserInfo(userInfos[0])
|
||||
userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
|
||||
var dialogRequest: ShowDialogRequestModel? = null
|
||||
val job = underTest.dialogShowRequests.onEach { dialogRequest = it }.launchIn(this)
|
||||
val dialogRequest = collectLastValue(underTest.dialogShowRequests)
|
||||
|
||||
underTest.selectUser(newlySelectedUserId = userInfos[1].id, dialogShower = dialogShower)
|
||||
|
||||
assertThat(dialogRequest).isNull()
|
||||
assertThat(dialogRequest()).isNull()
|
||||
verify(activityManager).switchUser(userInfos[1].id)
|
||||
verify(dialogShower).dismiss()
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Telephony call state changes - refreshes users`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
runCurrent()
|
||||
|
||||
val refreshUsersCallCount = userRepository.refreshUsersCallCount
|
||||
|
||||
telephonyRepository.setCallState(1)
|
||||
runCurrent()
|
||||
|
||||
assertThat(userRepository.refreshUsersCallCount).isEqualTo(refreshUsersCallCount + 1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `User switched broadcast`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
val userInfos = createUserInfos(count = 2, includeGuest = false)
|
||||
userRepository.setUserInfos(userInfos)
|
||||
userRepository.setSelectedUserInfo(userInfos[0])
|
||||
@@ -660,9 +625,11 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
val callback2: UserInteractor.UserCallback = mock()
|
||||
underTest.addCallback(callback1)
|
||||
underTest.addCallback(callback2)
|
||||
runCurrent()
|
||||
val refreshUsersCallCount = userRepository.refreshUsersCallCount
|
||||
|
||||
userRepository.setSelectedUserInfo(userInfos[1])
|
||||
runCurrent()
|
||||
fakeBroadcastDispatcher.registeredReceivers.forEach {
|
||||
it.onReceive(
|
||||
context,
|
||||
@@ -670,16 +637,17 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
.putExtra(Intent.EXTRA_USER_HANDLE, userInfos[1].id),
|
||||
)
|
||||
}
|
||||
runCurrent()
|
||||
|
||||
verify(callback1).onUserStateChanged()
|
||||
verify(callback2).onUserStateChanged()
|
||||
verify(callback1, atLeastOnce()).onUserStateChanged()
|
||||
verify(callback2, atLeastOnce()).onUserStateChanged()
|
||||
assertThat(userRepository.secondaryUserId).isEqualTo(userInfos[1].id)
|
||||
assertThat(userRepository.refreshUsersCallCount).isEqualTo(refreshUsersCallCount + 1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `User info changed broadcast`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
val userInfos = createUserInfos(count = 2, includeGuest = false)
|
||||
userRepository.setUserInfos(userInfos)
|
||||
userRepository.setSelectedUserInfo(userInfos[0])
|
||||
@@ -692,12 +660,14 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
)
|
||||
}
|
||||
|
||||
runCurrent()
|
||||
|
||||
assertThat(userRepository.refreshUsersCallCount).isEqualTo(refreshUsersCallCount + 1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `System user unlocked broadcast - refresh users`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
val userInfos = createUserInfos(count = 2, includeGuest = false)
|
||||
userRepository.setUserInfos(userInfos)
|
||||
userRepository.setSelectedUserInfo(userInfos[0])
|
||||
@@ -710,13 +680,14 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_SYSTEM),
|
||||
)
|
||||
}
|
||||
runCurrent()
|
||||
|
||||
assertThat(userRepository.refreshUsersCallCount).isEqualTo(refreshUsersCallCount + 1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Non-system user unlocked broadcast - do not refresh users`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
val userInfos = createUserInfos(count = 2, includeGuest = false)
|
||||
userRepository.setUserInfos(userInfos)
|
||||
userRepository.setSelectedUserInfo(userInfos[0])
|
||||
@@ -734,14 +705,14 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun userRecords() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
val userInfos = createUserInfos(count = 3, includeGuest = false)
|
||||
userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
|
||||
userRepository.setUserInfos(userInfos)
|
||||
userRepository.setSelectedUserInfo(userInfos[0])
|
||||
keyguardRepository.setKeyguardShowing(false)
|
||||
|
||||
testCoroutineScope.advanceUntilIdle()
|
||||
runCurrent()
|
||||
|
||||
assertRecords(
|
||||
records = underTest.userRecords.value,
|
||||
@@ -760,7 +731,7 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun userRecordsFullScreen() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
featureFlags.set(Flags.FULL_SCREEN_USER_SWITCHER, true)
|
||||
val userInfos = createUserInfos(count = 3, includeGuest = false)
|
||||
userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
|
||||
@@ -768,7 +739,7 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
userRepository.setSelectedUserInfo(userInfos[0])
|
||||
keyguardRepository.setKeyguardShowing(false)
|
||||
|
||||
testCoroutineScope.advanceUntilIdle()
|
||||
runCurrent()
|
||||
|
||||
assertRecords(
|
||||
records = underTest.userRecords.value,
|
||||
@@ -787,7 +758,7 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun selectedUserRecord() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
val userInfos = createUserInfos(count = 3, includeGuest = true)
|
||||
userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
|
||||
userRepository.setUserInfos(userInfos)
|
||||
@@ -805,64 +776,54 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun `users - secondary user - guest user can be switched to`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
val userInfos = createUserInfos(count = 3, includeGuest = true)
|
||||
userRepository.setUserInfos(userInfos)
|
||||
userRepository.setSelectedUserInfo(userInfos[1])
|
||||
userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
|
||||
|
||||
var res: List<UserModel>? = null
|
||||
val job = underTest.users.onEach { res = it }.launchIn(this)
|
||||
assertThat(res?.size == 3).isTrue()
|
||||
assertThat(res?.find { it.isGuest }).isNotNull()
|
||||
job.cancel()
|
||||
val res = collectLastValue(underTest.users)
|
||||
assertThat(res()?.size == 3).isTrue()
|
||||
assertThat(res()?.find { it.isGuest }).isNotNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `users - secondary user - no guest action`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
val userInfos = createUserInfos(count = 3, includeGuest = true)
|
||||
userRepository.setUserInfos(userInfos)
|
||||
userRepository.setSelectedUserInfo(userInfos[1])
|
||||
userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
|
||||
|
||||
var res: List<UserActionModel>? = null
|
||||
val job = underTest.actions.onEach { res = it }.launchIn(this)
|
||||
assertThat(res?.find { it == UserActionModel.ENTER_GUEST_MODE }).isNull()
|
||||
job.cancel()
|
||||
val res = collectLastValue(underTest.actions)
|
||||
assertThat(res()?.find { it == UserActionModel.ENTER_GUEST_MODE }).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `users - secondary user - no guest user record`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
val userInfos = createUserInfos(count = 3, includeGuest = true)
|
||||
userRepository.setUserInfos(userInfos)
|
||||
userRepository.setSelectedUserInfo(userInfos[1])
|
||||
userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
|
||||
|
||||
var res: List<UserRecord>? = null
|
||||
val job = underTest.userRecords.onEach { res = it }.launchIn(this)
|
||||
assertThat(res?.find { it.isGuest }).isNull()
|
||||
job.cancel()
|
||||
assertThat(underTest.userRecords.value.find { it.isGuest }).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `show user switcher - full screen disabled - shows dialog switcher`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
var dialogRequest: ShowDialogRequestModel? = null
|
||||
testScope.runTest {
|
||||
val expandable = mock<Expandable>()
|
||||
underTest.showUserSwitcher(context, expandable)
|
||||
|
||||
val job = underTest.dialogShowRequests.onEach { dialogRequest = it }.launchIn(this)
|
||||
val dialogRequest = collectLastValue(underTest.dialogShowRequests)
|
||||
|
||||
// Dialog is shown.
|
||||
assertThat(dialogRequest)
|
||||
assertThat(dialogRequest())
|
||||
.isEqualTo(ShowDialogRequestModel.ShowUserSwitcherDialog(expandable))
|
||||
|
||||
underTest.onDialogShown()
|
||||
assertThat(dialogRequest).isNull()
|
||||
|
||||
job.cancel()
|
||||
assertThat(dialogRequest()).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -893,8 +854,8 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun `users - secondary user - managed profile is not included`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
var userInfos = createUserInfos(count = 3, includeGuest = false).toMutableList()
|
||||
testScope.runTest {
|
||||
val userInfos = createUserInfos(count = 3, includeGuest = false).toMutableList()
|
||||
userInfos.add(
|
||||
UserInfo(
|
||||
50,
|
||||
@@ -907,23 +868,19 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
userRepository.setSelectedUserInfo(userInfos[1])
|
||||
userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
|
||||
|
||||
var res: List<UserModel>? = null
|
||||
val job = underTest.users.onEach { res = it }.launchIn(this)
|
||||
assertThat(res?.size == 3).isTrue()
|
||||
job.cancel()
|
||||
val res = collectLastValue(underTest.users)
|
||||
assertThat(res()?.size == 3).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `current user is not primary and user switcher is disabled`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
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()
|
||||
val selectedUser = collectLastValue(underTest.selectedUser)
|
||||
assertThat(selectedUser()).isNotNull()
|
||||
}
|
||||
|
||||
private fun assertUsers(
|
||||
@@ -1061,7 +1018,6 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val IMMEDIATE = Dispatchers.Main.immediate
|
||||
private val ICON = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888)
|
||||
private val GUEST_ICON: Drawable = mock()
|
||||
private const val SUPERVISED_USER_CREATION_APP_PACKAGE = "supervisedUserCreation"
|
||||
|
||||
Reference in New Issue
Block a user