sys user split: refactor systemui user switcher
BUG:19913735
Change-Id: I017dd1b03fd163c266b8080b969fb7a2e934e26c
diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index 4d9c176..cbd2f78 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -20,6 +20,7 @@
import android.os.Parcelable;
import android.os.SystemProperties;
import android.os.UserHandle;
+import android.os.UserManager;
/**
* Per-user information.
@@ -135,6 +136,15 @@
return !isManagedProfile() || SystemProperties.getBoolean("fw.show_hidden_users", false);
}
+ /**
+ * @return true if this user can be switched to by end user through UI.
+ */
+ public boolean supportsSwitchToByUser() {
+ // Hide the system user when it does not represent a human user.
+ boolean hideSystemUser = UserManager.isSplitSystemUser();
+ return (!hideSystemUser || id != UserHandle.USER_SYSTEM) && supportsSwitchTo();
+ }
+
public UserInfo() {
}
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index a43cf5a..0192ef5 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -15,6 +15,7 @@
*/
package android.os;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
@@ -522,6 +523,16 @@
}
/**
+ * @hide
+ * @return Whether the device is running with split system user. It means the system user and
+ * primary user are two separate users. Previously system user and primary user are combined as
+ * a single owner user. see @link {android.os.UserHandle#USER_OWNER}
+ */
+ public static boolean isSplitSystemUser() {
+ return SystemProperties.getBoolean("ro.fw.system_user_split", false);
+ }
+
+ /**
* Returns the user handle for the user that this process is running under.
*
* @return the user handle of this process.
@@ -986,7 +997,7 @@
* @return the Primary user, null if not found.
* @hide
*/
- public UserInfo getPrimaryUser() {
+ public @Nullable UserInfo getPrimaryUser() {
try {
return mService.getPrimaryUser();
} catch (RemoteException re) {
@@ -1293,7 +1304,7 @@
}
int switchableUserCount = 0;
for (UserInfo user : users) {
- if (user.supportsSwitchTo()) {
+ if (user.supportsSwitchToByUser()) {
++switchableUserCount;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index 41fc967..eec91db 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -79,7 +79,7 @@
private ArrayList<UserRecord> mUsers = new ArrayList<>();
private Dialog mExitGuestDialog;
private Dialog mAddUserDialog;
- private int mLastNonGuestUser = UserHandle.USER_OWNER;
+ private int mLastNonGuestUser = UserHandle.USER_SYSTEM;
private boolean mSimpleUserSwitcher;
private boolean mAddUsersWhenLocked;
@@ -95,7 +95,7 @@
filter.addAction(Intent.ACTION_USER_SWITCHED);
filter.addAction(Intent.ACTION_USER_STOPPING);
filter.addAction(ACTION_REMOVE_GUEST);
- mContext.registerReceiverAsUser(mReceiver, UserHandle.OWNER, filter,
+ mContext.registerReceiverAsUser(mReceiver, UserHandle.SYSTEM, filter,
null /* permission */, null /* scheduler */);
@@ -146,17 +146,21 @@
}
ArrayList<UserRecord> records = new ArrayList<>(infos.size());
int currentId = ActivityManager.getCurrentUser();
+ UserInfo currentUserInfo = null;
UserRecord guestRecord = null;
int avatarSize = mContext.getResources()
.getDimensionPixelSize(R.dimen.max_avatar_size);
for (UserInfo info : infos) {
boolean isCurrent = currentId == info.id;
+ if (isCurrent) {
+ currentUserInfo = info;
+ }
if (info.isGuest()) {
guestRecord = new UserRecord(info, null /* picture */,
true /* isGuest */, isCurrent, false /* isAddUser */,
false /* isRestricted */);
- } else if (info.supportsSwitchTo()) {
+ } else if (info.supportsSwitchToByUser()) {
Bitmap picture = bitmaps.get(info.id);
if (picture == null) {
picture = mUserManager.getUserIcon(info.id);
@@ -172,11 +176,13 @@
}
}
- boolean ownerCanCreateUsers = !mUserManager.hasUserRestriction(
- UserManager.DISALLOW_ADD_USER, UserHandle.OWNER);
- boolean currentUserCanCreateUsers =
- (currentId == UserHandle.USER_OWNER) && ownerCanCreateUsers;
- boolean anyoneCanCreateUsers = ownerCanCreateUsers && addUsersWhenLocked;
+ boolean systemCanCreateUsers = !mUserManager.hasUserRestriction(
+ UserManager.DISALLOW_ADD_USER, UserHandle.SYSTEM);
+ boolean currentUserCanCreateUsers = currentUserInfo != null
+ && (currentUserInfo.isAdmin()
+ || currentUserInfo.id == UserHandle.USER_SYSTEM)
+ && systemCanCreateUsers;
+ boolean anyoneCanCreateUsers = systemCanCreateUsers && addUsersWhenLocked;
boolean canCreateGuest = (currentUserCanCreateUsers || anyoneCanCreateUsers)
&& guestRecord == null;
boolean canCreateUser = (currentUserCanCreateUsers || anyoneCanCreateUsers)
@@ -284,10 +290,10 @@
}
private void exitGuest(int id) {
- int newId = UserHandle.USER_OWNER;
- if (mLastNonGuestUser != UserHandle.USER_OWNER) {
+ int newId = UserHandle.USER_SYSTEM;
+ if (mLastNonGuestUser != UserHandle.USER_SYSTEM) {
UserInfo info = mUserManager.getUserInfo(mLastNonGuestUser);
- if (info != null && info.isEnabled() && info.supportsSwitchTo()) {
+ if (info != null && info.isEnabled() && info.supportsSwitchToByUser()) {
newId = info.id;
}
}
@@ -325,6 +331,7 @@
}
final int currentId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
+ final UserInfo userInfo = mUserManager.getUserInfo(currentId);
final int N = mUsers.size();
for (int i = 0; i < N; i++) {
UserRecord record = mUsers.get(i);
@@ -336,7 +343,7 @@
if (shouldBeCurrent && !record.isGuest) {
mLastNonGuestUser = record.info.id;
}
- if (currentId != UserHandle.USER_OWNER && record.isRestricted) {
+ if ((userInfo == null || !userInfo.isAdmin()) && record.isRestricted) {
// Immediately remove restricted records in case the AsyncTask is too slow.
mUsers.remove(i);
i--;
@@ -354,7 +361,7 @@
private void showGuestNotification(int guestUserId) {
PendingIntent removeGuestPI = PendingIntent.getBroadcastAsUser(mContext,
- 0, new Intent(ACTION_REMOVE_GUEST), 0, UserHandle.OWNER);
+ 0, new Intent(ACTION_REMOVE_GUEST), 0, UserHandle.SYSTEM);
Notification notification = new Notification.Builder(mContext)
.setVisibility(Notification.VISIBILITY_SECRET)
.setPriority(Notification.PRIORITY_MIN)
diff --git a/services/core/java/com/android/server/policy/GlobalActions.java b/services/core/java/com/android/server/policy/GlobalActions.java
index 3cee927..d160221f 100644
--- a/services/core/java/com/android/server/policy/GlobalActions.java
+++ b/services/core/java/com/android/server/policy/GlobalActions.java
@@ -534,7 +534,7 @@
List<UserInfo> users = um.getUsers();
UserInfo currentUser = getCurrentUser();
for (final UserInfo user : users) {
- if (user.supportsSwitchTo()) {
+ if (user.supportsSwitchToByUser()) {
boolean isCurrentUser = currentUser == null
? user.id == 0 : (currentUser.id == user.id);
Drawable icon = user.iconPath != null ? Drawable.createFromPath(user.iconPath)
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 15da829..07fc23f 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -227,7 +227,7 @@
for (UserInfo userInfo : userInfos) {
if (userInfo == null || userInfo.partial || !userInfo.isEnabled()
|| userInfo.guestToRemove) continue;
- if (!userInfo.supportsSwitchTo()) continue;
+ if (!userInfo.supportsSwitchToByUser()) continue;
if (!mActivityManager.isUserRunning(userInfo.id)) continue;
if (!lockPatternUtils.isSecure(userInfo.id)) continue;
if (!getUserHasAuthenticated(userInfo.id)) continue;
@@ -316,7 +316,7 @@
UserInfo info = userInfos.get(i);
if (info == null || info.partial || !info.isEnabled() || info.guestToRemove
- || !info.supportsSwitchTo()) {
+ || !info.supportsSwitchToByUser()) {
continue;
}
@@ -783,7 +783,7 @@
private void dumpUser(PrintWriter fout, UserInfo user, boolean isCurrent) {
fout.printf(" User \"%s\" (id=%d, flags=%#x)",
user.name, user.id, user.flags);
- if (!user.supportsSwitchTo()) {
+ if (!user.supportsSwitchToByUser()) {
fout.println("(managed profile)");
fout.println(" disabled because switching to this user is not possible.");
return;