diff options
5 files changed, 242 insertions, 86 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt index a487f538e59c..ab4ead6749cb 100644 --- a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt @@ -27,6 +27,7 @@ import android.content.pm.UserInfo import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable import android.graphics.drawable.Icon +import android.os.Process import android.os.RemoteException import android.os.UserHandle import android.os.UserManager @@ -334,6 +335,7 @@ constructor( onBroadcastReceived(intent, previousSelectedUser) } .launchIn(applicationScope) + restartSecondaryService(repository.getSelectedUserInfo().id) keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback) } @@ -646,7 +648,7 @@ constructor( // Connect to the new secondary user's service (purely to ensure that a persistent // SystemUI application is created for that user) - if (userId != UserHandle.USER_SYSTEM) { + if (userId != Process.myUserHandle().identifier) { applicationContext.startServiceAsUser( intent, UserHandle.of(userId), diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt index 3ea8f5412b40..cdcd1a257671 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt @@ -20,6 +20,7 @@ import android.app.ActivityManager import android.app.StatusBarManager.DISABLE2_NONE import android.app.StatusBarManager.DISABLE2_NOTIFICATION_SHADE import android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS +import android.content.pm.UserInfo import android.os.UserManager import androidx.test.filters.SmallTest import com.android.internal.logging.UiEventLogger @@ -47,6 +48,7 @@ import com.android.systemui.user.domain.interactor.UserInteractor import com.android.systemui.util.mockito.whenever import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.runBlocking import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest @@ -92,6 +94,23 @@ class ShadeInteractorTest : SysuiTestCase() { mainDispatcher = testDispatcher, repository = userRepository, ) + + runBlocking { + val userInfos = + listOf( + UserInfo( + /* id= */ 0, + /* name= */ "zero", + /* iconPath= */ "", + /* flags= */ UserInfo.FLAG_PRIMARY or + UserInfo.FLAG_ADMIN or + UserInfo.FLAG_FULL, + UserManager.USER_TYPE_FULL_SYSTEM, + ), + ) + userRepository.setUserInfos(userInfos) + userRepository.setSelectedUserInfo(userInfos[0]) + } userInteractor = UserInteractor( applicationContext = context, diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt index 89dce6151de9..5b418eddc4f5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt @@ -19,10 +19,12 @@ package com.android.systemui.user.domain.interactor import android.app.ActivityManager import android.app.admin.DevicePolicyManager +import android.content.Context import android.content.Intent import android.content.pm.UserInfo import android.graphics.Bitmap import android.graphics.drawable.Drawable +import android.os.Process import android.os.UserHandle import android.os.UserManager import android.provider.Settings @@ -62,7 +64,9 @@ import com.google.common.truth.Truth.assertThat import junit.framework.Assert.assertNotNull import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking import kotlinx.coroutines.test.StandardTestDispatcher +import kotlinx.coroutines.test.TestDispatcher import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest @@ -76,6 +80,7 @@ import org.mockito.ArgumentMatchers.anyInt import org.mockito.Mock import org.mockito.Mockito.atLeastOnce import org.mockito.Mockito.never +import org.mockito.Mockito.spy import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @@ -99,11 +104,15 @@ class UserInteractorTest : SysuiTestCase() { private lateinit var underTest: UserInteractor + private lateinit var spyContext: Context private lateinit var testScope: TestScope private lateinit var userRepository: FakeUserRepository + private lateinit var keyguardReply: KeyguardInteractorFactory.WithDependencies private lateinit var keyguardRepository: FakeKeyguardRepository private lateinit var telephonyRepository: FakeTelephonyRepository + private lateinit var testDispatcher: TestDispatcher private lateinit var featureFlags: FakeFeatureFlags + private lateinit var refreshUsersScheduler: RefreshUsersScheduler @Before fun setUp() { @@ -123,58 +132,36 @@ class UserInteractorTest : SysuiTestCase() { set(Flags.FULL_SCREEN_USER_SWITCHER, false) set(Flags.FACE_AUTH_REFACTOR, true) } - val reply = KeyguardInteractorFactory.create(featureFlags = featureFlags) - keyguardRepository = reply.repository + spyContext = spy(context) + keyguardReply = KeyguardInteractorFactory.create(featureFlags = featureFlags) + keyguardRepository = keyguardReply.repository userRepository = FakeUserRepository() telephonyRepository = FakeTelephonyRepository() - val testDispatcher = StandardTestDispatcher() + testDispatcher = StandardTestDispatcher() testScope = TestScope(testDispatcher) - val refreshUsersScheduler = + refreshUsersScheduler = RefreshUsersScheduler( applicationScope = testScope.backgroundScope, mainDispatcher = testDispatcher, repository = userRepository, ) - underTest = - UserInteractor( - applicationContext = context, - repository = userRepository, - activityStarter = activityStarter, - keyguardInteractor = reply.keyguardInteractor, - manager = manager, - headlessSystemUserMode = headlessSystemUserMode, - applicationScope = testScope.backgroundScope, - telephonyInteractor = - TelephonyInteractor( - repository = telephonyRepository, - ), - broadcastDispatcher = fakeBroadcastDispatcher, - keyguardUpdateMonitor = keyguardUpdateMonitor, - backgroundDispatcher = testDispatcher, - activityManager = activityManager, - refreshUsersScheduler = refreshUsersScheduler, - guestUserInteractor = - GuestUserInteractor( - applicationContext = context, - applicationScope = testScope.backgroundScope, - mainDispatcher = testDispatcher, - backgroundDispatcher = testDispatcher, - manager = manager, - repository = userRepository, - deviceProvisionedController = deviceProvisionedController, - devicePolicyManager = devicePolicyManager, - refreshUsersScheduler = refreshUsersScheduler, - uiEventLogger = uiEventLogger, - resumeSessionReceiver = resumeSessionReceiver, - resetOrExitSessionReceiver = resetOrExitSessionReceiver, - ), - uiEventLogger = uiEventLogger, - featureFlags = featureFlags, - ) } @Test - fun testKeyguardUpdateMonitor_onKeyguardGoingAway() = + fun createUserInteractor_processUser_noSecondaryService() { + createUserInteractor() + verify(spyContext, never()).startServiceAsUser(any(), any()) + } + + @Test + fun createUserInteractor_nonProcessUser_startsSecondaryService() { + createUserInteractor(false /* startAsProcessUser */) + verify(spyContext).startServiceAsUser(any(), any()) + } + + @Test + fun testKeyguardUpdateMonitor_onKeyguardGoingAway() { + createUserInteractor() testScope.runTest { val argumentCaptor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java) verify(keyguardUpdateMonitor).registerCallback(argumentCaptor.capture()) @@ -184,9 +171,11 @@ class UserInteractorTest : SysuiTestCase() { val lastValue = collectLastValue(underTest.dialogDismissRequests) assertNotNull(lastValue) } + } @Test - fun onRecordSelected_user() = + fun onRecordSelected_user() { + createUserInteractor() testScope.runTest { val userInfos = createUserInfos(count = 3, includeGuest = false) userRepository.setUserInfos(userInfos) @@ -201,9 +190,11 @@ class UserInteractorTest : SysuiTestCase() { verify(activityManager).switchUser(userInfos[1].id) Unit } + } @Test - fun onRecordSelected_switchToGuestUser() = + fun onRecordSelected_switchToGuestUser() { + createUserInteractor() testScope.runTest { val userInfos = createUserInfos(count = 3, includeGuest = true) userRepository.setUserInfos(userInfos) @@ -217,9 +208,11 @@ class UserInteractorTest : SysuiTestCase() { verify(activityManager).switchUser(userInfos.last().id) Unit } + } @Test - fun onRecordSelected_switchToRestrictedUser() = + fun onRecordSelected_switchToRestrictedUser() { + createUserInteractor() testScope.runTest { var userInfos = createUserInfos(count = 2, includeGuest = false).toMutableList() userInfos.add( @@ -242,9 +235,11 @@ class UserInteractorTest : SysuiTestCase() { verify(activityManager).switchUser(userInfos.last().id) Unit } + } @Test - fun onRecordSelected_enterGuestMode() = + fun onRecordSelected_enterGuestMode() { + createUserInteractor() testScope.runTest { val userInfos = createUserInfos(count = 3, includeGuest = false) userRepository.setUserInfos(userInfos) @@ -262,9 +257,11 @@ class UserInteractorTest : SysuiTestCase() { verify(manager).createGuest(any()) Unit } + } @Test - fun onRecordSelected_action() = + fun onRecordSelected_action() { + createUserInteractor() testScope.runTest { val userInfos = createUserInfos(count = 3, includeGuest = true) userRepository.setUserInfos(userInfos) @@ -278,9 +275,11 @@ class UserInteractorTest : SysuiTestCase() { verify(dialogShower, never()).dismiss() verify(activityStarter).startActivity(any(), anyBoolean()) } + } @Test - fun users_switcherEnabled() = + fun users_switcherEnabled() { + createUserInteractor() testScope.runTest { val userInfos = createUserInfos(count = 3, includeGuest = true) userRepository.setUserInfos(userInfos) @@ -291,9 +290,11 @@ class UserInteractorTest : SysuiTestCase() { assertUsers(models = value(), count = 3, includeGuest = true) } + } @Test - fun users_switchesToSecondUser() = + fun users_switchesToSecondUser() { + createUserInteractor() testScope.runTest { val userInfos = createUserInfos(count = 2, includeGuest = false) userRepository.setUserInfos(userInfos) @@ -305,9 +306,11 @@ class UserInteractorTest : SysuiTestCase() { assertUsers(models = value(), count = 2, selectedIndex = 1) } + } @Test - fun users_switcherNotEnabled() = + fun users_switcherNotEnabled() { + createUserInteractor() testScope.runTest { val userInfos = createUserInfos(count = 2, includeGuest = false) userRepository.setUserInfos(userInfos) @@ -317,9 +320,11 @@ class UserInteractorTest : SysuiTestCase() { val value = collectLastValue(underTest.users) assertUsers(models = value(), count = 1) } + } @Test - fun selectedUser() = + fun selectedUser() { + createUserInteractor() testScope.runTest { val userInfos = createUserInfos(count = 2, includeGuest = false) userRepository.setUserInfos(userInfos) @@ -332,9 +337,11 @@ class UserInteractorTest : SysuiTestCase() { userRepository.setSelectedUserInfo(userInfos[1]) assertUser(value(), id = 1, isSelected = true) } + } @Test - fun actions_deviceUnlocked() = + fun actions_deviceUnlocked() { + createUserInteractor() testScope.runTest { val userInfos = createUserInfos(count = 2, includeGuest = false) @@ -356,9 +363,11 @@ class UserInteractorTest : SysuiTestCase() { ) ) } + } @Test - fun actions_deviceUnlocked_fullScreen() = + fun actions_deviceUnlocked_fullScreen() { + createUserInteractor() testScope.runTest { featureFlags.set(Flags.FULL_SCREEN_USER_SWITCHER, true) val userInfos = createUserInfos(count = 2, includeGuest = false) @@ -379,9 +388,11 @@ class UserInteractorTest : SysuiTestCase() { ) ) } + } @Test - fun actions_deviceUnlockedUserNotPrimary_emptyList() = + fun actions_deviceUnlockedUserNotPrimary_emptyList() { + createUserInteractor() testScope.runTest { val userInfos = createUserInfos(count = 2, includeGuest = false) userRepository.setUserInfos(userInfos) @@ -392,9 +403,11 @@ class UserInteractorTest : SysuiTestCase() { assertThat(value()).isEqualTo(emptyList<UserActionModel>()) } + } @Test - fun actions_deviceUnlockedUserIsGuest_emptyList() = + fun actions_deviceUnlockedUserIsGuest_emptyList() { + createUserInteractor() testScope.runTest { val userInfos = createUserInfos(count = 2, includeGuest = true) assertThat(userInfos[1].isGuest).isTrue() @@ -406,9 +419,11 @@ class UserInteractorTest : SysuiTestCase() { assertThat(value()).isEqualTo(emptyList<UserActionModel>()) } + } @Test - fun actions_deviceLockedAddFromLockscreenSet_fullList() = + fun actions_deviceLockedAddFromLockscreenSet_fullList() { + createUserInteractor() testScope.runTest { val userInfos = createUserInfos(count = 2, includeGuest = false) userRepository.setUserInfos(userInfos) @@ -432,9 +447,11 @@ class UserInteractorTest : SysuiTestCase() { ) ) } + } @Test - fun actions_deviceLockedAddFromLockscreenSet_fullList_fullScreen() = + fun actions_deviceLockedAddFromLockscreenSet_fullList_fullScreen() { + createUserInteractor() testScope.runTest { featureFlags.set(Flags.FULL_SCREEN_USER_SWITCHER, true) val userInfos = createUserInfos(count = 2, includeGuest = false) @@ -459,9 +476,11 @@ class UserInteractorTest : SysuiTestCase() { ) ) } + } @Test - fun actions_deviceLocked_onlymanageUserIsShown() = + fun actions_deviceLocked_onlymanageUserIsShown() { + createUserInteractor() testScope.runTest { val userInfos = createUserInfos(count = 2, includeGuest = false) userRepository.setUserInfos(userInfos) @@ -472,9 +491,11 @@ class UserInteractorTest : SysuiTestCase() { assertThat(value()).isEqualTo(listOf(UserActionModel.NAVIGATE_TO_USER_MANAGEMENT)) } + } @Test - fun executeAction_addUser_dismissesDialogAndStartsActivity() = + fun executeAction_addUser_dismissesDialogAndStartsActivity() { + createUserInteractor() testScope.runTest { val userInfos = createUserInfos(count = 2, includeGuest = false) userRepository.setUserInfos(userInfos) @@ -486,9 +507,11 @@ class UserInteractorTest : SysuiTestCase() { .log(MultiUserActionsEvent.CREATE_USER_FROM_USER_SWITCHER) underTest.onDialogShown() } + } @Test - fun executeAction_addSupervisedUser_dismissesDialogAndStartsActivity() = + fun executeAction_addSupervisedUser_dismissesDialogAndStartsActivity() { + createUserInteractor() testScope.runTest { underTest.executeAction(UserActionModel.ADD_SUPERVISED_USER) @@ -500,9 +523,11 @@ class UserInteractorTest : SysuiTestCase() { .isEqualTo(UserManager.ACTION_CREATE_SUPERVISED_USER) assertThat(intentCaptor.value.`package`).isEqualTo(SUPERVISED_USER_CREATION_APP_PACKAGE) } + } @Test - fun executeAction_navigateToManageUsers() = + fun executeAction_navigateToManageUsers() { + createUserInteractor() testScope.runTest { underTest.executeAction(UserActionModel.NAVIGATE_TO_USER_MANAGEMENT) @@ -510,9 +535,11 @@ class UserInteractorTest : SysuiTestCase() { verify(activityStarter).startActivity(intentCaptor.capture(), eq(true)) assertThat(intentCaptor.value.action).isEqualTo(Settings.ACTION_USER_SETTINGS) } + } @Test - fun executeAction_guestMode() = + fun executeAction_guestMode() { + createUserInteractor() testScope.runTest { val userInfos = createUserInfos(count = 2, includeGuest = false) userRepository.setUserInfos(userInfos) @@ -548,9 +575,11 @@ class UserInteractorTest : SysuiTestCase() { ) verify(activityManager).switchUser(guestUserInfo.id) } + } @Test - fun selectUser_alreadySelectedGuestReSelected_exitGuestDialog() = + fun selectUser_alreadySelectedGuestReSelected_exitGuestDialog() { + createUserInteractor() testScope.runTest { val userInfos = createUserInfos(count = 2, includeGuest = true) val guestUserInfo = userInfos[1] @@ -569,9 +598,11 @@ class UserInteractorTest : SysuiTestCase() { .isInstanceOf(ShowDialogRequestModel.ShowExitGuestDialog::class.java) verify(dialogShower, never()).dismiss() } + } @Test - fun selectUser_currentlyGuestNonGuestSelected_exitGuestDialog() = + fun selectUser_currentlyGuestNonGuestSelected_exitGuestDialog() { + createUserInteractor() testScope.runTest { val userInfos = createUserInfos(count = 2, includeGuest = true) val guestUserInfo = userInfos[1] @@ -587,9 +618,11 @@ class UserInteractorTest : SysuiTestCase() { .isInstanceOf(ShowDialogRequestModel.ShowExitGuestDialog::class.java) verify(dialogShower, never()).dismiss() } + } @Test - fun selectUser_notCurrentlyGuest_switchesUsers() = + fun selectUser_notCurrentlyGuest_switchesUsers() { + createUserInteractor() testScope.runTest { val userInfos = createUserInfos(count = 2, includeGuest = false) userRepository.setUserInfos(userInfos) @@ -603,9 +636,11 @@ class UserInteractorTest : SysuiTestCase() { verify(activityManager).switchUser(userInfos[1].id) verify(dialogShower).dismiss() } + } @Test - fun telephonyCallStateChanges_refreshesUsers() = + fun telephonyCallStateChanges_refreshesUsers() { + createUserInteractor() testScope.runTest { runCurrent() @@ -616,9 +651,11 @@ class UserInteractorTest : SysuiTestCase() { assertThat(userRepository.refreshUsersCallCount).isEqualTo(refreshUsersCallCount + 1) } + } @Test - fun userSwitchedBroadcast() = + fun userSwitchedBroadcast() { + createUserInteractor() testScope.runTest { val userInfos = createUserInfos(count = 2, includeGuest = false) userRepository.setUserInfos(userInfos) @@ -634,7 +671,7 @@ class UserInteractorTest : SysuiTestCase() { userRepository.setSelectedUserInfo(userInfos[1]) runCurrent() fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly( - context, + spyContext, Intent(Intent.ACTION_USER_SWITCHED) .putExtra(Intent.EXTRA_USER_HANDLE, userInfos[1].id), ) @@ -644,10 +681,13 @@ class UserInteractorTest : SysuiTestCase() { verify(callback2, atLeastOnce()).onUserStateChanged() assertThat(userRepository.secondaryUserId).isEqualTo(userInfos[1].id) assertThat(userRepository.refreshUsersCallCount).isEqualTo(refreshUsersCallCount + 1) + verify(spyContext).startServiceAsUser(any(), eq(UserHandle.of(userInfos[1].id))) } + } @Test - fun userInfoChangedBroadcast() = + fun userInfoChangedBroadcast() { + createUserInteractor() testScope.runTest { val userInfos = createUserInfos(count = 2, includeGuest = false) userRepository.setUserInfos(userInfos) @@ -655,7 +695,7 @@ class UserInteractorTest : SysuiTestCase() { val refreshUsersCallCount = userRepository.refreshUsersCallCount fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly( - context, + spyContext, Intent(Intent.ACTION_USER_INFO_CHANGED), ) @@ -663,9 +703,11 @@ class UserInteractorTest : SysuiTestCase() { assertThat(userRepository.refreshUsersCallCount).isEqualTo(refreshUsersCallCount + 1) } + } @Test - fun systemUserUnlockedBroadcast_refreshUsers() = + fun systemUserUnlockedBroadcast_refreshUsers() { + createUserInteractor() testScope.runTest { val userInfos = createUserInfos(count = 2, includeGuest = false) userRepository.setUserInfos(userInfos) @@ -673,7 +715,7 @@ class UserInteractorTest : SysuiTestCase() { val refreshUsersCallCount = userRepository.refreshUsersCallCount fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly( - context, + spyContext, Intent(Intent.ACTION_USER_UNLOCKED) .putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_SYSTEM), ) @@ -681,9 +723,11 @@ class UserInteractorTest : SysuiTestCase() { assertThat(userRepository.refreshUsersCallCount).isEqualTo(refreshUsersCallCount + 1) } + } @Test - fun nonSystemUserUnlockedBroadcast_doNotRefreshUsers() = + fun nonSystemUserUnlockedBroadcast_doNotRefreshUsers() { + createUserInteractor() testScope.runTest { val userInfos = createUserInfos(count = 2, includeGuest = false) userRepository.setUserInfos(userInfos) @@ -691,15 +735,17 @@ class UserInteractorTest : SysuiTestCase() { val refreshUsersCallCount = userRepository.refreshUsersCallCount fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly( - context, + spyContext, Intent(Intent.ACTION_USER_UNLOCKED).putExtra(Intent.EXTRA_USER_HANDLE, 1337), ) assertThat(userRepository.refreshUsersCallCount).isEqualTo(refreshUsersCallCount) } + } @Test - fun userRecords() = + fun userRecords() { + createUserInteractor() testScope.runTest { val userInfos = createUserInfos(count = 3, includeGuest = false) userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true)) @@ -723,9 +769,11 @@ class UserInteractorTest : SysuiTestCase() { ), ) } + } @Test - fun userRecordsFullScreen() = + fun userRecordsFullScreen() { + createUserInteractor() testScope.runTest { featureFlags.set(Flags.FULL_SCREEN_USER_SWITCHER, true) val userInfos = createUserInfos(count = 3, includeGuest = false) @@ -750,9 +798,11 @@ class UserInteractorTest : SysuiTestCase() { ), ) } + } @Test - fun selectedUserRecord() = + fun selectedUserRecord() { + createUserInteractor() testScope.runTest { val userInfos = createUserInfos(count = 3, includeGuest = true) userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true)) @@ -768,9 +818,11 @@ class UserInteractorTest : SysuiTestCase() { isSwitchToEnabled = true, ) } + } @Test - fun users_secondaryUser_guestUserCanBeSwitchedTo() = + fun users_secondaryUser_guestUserCanBeSwitchedTo() { + createUserInteractor() testScope.runTest { val userInfos = createUserInfos(count = 3, includeGuest = true) userRepository.setUserInfos(userInfos) @@ -781,9 +833,11 @@ class UserInteractorTest : SysuiTestCase() { assertThat(res()?.size == 3).isTrue() assertThat(res()?.find { it.isGuest }).isNotNull() } + } @Test - fun users_secondaryUser_noGuestAction() = + fun users_secondaryUser_noGuestAction() { + createUserInteractor() testScope.runTest { val userInfos = createUserInfos(count = 3, includeGuest = true) userRepository.setUserInfos(userInfos) @@ -793,9 +847,11 @@ class UserInteractorTest : SysuiTestCase() { val res = collectLastValue(underTest.actions) assertThat(res()?.find { it == UserActionModel.ENTER_GUEST_MODE }).isNull() } + } @Test - fun users_secondaryUser_noGuestUserRecord() = + fun users_secondaryUser_noGuestUserRecord() { + createUserInteractor() testScope.runTest { val userInfos = createUserInfos(count = 3, includeGuest = true) userRepository.setUserInfos(userInfos) @@ -804,9 +860,11 @@ class UserInteractorTest : SysuiTestCase() { assertThat(underTest.userRecords.value.find { it.isGuest }).isNull() } + } @Test - fun showUserSwitcher_fullScreenDisabled_showsDialogSwitcher() = + fun showUserSwitcher_fullScreenDisabled_showsDialogSwitcher() { + createUserInteractor() testScope.runTest { val expandable = mock<Expandable>() underTest.showUserSwitcher(expandable) @@ -820,9 +878,11 @@ class UserInteractorTest : SysuiTestCase() { underTest.onDialogShown() assertThat(dialogRequest()).isNull() } + } @Test - fun showUserSwitcher_fullScreenEnabled_launchesFullScreenDialog() = + fun showUserSwitcher_fullScreenEnabled_launchesFullScreenDialog() { + createUserInteractor() testScope.runTest { featureFlags.set(Flags.FULL_SCREEN_USER_SWITCHER, true) @@ -838,9 +898,11 @@ class UserInteractorTest : SysuiTestCase() { underTest.onDialogShown() assertThat(dialogRequest()).isNull() } + } @Test - fun users_secondaryUser_managedProfileIsNotIncluded() = + fun users_secondaryUser_managedProfileIsNotIncluded() { + createUserInteractor() testScope.runTest { val userInfos = createUserInfos(count = 3, includeGuest = false).toMutableList() userInfos.add( @@ -858,9 +920,11 @@ class UserInteractorTest : SysuiTestCase() { val res = collectLastValue(underTest.users) assertThat(res()?.size == 3).isTrue() } + } @Test - fun currentUserIsNotPrimaryAndUserSwitcherIsDisabled() = + fun currentUserIsNotPrimaryAndUserSwitcherIsDisabled() { + createUserInteractor() testScope.runTest { val userInfos = createUserInfos(count = 2, includeGuest = false) userRepository.setUserInfos(userInfos) @@ -869,9 +933,11 @@ class UserInteractorTest : SysuiTestCase() { val selectedUser = collectLastValue(underTest.selectedUser) assertThat(selectedUser()).isNotNull() } + } @Test - fun userRecords_isActionAndNoUsersUnlocked_actionIsDisabled() = + fun userRecords_isActionAndNoUsersUnlocked_actionIsDisabled() { + createUserInteractor() testScope.runTest { keyguardRepository.setKeyguardShowing(true) whenever(manager.getUserSwitchability(any())) @@ -891,9 +957,11 @@ class UserInteractorTest : SysuiTestCase() { .filter { it.info == null } .forEach { action -> assertThat(action.isSwitchToEnabled).isFalse() } } + } @Test - fun userRecords_isActionAndNoUsersUnlocked_actionIsDisabled_HeadlessMode() = + fun userRecords_isActionAndNoUsersUnlocked_actionIsDisabled_HeadlessMode() { + createUserInteractor() testScope.runTest { keyguardRepository.setKeyguardShowing(true) whenever(headlessSystemUserMode.isHeadlessSystemUserMode()).thenReturn(true) @@ -913,6 +981,7 @@ class UserInteractorTest : SysuiTestCase() { .filter { it.info == null } .forEach { action -> assertThat(action.isSwitchToEnabled).isFalse() } } + } private fun assertUsers( models: List<UserModel>?, @@ -1005,6 +1074,53 @@ class UserInteractorTest : SysuiTestCase() { .isEqualTo(type == UserActionModel.ADD_SUPERVISED_USER) } + private fun createUserInteractor(startAsProcessUser: Boolean = true) { + val processUserId = Process.myUserHandle().identifier + val startUserId = if (startAsProcessUser) processUserId else (processUserId + 1) + runBlocking { + val userInfo = + createUserInfo(id = startUserId, name = "user_$startUserId", isPrimary = true) + userRepository.setUserInfos(listOf(userInfo)) + userRepository.setSelectedUserInfo(userInfo) + } + underTest = + UserInteractor( + applicationContext = spyContext, + repository = userRepository, + activityStarter = activityStarter, + keyguardInteractor = keyguardReply.keyguardInteractor, + manager = manager, + headlessSystemUserMode = headlessSystemUserMode, + applicationScope = testScope.backgroundScope, + telephonyInteractor = + TelephonyInteractor( + repository = telephonyRepository, + ), + broadcastDispatcher = fakeBroadcastDispatcher, + keyguardUpdateMonitor = keyguardUpdateMonitor, + backgroundDispatcher = testDispatcher, + activityManager = activityManager, + refreshUsersScheduler = refreshUsersScheduler, + guestUserInteractor = + GuestUserInteractor( + applicationContext = spyContext, + applicationScope = testScope.backgroundScope, + mainDispatcher = testDispatcher, + backgroundDispatcher = testDispatcher, + manager = manager, + repository = userRepository, + deviceProvisionedController = deviceProvisionedController, + devicePolicyManager = devicePolicyManager, + refreshUsersScheduler = refreshUsersScheduler, + uiEventLogger = uiEventLogger, + resumeSessionReceiver = resumeSessionReceiver, + resetOrExitSessionReceiver = resetOrExitSessionReceiver, + ), + uiEventLogger = uiEventLogger, + featureFlags = featureFlags, + ) + } + private fun createUserInfos( count: Int, includeGuest: Boolean, diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt index 9cb26e05887d..2433e123a309 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt @@ -50,6 +50,7 @@ import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.toList import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.advanceUntilIdle @@ -237,6 +238,10 @@ class StatusBarUserChipViewModelTest : SysuiTestCase() { set(Flags.FULL_SCREEN_USER_SWITCHER, false) set(Flags.FACE_AUTH_REFACTOR, true) } + runBlocking { + userRepository.setUserInfos(listOf(USER_0)) + userRepository.setSelectedUserInfo(USER_0) + } return StatusBarUserChipViewModel( context = context, interactor = diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt index e3f9fac27815..8c88f95d73a5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt @@ -102,6 +102,20 @@ class UserSwitcherViewModelTest : SysuiTestCase() { testScope = TestScope(testDispatcher) userRepository = FakeUserRepository() runBlocking { + val userInfos = + listOf( + UserInfo( + /* id= */ 0, + /* name= */ "zero", + /* iconPath= */ "", + /* flags= */ UserInfo.FLAG_PRIMARY or + UserInfo.FLAG_ADMIN or + UserInfo.FLAG_FULL, + UserManager.USER_TYPE_FULL_SYSTEM, + ), + ) + userRepository.setUserInfos(userInfos) + userRepository.setSelectedUserInfo(userInfos[0]) userRepository.setSettings( UserSwitcherSettingsModel( isUserSwitcherEnabled = true, |