UserInfo: FULL and SYSTEM flags
Introduces two new UserInfo flags:
SYSTEM - refers to the system user, i.e. user 0. Although
UserManagerService already knows which user is the system, this flag
will be useful in other contexts.
FULL - refers to a non-profile human user.
Right now, for every user, one of the following flag combos are true:
SYSTEM (user 0 on a headless-user-0 device)
SYSTEM | FULL (user 0 on a regular device)
FULL (secondary user)
MANAGED_PROFILE (profile users)
Test: Manual verification via "pm list users" of new flags when adding a new user
Test: Manual verification via "pm list users" of new flags for pre-existing users
Test: Later cls will test the functionality as it is introduced
Bug: 134605778
Change-Id: Ife92bfa8a91cc4567d825da8e6a1b3894b088b22
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index a707aa8..2ccb6c1 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -75,6 +75,7 @@
import android.security.GateKeeper;
import android.service.gatekeeper.IGateKeeperService;
import android.stats.devicepolicy.DevicePolicyEnums;
+import android.util.ArraySet;
import android.util.AtomicFile;
import android.util.IntArray;
import android.util.Log;
@@ -125,6 +126,7 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
+import java.util.Set;
/**
* Service for {@link UserManager}.
@@ -214,7 +216,7 @@
@VisibleForTesting
static final int MAX_RECENTLY_REMOVED_IDS_SIZE = 100;
- private static final int USER_VERSION = 7;
+ private static final int USER_VERSION = 8;
private static final long EPOCH_PLUS_30_YEARS = 30L * 365 * 24 * 60 * 60 * 1000L; // ms
@@ -2139,6 +2141,7 @@
*/
@GuardedBy({"mRestrictionsLock", "mPackagesLock"})
private void upgradeIfNecessaryLP(Bundle oldGlobalUserRestrictions) {
+ Set<Integer> userIdsToWrite = new ArraySet<>();
final int originalVersion = mUserVersion;
int userVersion = mUserVersion;
if (userVersion < 1) {
@@ -2147,7 +2150,7 @@
if ("Primary".equals(userData.info.name)) {
userData.info.name =
mContext.getResources().getString(com.android.internal.R.string.owner_name);
- scheduleWriteUser(userData);
+ userIdsToWrite.add(userData.info.id);
}
userVersion = 1;
}
@@ -2157,7 +2160,7 @@
UserData userData = getUserDataNoChecks(UserHandle.USER_SYSTEM);
if ((userData.info.flags & UserInfo.FLAG_INITIALIZED) == 0) {
userData.info.flags |= UserInfo.FLAG_INITIALIZED;
- scheduleWriteUser(userData);
+ userIdsToWrite.add(userData.info.id);
}
userVersion = 2;
}
@@ -2182,7 +2185,7 @@
&& (userData.info.restrictedProfileParentId
== UserInfo.NO_PROFILE_GROUP_ID)) {
userData.info.restrictedProfileParentId = UserHandle.USER_SYSTEM;
- scheduleWriteUser(userData);
+ userIdsToWrite.add(userData.info.id);
}
}
}
@@ -2206,6 +2209,29 @@
userVersion = 7;
}
+ if (userVersion < 8) {
+ // Added FLAG_FULL and FLAG_SYSTEM flags.
+ synchronized (mUsersLock) {
+ UserData userData = mUsers.get(UserHandle.USER_SYSTEM);
+ userData.info.flags |= UserInfo.FLAG_SYSTEM;
+ if (!UserManager.isHeadlessSystemUserMode()) {
+ userData.info.flags |= UserInfo.FLAG_FULL;
+ }
+ userIdsToWrite.add(userData.info.id);
+
+ // Mark FULL all non-profile users except USER_SYSTEM.
+ // Start index at 1 since USER_SYSTEM is the smallest userId and we're skipping it.
+ for (int i = 1; i < mUsers.size(); i++) {
+ userData = mUsers.valueAt(i);
+ if ((userData.info.flags & UserInfo.FLAG_MANAGED_PROFILE) == 0) {
+ userData.info.flags |= UserInfo.FLAG_FULL;
+ userIdsToWrite.add(userData.info.id);
+ }
+ }
+ }
+ userVersion = 8;
+ }
+
if (userVersion < USER_VERSION) {
Slog.w(LOG_TAG, "User version " + mUserVersion + " didn't upgrade as expected to "
+ USER_VERSION);
@@ -2213,6 +2239,12 @@
mUserVersion = userVersion;
if (originalVersion < mUserVersion) {
+ for (int userId : userIdsToWrite) {
+ UserData userData = getUserDataNoChecks(userId);
+ if (userData != null) {
+ writeUserLP(userData);
+ }
+ }
writeUserListLP();
}
}
@@ -2220,12 +2252,15 @@
@GuardedBy({"mPackagesLock", "mRestrictionsLock"})
private void fallbackToSingleUserLP() {
- int flags = UserInfo.FLAG_INITIALIZED;
+ int flags = UserInfo.FLAG_SYSTEM | UserInfo.FLAG_INITIALIZED;
// In split system user mode, the admin and primary flags are assigned to the first human
// user.
if (!UserManager.isSplitSystemUser()) {
flags |= UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY;
}
+ if (!UserManager.isHeadlessSystemUserMode()) {
+ flags |= UserInfo.FLAG_FULL;
+ }
// Create the system user
UserInfo system = new UserInfo(UserHandle.USER_SYSTEM, null, null, flags);
UserData userData = putUserInfo(system);
@@ -2262,14 +2297,14 @@
return mContext.getResources().getString(com.android.internal.R.string.owner_name);
}
- private void scheduleWriteUser(UserData UserData) {
+ private void scheduleWriteUser(UserData userData) {
if (DBG) {
debug("scheduleWriteUser");
}
// No need to wrap it within a lock -- worst case, we'll just post the same message
// twice.
- if (!mHandler.hasMessages(WRITE_USER_MSG, UserData)) {
- Message msg = mHandler.obtainMessage(WRITE_USER_MSG, UserData);
+ if (!mHandler.hasMessages(WRITE_USER_MSG, userData)) {
+ Message msg = mHandler.obtainMessage(WRITE_USER_MSG, userData);
mHandler.sendMessageDelayed(msg, WRITE_USER_DELAY);
}
}
@@ -2749,6 +2784,10 @@
}
}
}
+ if (!isManagedProfile) {
+ // New users cannot be system, and it's not a profile, so per-force it's FULL.
+ flags |= UserInfo.FLAG_FULL;
+ }
userId = getNextAvailableId();
Environment.getUserSystemDirectory(userId).mkdirs();