Merge "[Bouncer] Add manage users to bouncer." into tm-qpr-dev

This commit is contained in:
Aaron Liu
2022-10-15 17:45:10 +00:00
committed by Android (Google) Code Review
17 changed files with 285 additions and 116 deletions

View File

@@ -241,4 +241,6 @@
<string name="clock_title_bubble">Bubble</string>
<!-- Name of the "Analog" clock face [CHAR LIMIT=15]-->
<string name="clock_title_analog">Analog</string>
<!-- Title of bouncer when we want to authenticate before continuing with action. [CHAR LIMIT=NONE] -->
<string name="keyguard_unlock_to_continue">Unlock your device to continue</string>
</resources>

View File

@@ -67,7 +67,6 @@ import android.view.ViewGroup;
import android.view.WindowInsets;
import android.view.WindowInsetsAnimation;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
@@ -318,7 +317,8 @@ public class KeyguardSecurityContainer extends ConstraintLayout {
}
void initMode(@Mode int mode, GlobalSettings globalSettings, FalsingManager falsingManager,
UserSwitcherController userSwitcherController) {
UserSwitcherController userSwitcherController,
UserSwitcherViewMode.UserSwitcherCallback userSwitcherCallback) {
if (mCurrentMode == mode) return;
Log.i(TAG, "Switching mode from " + modeToString(mCurrentMode) + " to "
+ modeToString(mode));
@@ -330,7 +330,7 @@ public class KeyguardSecurityContainer extends ConstraintLayout {
mViewMode = new OneHandedViewMode();
break;
case MODE_USER_SWITCHER:
mViewMode = new UserSwitcherViewMode();
mViewMode = new UserSwitcherViewMode(userSwitcherCallback);
break;
default:
mViewMode = new DefaultViewMode();
@@ -864,6 +864,12 @@ public class KeyguardSecurityContainer extends ConstraintLayout {
private UserSwitcherController.UserSwitchCallback mUserSwitchCallback =
this::setupUserSwitcher;
private UserSwitcherCallback mUserSwitcherCallback;
UserSwitcherViewMode(UserSwitcherCallback userSwitcherCallback) {
mUserSwitcherCallback = userSwitcherCallback;
}
@Override
public void init(@NonNull ConstraintLayout v, @NonNull GlobalSettings globalSettings,
@NonNull KeyguardSecurityViewFlipper viewFlipper,
@@ -1040,34 +1046,25 @@ public class KeyguardSecurityContainer extends ConstraintLayout {
}
};
if (adapter.getCount() < 2) {
// The drop down arrow is at index 1
((LayerDrawable) mUserSwitcher.getBackground()).getDrawable(1).setAlpha(0);
anchor.setClickable(false);
return;
} else {
((LayerDrawable) mUserSwitcher.getBackground()).getDrawable(1).setAlpha(255);
}
anchor.setOnClickListener((v) -> {
if (mFalsingManager.isFalseTap(LOW_PENALTY)) return;
mPopup = new KeyguardUserSwitcherPopupMenu(v.getContext(), mFalsingManager);
mPopup.setAnchorView(anchor);
mPopup.setAdapter(adapter);
mPopup.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView parent, View view, int pos, long id) {
if (mFalsingManager.isFalseTap(LOW_PENALTY)) return;
if (!view.isEnabled()) return;
// Subtract one for the header
UserRecord user = adapter.getItem(pos - 1);
if (!user.isCurrent) {
adapter.onUserListItemClicked(user);
}
mPopup.dismiss();
mPopup = null;
}
});
mPopup.setOnItemClickListener((parent, view, pos, id) -> {
if (mFalsingManager.isFalseTap(LOW_PENALTY)) return;
if (!view.isEnabled()) return;
// Subtract one for the header
UserRecord user = adapter.getItem(pos - 1);
if (user.isManageUsers || user.isAddSupervisedUser) {
mUserSwitcherCallback.showUnlockToContinueMessage();
}
if (!user.isCurrent) {
adapter.onUserListItemClicked(user);
}
mPopup.dismiss();
mPopup = null;
});
mPopup.show();
});
}
@@ -1122,6 +1119,10 @@ public class KeyguardSecurityContainer extends ConstraintLayout {
constraintSet.applyTo(mView);
}
}
interface UserSwitcherCallback {
void showUnlockToContinueMessage();
}
}
/**

View File

@@ -620,7 +620,9 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
mode = KeyguardSecurityContainer.MODE_ONE_HANDED;
}
mView.initMode(mode, mGlobalSettings, mFalsingManager, mUserSwitcherController);
mView.initMode(mode, mGlobalSettings, mFalsingManager, mUserSwitcherController,
() -> showMessage(getContext().getString(R.string.keyguard_unlock_to_continue),
null));
}
public void reportFailedUnlockAttempt(int userId, int timeoutMs) {

View File

@@ -35,8 +35,8 @@ protected constructor(
protected val controller: UserSwitcherController,
) : BaseAdapter() {
protected open val users: ArrayList<UserRecord>
get() = controller.users
protected open val users: List<UserRecord>
get() = controller.users.filter { !controller.isKeyguardShowing || !it.isRestricted }
init {
controller.addAdapter(WeakReference(this))
@@ -112,6 +112,7 @@ protected constructor(
item.isGuest,
item.isAddSupervisedUser,
isTablet,
item.isManageUsers,
)
return checkNotNull(context.getDrawable(iconRes))
}

View File

@@ -53,6 +53,7 @@ import com.android.systemui.user.data.source.UserRecord;
import com.android.systemui.util.ViewController;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
@@ -456,7 +457,7 @@ public class KeyguardUserSwitcherController extends ViewController<KeyguardUserS
}
void refreshUserOrder() {
ArrayList<UserRecord> users = super.getUsers();
List<UserRecord> users = super.getUsers();
mUsersOrdered = new ArrayList<>(users.size());
for (int i = 0; i < users.size(); i++) {
UserRecord record = users.get(i);

View File

@@ -249,7 +249,7 @@ constructor(
override fun startActivity(intent: Intent) {
if (useInteractor) {
activityStarter.startActivity(intent, /* dismissShade= */ false)
activityStarter.startActivity(intent, /* dismissShade= */ true)
} else {
_oldImpl.startActivity(intent)
}

View File

@@ -49,6 +49,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.util.LatencyTracker;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.settingslib.users.UserCreatingDialog;
import com.android.systemui.GuestResetOrExitSessionReceiver;
import com.android.systemui.GuestResumeSessionReceiver;
@@ -399,6 +400,16 @@ public class UserSwitcherControllerOldImpl implements UserSwitcherController {
records.add(userRecord);
}
if (canManageUsers()) {
records.add(LegacyUserDataHelper.createRecord(
mContext,
KeyguardUpdateMonitor.getCurrentUser(),
UserActionModel.NAVIGATE_TO_USER_MANAGEMENT,
/* isRestricted= */ false,
/* isSwitchToEnabled= */ true
));
}
mUiExecutor.execute(() -> {
if (records != null) {
mUsers = records;
@@ -438,6 +449,14 @@ public class UserSwitcherControllerOldImpl implements UserSwitcherController {
&& mUserManager.canAddMoreUsers(UserManager.USER_TYPE_FULL_SECONDARY);
}
@VisibleForTesting
boolean canManageUsers() {
UserInfo currentUser = mUserTracker.getUserInfo();
return mUserSwitcherEnabled
&& ((currentUser != null && currentUser.isAdmin())
|| mAddUsersFromLockScreen.getValue());
}
private boolean createIsRestricted() {
return !mAddUsersFromLockScreen.getValue();
}
@@ -525,6 +544,8 @@ public class UserSwitcherControllerOldImpl implements UserSwitcherController {
showAddUserDialog(dialogShower);
} else if (record.isAddSupervisedUser) {
startSupervisedUserActivity();
} else if (record.isManageUsers) {
startActivity(new Intent(Settings.ACTION_USER_SETTINGS));
} else {
onUserListItemClicked(record.info.id, record, dialogShower);
}
@@ -984,7 +1005,7 @@ public class UserSwitcherControllerOldImpl implements UserSwitcherController {
@Override
public void startActivity(Intent intent) {
mActivityStarter.startActivity(intent, true);
mActivityStarter.startActivity(intent, /* dismissShade= */ true);
}
@Override

View File

@@ -47,6 +47,9 @@ data class UserRecord(
* If not disabled, this is `null`.
*/
@JvmField val enforcedAdmin: RestrictedLockUtils.EnforcedAdmin? = null,
/** Whether this record is to go to the Settings page to manage users. */
@JvmField val isManageUsers: Boolean = false
) {
/** Returns a new instance of [UserRecord] with its [isCurrent] set to the given value. */
fun copyWithIsCurrent(isCurrent: Boolean): UserRecord {

View File

@@ -82,6 +82,15 @@ object UserActionsUtil {
)
}
fun canManageUsers(
repository: UserRepository,
isUserSwitcherEnabled: Boolean,
isAddUsersFromLockScreenEnabled: Boolean,
): Boolean {
return isUserSwitcherEnabled &&
(repository.getSelectedUserInfo().isAdmin || isAddUsersFromLockScreenEnabled)
}
/**
* Returns `true` if the current user is allowed to add users to the device; `false` otherwise.
*/

View File

@@ -102,6 +102,7 @@ constructor(
interface UserCallback {
/** Returns `true` if this callback can be cleaned-up. */
fun isEvictable(): Boolean = false
/** Notifies that the state of users on the device has changed. */
fun onUserStateChanged()
}
@@ -164,10 +165,11 @@ constructor(
get() =
if (isNewImpl) {
combine(
repository.selectedUserInfo,
repository.userInfos,
repository.userSwitcherSettings,
keyguardInteractor.isKeyguardShowing,
) { userInfos, settings, isDeviceLocked ->
) { _, userInfos, settings, isDeviceLocked ->
buildList {
val hasGuestUser = userInfos.any { it.isGuest }
if (
@@ -183,35 +185,45 @@ constructor(
add(UserActionModel.ENTER_GUEST_MODE)
}
if (isDeviceLocked && !settings.isAddUsersFromLockscreen) {
if (!isDeviceLocked || settings.isAddUsersFromLockscreen) {
// The device is locked and our setting to allow actions that add users
// from the lock-screen is not enabled. The guest action from above is
// always allowed, even when the device is locked, but the various "add
// user" actions below are not. We can finish building the list here.
return@buildList
val canCreateUsers =
UserActionsUtil.canCreateUser(
manager,
repository,
settings.isUserSwitcherEnabled,
settings.isAddUsersFromLockscreen,
)
if (canCreateUsers) {
add(UserActionModel.ADD_USER)
}
if (
UserActionsUtil.canCreateSupervisedUser(
manager,
repository,
settings.isUserSwitcherEnabled,
settings.isAddUsersFromLockscreen,
supervisedUserPackageName,
)
) {
add(UserActionModel.ADD_SUPERVISED_USER)
}
}
if (
UserActionsUtil.canCreateUser(
manager,
UserActionsUtil.canManageUsers(
repository,
settings.isUserSwitcherEnabled,
settings.isAddUsersFromLockscreen,
)
) {
add(UserActionModel.ADD_USER)
}
if (
UserActionsUtil.canCreateSupervisedUser(
manager,
repository,
settings.isUserSwitcherEnabled,
settings.isAddUsersFromLockscreen,
supervisedUserPackageName,
)
) {
add(UserActionModel.ADD_SUPERVISED_USER)
add(UserActionModel.NAVIGATE_TO_USER_MANAGEMENT)
}
}
}
@@ -264,7 +276,10 @@ constructor(
toRecord(
action = it,
selectedUserId = selectedUserInfo.id,
isAddFromLockscreenEnabled = settings.isAddUsersFromLockscreen,
isRestricted =
it != UserActionModel.ENTER_GUEST_MODE &&
it != UserActionModel.NAVIGATE_TO_USER_MANAGEMENT &&
!settings.isAddUsersFromLockscreen,
)
}
)
@@ -482,12 +497,12 @@ constructor(
.setAction(UserManager.ACTION_CREATE_SUPERVISED_USER)
.setPackage(supervisedUserPackageName)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
/* dismissShade= */ false,
/* dismissShade= */ true,
)
UserActionModel.NAVIGATE_TO_USER_MANAGEMENT ->
activityStarter.startActivity(
Intent(Settings.ACTION_USER_SETTINGS),
/* dismissShade= */ false,
/* dismissShade= */ true,
)
}
} else {
@@ -575,20 +590,13 @@ constructor(
private suspend fun toRecord(
action: UserActionModel,
selectedUserId: Int,
isAddFromLockscreenEnabled: Boolean,
isRestricted: Boolean,
): UserRecord {
return LegacyUserDataHelper.createRecord(
context = applicationContext,
selectedUserId = selectedUserId,
actionType = action,
isRestricted =
if (action == UserActionModel.ENTER_GUEST_MODE) {
// Entering guest mode is never restricted, so it's allowed to happen from the
// lockscreen even if the "add from lockscreen" system setting is off.
false
} else {
!isAddFromLockscreenEnabled
},
isRestricted = isRestricted,
isSwitchToEnabled =
canSwitchUsers(selectedUserId) &&
// If the user is auto-created is must not be currently resetting.

View File

@@ -80,6 +80,7 @@ object LegacyUserDataHelper {
context = context,
selectedUserId = selectedUserId,
),
isManageUsers = actionType == UserActionModel.NAVIGATE_TO_USER_MANAGEMENT,
)
}
@@ -90,6 +91,7 @@ object LegacyUserDataHelper {
record.isAddUser -> UserActionModel.ADD_USER
record.isAddSupervisedUser -> UserActionModel.ADD_SUPERVISED_USER
record.isGuest -> UserActionModel.ENTER_GUEST_MODE
record.isManageUsers -> UserActionModel.NAVIGATE_TO_USER_MANAGEMENT
else -> error("Not a known action: $record")
}
}

View File

@@ -39,6 +39,7 @@ object LegacyUserUiHelper {
isGuest: Boolean,
isAddSupervisedUser: Boolean,
isTablet: Boolean = false,
isManageUsers: Boolean,
): Int {
return if (isAddUser && isTablet) {
R.drawable.ic_account_circle_filled
@@ -48,6 +49,8 @@ object LegacyUserUiHelper {
R.drawable.ic_account_circle
} else if (isAddSupervisedUser) {
R.drawable.ic_add_supervised_user
} else if (isManageUsers) {
R.drawable.ic_manage_users
} else {
R.drawable.ic_avatar_user
}
@@ -74,6 +77,7 @@ object LegacyUserUiHelper {
isAddUser = record.isAddUser,
isAddSupervisedUser = record.isAddSupervisedUser,
isTablet = isTablet,
isManageUsers = record.isManageUsers,
)
)
}
@@ -103,8 +107,9 @@ object LegacyUserUiHelper {
isAddUser: Boolean,
isAddSupervisedUser: Boolean,
isTablet: Boolean = false,
isManageUsers: Boolean,
): Int {
check(isGuest || isAddUser || isAddSupervisedUser)
check(isGuest || isAddUser || isAddSupervisedUser || isManageUsers)
return when {
isGuest && isGuestUserAutoCreated && isGuestUserResetting ->
@@ -114,6 +119,7 @@ object LegacyUserUiHelper {
isGuest -> com.android.internal.R.string.guest_name
isAddUser -> com.android.settingslib.R.string.user_add_user
isAddSupervisedUser -> R.string.add_user_supervised
isManageUsers -> R.string.manage_users
else -> error("This should never happen!")
}
}

View File

@@ -19,8 +19,6 @@ package com.android.systemui.user.ui.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.android.systemui.R
import com.android.systemui.common.shared.model.Text
import com.android.systemui.common.ui.drawable.CircularDrawable
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
@@ -162,12 +160,7 @@ private constructor(
): UserViewModel {
return UserViewModel(
viewKey = model.id,
name =
if (model.isGuest) {
Text.Resource(com.android.settingslib.R.string.guest_exit_quick_settings_button)
} else {
model.name
},
name = model.name,
image = CircularDrawable(model.image),
isSelectionMarkerVisible = model.isSelected,
alpha =
@@ -186,29 +179,23 @@ private constructor(
return UserActionViewModel(
viewKey = model.ordinal.toLong(),
iconResourceId =
if (model == UserActionModel.NAVIGATE_TO_USER_MANAGEMENT) {
R.drawable.ic_manage_users
} else {
LegacyUserUiHelper.getUserSwitcherActionIconResourceId(
isAddSupervisedUser = model == UserActionModel.ADD_SUPERVISED_USER,
isAddUser = model == UserActionModel.ADD_USER,
isGuest = model == UserActionModel.ENTER_GUEST_MODE,
isTablet = true,
)
},
LegacyUserUiHelper.getUserSwitcherActionIconResourceId(
isAddSupervisedUser = model == UserActionModel.ADD_SUPERVISED_USER,
isAddUser = model == UserActionModel.ADD_USER,
isGuest = model == UserActionModel.ENTER_GUEST_MODE,
isManageUsers = model == UserActionModel.NAVIGATE_TO_USER_MANAGEMENT,
isTablet = true,
),
textResourceId =
if (model == UserActionModel.NAVIGATE_TO_USER_MANAGEMENT) {
R.string.manage_users
} else {
LegacyUserUiHelper.getUserSwitcherActionTextResourceId(
isGuest = model == UserActionModel.ENTER_GUEST_MODE,
isGuestUserAutoCreated = guestUserInteractor.isGuestUserAutoCreated,
isGuestUserResetting = guestUserInteractor.isGuestUserResetting,
isAddSupervisedUser = model == UserActionModel.ADD_SUPERVISED_USER,
isAddUser = model == UserActionModel.ADD_USER,
isTablet = true,
)
},
LegacyUserUiHelper.getUserSwitcherActionTextResourceId(
isGuest = model == UserActionModel.ENTER_GUEST_MODE,
isGuestUserAutoCreated = guestUserInteractor.isGuestUserAutoCreated,
isGuestUserResetting = guestUserInteractor.isGuestUserResetting,
isAddSupervisedUser = model == UserActionModel.ADD_SUPERVISED_USER,
isAddUser = model == UserActionModel.ADD_USER,
isManageUsers = model == UserActionModel.NAVIGATE_TO_USER_MANAGEMENT,
isTablet = true,
),
onClicked = {
userInteractor.executeAction(action = model)
// We don't finish because we want to show a dialog over the full-screen UI and

View File

@@ -221,15 +221,17 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
public void onResourcesUpdate_callsThroughOnRotationChange() {
// Rotation is the same, shouldn't cause an update
mKeyguardSecurityContainerController.updateResources();
verify(mView, never()).initMode(MODE_DEFAULT, mGlobalSettings, mFalsingManager,
mUserSwitcherController);
verify(mView, never()).initMode(eq(MODE_DEFAULT), eq(mGlobalSettings), eq(mFalsingManager),
eq(mUserSwitcherController),
any(KeyguardSecurityContainer.UserSwitcherViewMode.UserSwitcherCallback.class));
// Update rotation. Should trigger update
mConfiguration.orientation = Configuration.ORIENTATION_LANDSCAPE;
mKeyguardSecurityContainerController.updateResources();
verify(mView).initMode(MODE_DEFAULT, mGlobalSettings, mFalsingManager,
mUserSwitcherController);
verify(mView).initMode(eq(MODE_DEFAULT), eq(mGlobalSettings), eq(mFalsingManager),
eq(mUserSwitcherController),
any(KeyguardSecurityContainer.UserSwitcherViewMode.UserSwitcherCallback.class));
}
private void touchDown() {
@@ -263,8 +265,9 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
.thenReturn((KeyguardInputViewController) mKeyguardPasswordViewController);
mKeyguardSecurityContainerController.showSecurityScreen(SecurityMode.Pattern);
verify(mView).initMode(MODE_DEFAULT, mGlobalSettings, mFalsingManager,
mUserSwitcherController);
verify(mView).initMode(eq(MODE_DEFAULT), eq(mGlobalSettings), eq(mFalsingManager),
eq(mUserSwitcherController),
any(KeyguardSecurityContainer.UserSwitcherViewMode.UserSwitcherCallback.class));
}
@Test
@@ -275,8 +278,9 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
.thenReturn((KeyguardInputViewController) mKeyguardPasswordViewController);
mKeyguardSecurityContainerController.showSecurityScreen(SecurityMode.Pattern);
verify(mView).initMode(MODE_ONE_HANDED, mGlobalSettings, mFalsingManager,
mUserSwitcherController);
verify(mView).initMode(eq(MODE_ONE_HANDED), eq(mGlobalSettings), eq(mFalsingManager),
eq(mUserSwitcherController),
any(KeyguardSecurityContainer.UserSwitcherViewMode.UserSwitcherCallback.class));
}
@Test
@@ -285,8 +289,26 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
setupGetSecurityView();
mKeyguardSecurityContainerController.showSecurityScreen(SecurityMode.Password);
verify(mView).initMode(MODE_DEFAULT, mGlobalSettings, mFalsingManager,
mUserSwitcherController);
verify(mView).initMode(eq(MODE_DEFAULT), eq(mGlobalSettings), eq(mFalsingManager),
eq(mUserSwitcherController),
any(KeyguardSecurityContainer.UserSwitcherViewMode.UserSwitcherCallback.class));
}
@Test
public void addUserSwitcherCallback() {
ArgumentCaptor<KeyguardSecurityContainer.UserSwitcherViewMode.UserSwitcherCallback>
captor = ArgumentCaptor.forClass(
KeyguardSecurityContainer.UserSwitcherViewMode.UserSwitcherCallback.class);
setupGetSecurityView();
mKeyguardSecurityContainerController.showSecurityScreen(SecurityMode.Password);
verify(mView).initMode(anyInt(), any(GlobalSettings.class), any(FalsingManager.class),
any(UserSwitcherController.class),
captor.capture());
captor.getValue().showUnlockToContinueMessage();
verify(mKeyguardPasswordViewControllerMock).showMessage(
getContext().getString(R.string.keyguard_unlock_to_continue), null);
}
@Test

View File

@@ -119,7 +119,7 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase {
int systemBarInsetAmount = 0;
mKeyguardSecurityContainer.initMode(MODE_DEFAULT, mGlobalSettings, mFalsingManager,
mUserSwitcherController);
mUserSwitcherController, () -> {});
Insets imeInset = Insets.of(0, 0, 0, imeInsetAmount);
Insets systemBarInset = Insets.of(0, 0, 0, systemBarInsetAmount);
@@ -141,7 +141,7 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase {
int systemBarInsetAmount = paddingBottom + 1;
mKeyguardSecurityContainer.initMode(MODE_DEFAULT, mGlobalSettings, mFalsingManager,
mUserSwitcherController);
mUserSwitcherController, () -> {});
Insets imeInset = Insets.of(0, 0, 0, imeInsetAmount);
Insets systemBarInset = Insets.of(0, 0, 0, systemBarInsetAmount);
@@ -158,9 +158,10 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase {
@Test
public void testDefaultViewMode() {
mKeyguardSecurityContainer.initMode(MODE_ONE_HANDED, mGlobalSettings, mFalsingManager,
mUserSwitcherController);
mUserSwitcherController, () -> {
});
mKeyguardSecurityContainer.initMode(MODE_DEFAULT, mGlobalSettings, mFalsingManager,
mUserSwitcherController);
mUserSwitcherController, () -> {});
ConstraintSet.Constraint viewFlipperConstraint =
getViewConstraint(mSecurityViewFlipper.getId());
assertThat(viewFlipperConstraint.layout.topToTop).isEqualTo(PARENT_ID);
@@ -377,7 +378,7 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase {
private void setupUserSwitcher() {
when(mGlobalSettings.getInt(any(), anyInt())).thenReturn(ONE_HANDED_KEYGUARD_SIDE_RIGHT);
mKeyguardSecurityContainer.initMode(KeyguardSecurityContainer.MODE_USER_SWITCHER,
mGlobalSettings, mFalsingManager, mUserSwitcherController);
mGlobalSettings, mFalsingManager, mUserSwitcherController, () -> {});
}
private ArrayList<UserRecord> buildUserRecords(int count) {
@@ -387,7 +388,8 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase {
0 /* flags */);
users.add(new UserRecord(info, null, false /* isGuest */, false /* isCurrent */,
false /* isAddUser */, false /* isRestricted */, true /* isSwitchToEnabled */,
false /* isAddSupervisedUser */, null /* enforcedAdmin */));
false /* isAddSupervisedUser */, null /* enforcedAdmin */,
false /* isManageUsers */));
}
return users;
}
@@ -395,7 +397,7 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase {
private void setupForUpdateKeyguardPosition(boolean oneHandedMode) {
int mode = oneHandedMode ? MODE_ONE_HANDED : MODE_DEFAULT;
mKeyguardSecurityContainer.initMode(mode, mGlobalSettings, mFalsingManager,
mUserSwitcherController);
mUserSwitcherController, () -> {});
}
/** Get the ConstraintLayout constraint of the view. */

View File

@@ -57,14 +57,18 @@ import com.android.systemui.settings.UserTracker
import com.android.systemui.shade.NotificationShadeWindowView
import com.android.systemui.telephony.TelephonyListenerManager
import com.android.systemui.user.data.source.UserRecord
import com.android.systemui.user.legacyhelper.data.LegacyUserDataHelper
import com.android.systemui.user.shared.model.UserActionModel
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.argumentCaptor
import com.android.systemui.util.mockito.capture
import com.android.systemui.util.mockito.kotlinArgumentCaptor
import com.android.systemui.util.mockito.nullable
import com.android.systemui.util.settings.GlobalSettings
import com.android.systemui.util.settings.SecureSettings
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotNull
@@ -123,7 +127,7 @@ class UserSwitcherControllerOldImplTest : SysuiTestCase() {
private val ownerId = UserHandle.USER_SYSTEM
private val ownerInfo = UserInfo(ownerId, "Owner", null,
UserInfo.FLAG_ADMIN or UserInfo.FLAG_FULL or UserInfo.FLAG_INITIALIZED or
UserInfo.FLAG_PRIMARY or UserInfo.FLAG_SYSTEM,
UserInfo.FLAG_PRIMARY or UserInfo.FLAG_SYSTEM or UserInfo.FLAG_ADMIN,
UserManager.USER_TYPE_FULL_SYSTEM)
private val guestId = 1234
private val guestInfo = UserInfo(guestId, "Guest", null,
@@ -596,6 +600,76 @@ class UserSwitcherControllerOldImplTest : SysuiTestCase() {
assertFalse(userSwitcherController.canCreateSupervisedUser())
}
@Test
fun testCanManageUser_userSwitcherEnabled_addUserWhenLocked() {
`when`(
globalSettings.getIntForUser(
eq(Settings.Global.USER_SWITCHER_ENABLED),
anyInt(),
eq(UserHandle.USER_SYSTEM)
)
).thenReturn(1)
`when`(
globalSettings.getIntForUser(
eq(Settings.Global.ADD_USERS_WHEN_LOCKED),
anyInt(),
eq(UserHandle.USER_SYSTEM)
)
).thenReturn(1)
setupController()
assertTrue(userSwitcherController.canManageUsers())
}
@Test
fun testCanManageUser_userSwitcherDisabled_addUserWhenLocked() {
`when`(
globalSettings.getIntForUser(
eq(Settings.Global.USER_SWITCHER_ENABLED),
anyInt(),
eq(UserHandle.USER_SYSTEM)
)
).thenReturn(0)
`when`(
globalSettings.getIntForUser(
eq(Settings.Global.ADD_USERS_WHEN_LOCKED),
anyInt(),
eq(UserHandle.USER_SYSTEM)
)
).thenReturn(1)
setupController()
assertFalse(userSwitcherController.canManageUsers())
}
@Test
fun testCanManageUser_userSwitcherEnabled_isAdmin() {
`when`(
globalSettings.getIntForUser(
eq(Settings.Global.USER_SWITCHER_ENABLED),
anyInt(),
eq(UserHandle.USER_SYSTEM)
)
).thenReturn(1)
setupController()
assertTrue(userSwitcherController.canManageUsers())
}
@Test
fun testCanManageUser_userSwitcherDisabled_isAdmin() {
`when`(
globalSettings.getIntForUser(
eq(Settings.Global.USER_SWITCHER_ENABLED),
anyInt(),
eq(UserHandle.USER_SYSTEM)
)
).thenReturn(0)
setupController()
assertFalse(userSwitcherController.canManageUsers())
}
@Test
fun addUserSwitchCallback() {
val broadcastReceiverCaptor = argumentCaptor<BroadcastReceiver>()
@@ -632,4 +706,22 @@ class UserSwitcherControllerOldImplTest : SysuiTestCase() {
bgExecutor.runAllReady()
verify(userManager).createGuest(context)
}
@Test
fun onUserItemClicked_manageUsers() {
val manageUserRecord = LegacyUserDataHelper.createRecord(
mContext,
ownerId,
UserActionModel.NAVIGATE_TO_USER_MANAGEMENT,
isRestricted = false,
isSwitchToEnabled = true
)
userSwitcherController.onUserListItemClicked(manageUserRecord, null)
val intentCaptor = kotlinArgumentCaptor<Intent>()
verify(activityStarter).startActivity(intentCaptor.capture(),
eq(true)
)
Truth.assertThat(intentCaptor.value.action).isEqualTo(Settings.ACTION_USER_SETTINGS)
}
}

View File

@@ -202,6 +202,7 @@ class UserInteractorRefactoredTest : UserInteractorTest() {
fun `actions - device unlocked`() =
runBlocking(IMMEDIATE) {
val userInfos = createUserInfos(count = 2, includeGuest = false)
userRepository.setUserInfos(userInfos)
userRepository.setSelectedUserInfo(userInfos[0])
userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
@@ -215,6 +216,7 @@ class UserInteractorRefactoredTest : UserInteractorTest() {
UserActionModel.ENTER_GUEST_MODE,
UserActionModel.ADD_USER,
UserActionModel.ADD_SUPERVISED_USER,
UserActionModel.NAVIGATE_TO_USER_MANAGEMENT,
)
)
@@ -276,6 +278,7 @@ class UserInteractorRefactoredTest : UserInteractorTest() {
UserActionModel.ENTER_GUEST_MODE,
UserActionModel.ADD_USER,
UserActionModel.ADD_SUPERVISED_USER,
UserActionModel.NAVIGATE_TO_USER_MANAGEMENT,
)
)
@@ -283,7 +286,7 @@ class UserInteractorRefactoredTest : UserInteractorTest() {
}
@Test
fun `actions - device locked - only guest action is shown`() =
fun `actions - device locked - only guest action and manage user is shown`() =
runBlocking(IMMEDIATE) {
val userInfos = createUserInfos(count = 2, includeGuest = false)
userRepository.setUserInfos(userInfos)
@@ -293,7 +296,13 @@ class UserInteractorRefactoredTest : UserInteractorTest() {
var value: List<UserActionModel>? = null
val job = underTest.actions.onEach { value = it }.launchIn(this)
assertThat(value).isEqualTo(listOf(UserActionModel.ENTER_GUEST_MODE))
assertThat(value)
.isEqualTo(
listOf(
UserActionModel.ENTER_GUEST_MODE,
UserActionModel.NAVIGATE_TO_USER_MANAGEMENT
)
)
job.cancel()
}
@@ -330,7 +339,7 @@ class UserInteractorRefactoredTest : UserInteractorTest() {
underTest.executeAction(UserActionModel.ADD_SUPERVISED_USER)
val intentCaptor = kotlinArgumentCaptor<Intent>()
verify(activityStarter).startActivity(intentCaptor.capture(), eq(false))
verify(activityStarter).startActivity(intentCaptor.capture(), eq(true))
assertThat(intentCaptor.value.action)
.isEqualTo(UserManager.ACTION_CREATE_SUPERVISED_USER)
assertThat(intentCaptor.value.`package`).isEqualTo(SUPERVISED_USER_CREATION_APP_PACKAGE)
@@ -342,7 +351,7 @@ class UserInteractorRefactoredTest : UserInteractorTest() {
underTest.executeAction(UserActionModel.NAVIGATE_TO_USER_MANAGEMENT)
val intentCaptor = kotlinArgumentCaptor<Intent>()
verify(activityStarter).startActivity(intentCaptor.capture(), eq(false))
verify(activityStarter).startActivity(intentCaptor.capture(), eq(true))
assertThat(intentCaptor.value.action).isEqualTo(Settings.ACTION_USER_SETTINGS)
}
@@ -561,6 +570,7 @@ class UserInteractorRefactoredTest : UserInteractorTest() {
UserActionModel.ENTER_GUEST_MODE,
UserActionModel.ADD_USER,
UserActionModel.ADD_SUPERVISED_USER,
UserActionModel.NAVIGATE_TO_USER_MANAGEMENT,
),
)
}
@@ -705,7 +715,7 @@ class UserInteractorRefactoredTest : UserInteractorTest() {
name,
/* iconPath= */ "",
/* flags= */ if (isPrimary) {
UserInfo.FLAG_PRIMARY
UserInfo.FLAG_PRIMARY or UserInfo.FLAG_ADMIN
} else {
0
},