Merge "System UserInfo flags are set in UserTypeFactory" into udc-dev
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index c0cd638..8ff1a84 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -985,7 +985,7 @@
     method public boolean isInitialized();
     method public boolean isMain();
     method public boolean isManagedProfile();
-    method public boolean isPrimary();
+    method @Deprecated public boolean isPrimary();
     method public boolean isProfile();
     method public boolean isQuietModeEnabled();
     method public boolean isRestricted();
@@ -1002,7 +1002,7 @@
     field public static final int FLAG_INITIALIZED = 16; // 0x10
     field public static final int FLAG_MAIN = 16384; // 0x4000
     field @Deprecated public static final int FLAG_MANAGED_PROFILE = 32; // 0x20
-    field public static final int FLAG_PRIMARY = 1; // 0x1
+    field @Deprecated public static final int FLAG_PRIMARY = 1; // 0x1
     field public static final int FLAG_PROFILE = 4096; // 0x1000
     field public static final int FLAG_QUIET_MODE = 128; // 0x80
     field @Deprecated public static final int FLAG_RESTRICTED = 8; // 0x8
diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index 6386f75..81fc029 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -60,10 +60,17 @@
      */
 
     /**
-     * Primary user. Only one user can have this flag set. It identifies the first human user
-     * on a device. This flag is not supported in headless system user mode.
+     * Primary user. In practice, this is just synonymous with {@link #FLAG_SYSTEM}.
+     *
+     * <p>On many devices, this will also be the first human user.
+     * However, in {@link UserManager#isHeadlessSystemUserMode() headless system user mode}, this
+     * should be regarded as unsupported since the system user may not be a human.
+     *
+     * @deprecated For checking for user 0, use {@link #FLAG_SYSTEM}.
+     *             For checking for the designated "main human user", use {@link #FLAG_MAIN}.
      */
     @UnsupportedAppUsage
+    @Deprecated
     public static final int FLAG_PRIMARY = 0x00000001;
 
     /**
@@ -335,7 +342,12 @@
         }
     }
 
+    /**
+     * @deprecated For checking for user 0, compare {@link #id} to {@link UserHandle#USER_SYSTEM}.
+     *             For checking for the designated "main human user", use {@link #isMain()}.
+     */
     @UnsupportedAppUsage
+    @Deprecated
     public boolean isPrimary() {
         return (flags & FLAG_PRIMARY) == FLAG_PRIMARY;
     }
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 9c55ad6..bbf7f81 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -4381,11 +4381,16 @@
     }
 
     /**
-     * Returns information for Primary user.
+     * Returns information for Primary user (which in practice is the same as the System user).
      *
      * @return the Primary user, null if not found.
+     * @deprecated For the system user, call {@link #getUserInfo} on {@link UserHandle#USER_SYSTEM},
+     *             or just use {@link UserHandle#SYSTEM} or {@link UserHandle#USER_SYSTEM}.
+     *             For the designated MainUser, use {@link #getMainUser()}.
+     *
      * @hide
      */
+    @Deprecated
     @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
     public @Nullable UserInfo getPrimaryUser() {
         try {
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 11efd41..58ae955 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -3938,22 +3938,22 @@
 
     @GuardedBy({"mPackagesLock"})
     private void fallbackToSingleUserLP() {
-        int flags = UserInfo.FLAG_SYSTEM | UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_ADMIN
-                | UserInfo.FLAG_PRIMARY;
         // Create the system user
-        String systemUserType = isDefaultHeadlessSystemUserMode()
+        final String systemUserType = isDefaultHeadlessSystemUserMode()
                 ? UserManager.USER_TYPE_SYSTEM_HEADLESS
                 : UserManager.USER_TYPE_FULL_SYSTEM;
-        flags |= mUserTypes.get(systemUserType).getDefaultUserInfoFlags();
-        UserInfo system = new UserInfo(UserHandle.USER_SYSTEM, null, null, flags, systemUserType);
-        UserData userData = putUserInfo(system);
+        final int flags = mUserTypes.get(systemUserType).getDefaultUserInfoFlags()
+                | UserInfo.FLAG_INITIALIZED;
+        final UserInfo system = new UserInfo(UserHandle.USER_SYSTEM,
+                /* name= */ null, /* iconPath= */ null, flags, systemUserType);
+        final UserData userData = putUserInfo(system);
         userData.userProperties = new UserProperties(
                 mUserTypes.get(userData.info.userType).getDefaultUserPropertiesReference());
         mNextSerialNumber = MIN_USER_ID;
         mUserVersion = USER_VERSION;
         mUserTypeVersion = UserTypeFactory.getUserTypeVersion();
 
-        Bundle restrictions = new Bundle();
+        final Bundle restrictions = new Bundle();
         try {
             final String[] defaultFirstUserRestrictions = mContext.getResources().getStringArray(
                     com.android.internal.R.array.config_defaultFirstUserRestrictions);
diff --git a/services/core/java/com/android/server/pm/UserTypeDetails.java b/services/core/java/com/android/server/pm/UserTypeDetails.java
index f86ee90..6065372 100644
--- a/services/core/java/com/android/server/pm/UserTypeDetails.java
+++ b/services/core/java/com/android/server/pm/UserTypeDetails.java
@@ -76,7 +76,7 @@
     private final @UserInfoFlag int mBaseType;
 
     // TODO(b/143784345): Update doc/name when we clean up UserInfo.
-    /** The {@link UserInfo.UserInfoFlag}s that all users of this type will automatically have. */
+    /** The {@link UserInfoFlag}s to apply by default to newly created users of this type. */
     private final @UserInfoFlag int mDefaultUserInfoPropertyFlags;
 
     /**
@@ -224,7 +224,7 @@
     }
 
     // TODO(b/143784345): Update comment when UserInfo is reorganized.
-    /** The {@link UserInfo.UserInfoFlag}s that all users of this type will automatically have. */
+    /** The {@link UserInfoFlag}s to apply by default to newly created users of this type. */
     public int getDefaultUserInfoFlags() {
         return mDefaultUserInfoPropertyFlags | mBaseType;
     }
@@ -526,6 +526,7 @@
             Preconditions.checkArgument(hasValidPropertyFlags(),
                     "UserTypeDetails " + mName + " has invalid flags: "
                             + Integer.toHexString(mDefaultUserInfoPropertyFlags));
+            checkSystemAndMainUserPreconditions();
             if (hasBadge()) {
                 Preconditions.checkArgument(mBadgeLabels != null && mBadgeLabels.length != 0,
                         "UserTypeDetails " + mName + " has badge but no badgeLabels.");
@@ -578,8 +579,6 @@
         // TODO(b/143784345): Refactor this when we clean up UserInfo.
         private boolean hasValidPropertyFlags() {
             final int forbiddenMask =
-                    UserInfo.FLAG_PRIMARY |
-                    UserInfo.FLAG_ADMIN |
                     UserInfo.FLAG_INITIALIZED |
                     UserInfo.FLAG_QUIET_MODE |
                     UserInfo.FLAG_FULL |
@@ -587,6 +586,18 @@
                     UserInfo.FLAG_PROFILE;
             return (mDefaultUserInfoPropertyFlags & forbiddenMask) == 0;
         }
+
+        private void checkSystemAndMainUserPreconditions() {
+            // Primary must be synonymous with System.
+            Preconditions.checkArgument(
+                    ((mBaseType & UserInfo.FLAG_SYSTEM) != 0) ==
+                            ((mDefaultUserInfoPropertyFlags & UserInfo.FLAG_PRIMARY) != 0),
+                    "UserTypeDetails " + mName + " cannot be SYSTEM xor PRIMARY.");
+            // At most one MainUser is ever allowed at a time.
+            Preconditions.checkArgument(
+                    ((mDefaultUserInfoPropertyFlags & UserInfo.FLAG_MAIN) == 0) || mMaxAllowed == 1,
+                    "UserTypeDetails " + mName + " must not sanction more than one MainUser.");
+        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/pm/UserTypeFactory.java b/services/core/java/com/android/server/pm/UserTypeFactory.java
index 4cf8c09..b7a2b86 100644
--- a/services/core/java/com/android/server/pm/UserTypeFactory.java
+++ b/services/core/java/com/android/server/pm/UserTypeFactory.java
@@ -16,11 +16,14 @@
 
 package com.android.server.pm;
 
+import static android.content.pm.UserInfo.FLAG_ADMIN;
 import static android.content.pm.UserInfo.FLAG_DEMO;
 import static android.content.pm.UserInfo.FLAG_EPHEMERAL;
 import static android.content.pm.UserInfo.FLAG_FULL;
 import static android.content.pm.UserInfo.FLAG_GUEST;
+import static android.content.pm.UserInfo.FLAG_MAIN;
 import static android.content.pm.UserInfo.FLAG_MANAGED_PROFILE;
+import static android.content.pm.UserInfo.FLAG_PRIMARY;
 import static android.content.pm.UserInfo.FLAG_PROFILE;
 import static android.content.pm.UserInfo.FLAG_RESTRICTED;
 import static android.content.pm.UserInfo.FLAG_SYSTEM;
@@ -62,7 +65,7 @@
  * This class is responsible both for defining the AOSP use types, as well as reading in customized
  * user types from {@link com.android.internal.R.xml#config_user_types}.
  *
- * Tests are located in UserManagerServiceUserTypeTest.java.
+ * Tests are located in {@link UserManagerServiceUserTypeTest}.
  * @hide
  */
 public final class UserTypeFactory {
@@ -277,7 +280,8 @@
         return new UserTypeDetails.Builder()
                 .setName(USER_TYPE_FULL_SYSTEM)
                 .setBaseType(FLAG_SYSTEM | FLAG_FULL)
-                .setDefaultUserInfoPropertyFlags(UserInfo.FLAG_MAIN);
+                .setDefaultUserInfoPropertyFlags(FLAG_PRIMARY | FLAG_ADMIN | FLAG_MAIN)
+                .setMaxAllowed(1);
     }
 
     /**
@@ -287,7 +291,9 @@
     private static UserTypeDetails.Builder getDefaultTypeSystemHeadless() {
         return new UserTypeDetails.Builder()
                 .setName(USER_TYPE_SYSTEM_HEADLESS)
-                .setBaseType(FLAG_SYSTEM);
+                .setBaseType(FLAG_SYSTEM)
+                .setDefaultUserInfoPropertyFlags(FLAG_PRIMARY | FLAG_ADMIN)
+                .setMaxAllowed(1);
     }
 
     private static Bundle getDefaultSecondaryUserRestrictions() {