Merge "[Bouncer] Add manage users to bouncer." into tm-qpr-dev
diff --git a/packages/SystemUI/res-keyguard/values/strings.xml b/packages/SystemUI/res-keyguard/values/strings.xml
index d90156d..8135aaa 100644
--- a/packages/SystemUI/res-keyguard/values/strings.xml
+++ b/packages/SystemUI/res-keyguard/values/strings.xml
@@ -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>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index c34db15..93ee151 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -67,7 +67,6 @@
 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 @@
     }
 
     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 @@
                 mViewMode = new OneHandedViewMode();
                 break;
             case MODE_USER_SWITCHER:
-                mViewMode = new UserSwitcherViewMode();
+                mViewMode = new UserSwitcherViewMode(userSwitcherCallback);
                 break;
             default:
                 mViewMode = new DefaultViewMode();
@@ -864,6 +864,12 @@
         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 @@
                 }
             };
 
-            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 @@
                 constraintSet.applyTo(mView);
             }
         }
+
+        interface UserSwitcherCallback {
+            void showUnlockToContinueMessage();
+        }
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
index d448f40..bcd1a1e 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
@@ -620,7 +620,9 @@
             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) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseUserSwitcherAdapter.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseUserSwitcherAdapter.kt
index 5b2d695..2f0ebf7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseUserSwitcherAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseUserSwitcherAdapter.kt
@@ -35,8 +35,8 @@
     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 @@
                     item.isGuest,
                     item.isAddSupervisedUser,
                     isTablet,
+                    item.isManageUsers,
                 )
             return checkNotNull(context.getDrawable(iconRes))
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java
index 494a4bb..c150654 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java
@@ -53,6 +53,7 @@
 import com.android.systemui.util.ViewController;
 
 import java.util.ArrayList;
+import java.util.List;
 
 import javax.inject.Inject;
 
@@ -456,7 +457,7 @@
         }
 
         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);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherControllerImpl.kt
index af39eee..935fc7f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherControllerImpl.kt
@@ -249,7 +249,7 @@
 
     override fun startActivity(intent: Intent) {
         if (useInteractor) {
-            activityStarter.startActivity(intent, /* dismissShade= */ false)
+            activityStarter.startActivity(intent, /* dismissShade= */ true)
         } else {
             _oldImpl.startActivity(intent)
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherControllerOldImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherControllerOldImpl.java
index 46d2f3a..c294c37 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherControllerOldImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherControllerOldImpl.java
@@ -49,6 +49,7 @@
 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 @@
                 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 @@
                 && 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 @@
             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 @@
 
     @Override
     public void startActivity(Intent intent) {
-        mActivityStarter.startActivity(intent, true);
+        mActivityStarter.startActivity(intent, /* dismissShade= */ true);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/user/data/source/UserRecord.kt b/packages/SystemUI/src/com/android/systemui/user/data/source/UserRecord.kt
index 9370286..d4fb563 100644
--- a/packages/SystemUI/src/com/android/systemui/user/data/source/UserRecord.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/data/source/UserRecord.kt
@@ -47,6 +47,9 @@
      * 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 {
diff --git a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserActionsUtil.kt b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserActionsUtil.kt
index 1b4746a..dc004f3 100644
--- a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserActionsUtil.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserActionsUtil.kt
@@ -82,6 +82,15 @@
         )
     }
 
+    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.
      */
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 142a328..ba5a82a 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
@@ -102,6 +102,7 @@
     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 @@
         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 @@
                             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 @@
                                 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 @@
                             .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 @@
     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.
diff --git a/packages/SystemUI/src/com/android/systemui/user/legacyhelper/data/LegacyUserDataHelper.kt b/packages/SystemUI/src/com/android/systemui/user/legacyhelper/data/LegacyUserDataHelper.kt
index 137de15..03a7470 100644
--- a/packages/SystemUI/src/com/android/systemui/user/legacyhelper/data/LegacyUserDataHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/legacyhelper/data/LegacyUserDataHelper.kt
@@ -80,6 +80,7 @@
                     context = context,
                     selectedUserId = selectedUserId,
                 ),
+            isManageUsers = actionType == UserActionModel.NAVIGATE_TO_USER_MANAGEMENT,
         )
     }
 
@@ -90,6 +91,7 @@
             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")
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/user/legacyhelper/ui/LegacyUserUiHelper.kt b/packages/SystemUI/src/com/android/systemui/user/legacyhelper/ui/LegacyUserUiHelper.kt
index 12641a8..e74232d 100644
--- a/packages/SystemUI/src/com/android/systemui/user/legacyhelper/ui/LegacyUserUiHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/legacyhelper/ui/LegacyUserUiHelper.kt
@@ -39,6 +39,7 @@
         isGuest: Boolean,
         isAddSupervisedUser: Boolean,
         isTablet: Boolean = false,
+        isManageUsers: Boolean,
     ): Int {
         return if (isAddUser && isTablet) {
             R.drawable.ic_account_circle_filled
@@ -48,6 +49,8 @@
             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 @@
                         isAddUser = record.isAddUser,
                         isAddSupervisedUser = record.isAddSupervisedUser,
                         isTablet = isTablet,
+                        isManageUsers = record.isManageUsers,
                     )
                 )
         }
@@ -103,8 +107,9 @@
         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 @@
             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!")
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModel.kt b/packages/SystemUI/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModel.kt
index 9c58853..219dae2 100644
--- a/packages/SystemUI/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModel.kt
@@ -19,8 +19,6 @@
 
 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 @@
     ): 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 @@
         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
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
index c6ebaa8..48e8239 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
@@ -221,15 +221,17 @@
     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 @@
                 .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 @@
                 .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 @@
         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
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
index 52f8825..82d3ca7 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
@@ -119,7 +119,7 @@
         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 @@
         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 @@
     @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 @@
     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 @@
                     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 @@
     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. */
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerOldImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerOldImplTest.kt
index 76ecc1c..169f4fb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerOldImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerOldImplTest.kt
@@ -57,14 +57,18 @@
 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 @@
     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,
@@ -597,6 +601,76 @@
     }
 
     @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>()
         verify(broadcastDispatcher).registerReceiver(
@@ -632,4 +706,22 @@
         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)
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorRefactoredTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorRefactoredTest.kt
index 37c378c..1540f85 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorRefactoredTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorRefactoredTest.kt
@@ -202,6 +202,7 @@
     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 @@
                         UserActionModel.ENTER_GUEST_MODE,
                         UserActionModel.ADD_USER,
                         UserActionModel.ADD_SUPERVISED_USER,
+                        UserActionModel.NAVIGATE_TO_USER_MANAGEMENT,
                     )
                 )
 
@@ -276,6 +278,7 @@
                         UserActionModel.ENTER_GUEST_MODE,
                         UserActionModel.ADD_USER,
                         UserActionModel.ADD_SUPERVISED_USER,
+                        UserActionModel.NAVIGATE_TO_USER_MANAGEMENT,
                     )
                 )
 
@@ -283,7 +286,7 @@
         }
 
     @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 @@
             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 @@
             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 @@
             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 @@
                         UserActionModel.ENTER_GUEST_MODE,
                         UserActionModel.ADD_USER,
                         UserActionModel.ADD_SUPERVISED_USER,
+                        UserActionModel.NAVIGATE_TO_USER_MANAGEMENT,
                     ),
             )
         }
@@ -705,7 +715,7 @@
             name,
             /* iconPath= */ "",
             /* flags= */ if (isPrimary) {
-                UserInfo.FLAG_PRIMARY
+                UserInfo.FLAG_PRIMARY or UserInfo.FLAG_ADMIN
             } else {
                 0
             },