Merge "Add isMainUser system API."

This commit is contained in:
Oli Lan
2022-11-15 18:05:57 +00:00
committed by Android (Google) Code Review
7 changed files with 93 additions and 7 deletions

View File

@@ -9969,9 +9969,10 @@ package android.os {
method public boolean isCloneProfile();
method public boolean isCredentialSharableWithParent();
method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS, android.Manifest.permission.QUERY_USERS}) public boolean isGuestUser();
method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS, android.Manifest.permission.QUERY_USERS}) public boolean isMainUser();
method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.QUERY_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional=true) public boolean isManagedProfile(int);
method public boolean isMediaSharedWithParent();
method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS, android.Manifest.permission.QUERY_USERS}) public boolean isPrimaryUser();
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS, android.Manifest.permission.QUERY_USERS}) public boolean isPrimaryUser();
method public static boolean isRemoveResultSuccessful(int);
method public boolean isRestrictedProfile();
method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}, conditional=true) public boolean isRestrictedProfile(@NonNull android.os.UserHandle);

View File

@@ -905,6 +905,7 @@ package android.content.pm {
method public boolean isFull();
method public boolean isGuest();
method public boolean isInitialized();
method public boolean isMain();
method public boolean isManagedProfile();
method public boolean isPrimary();
method public boolean isProfile();
@@ -923,6 +924,7 @@ package android.content.pm {
field public static final int FLAG_FULL = 1024; // 0x400
field @Deprecated public static final int FLAG_GUEST = 4; // 0x4
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 public static final int FLAG_PROFILE = 4096; // 0x1000

View File

@@ -158,6 +158,18 @@ public class UserInfo implements Parcelable {
*/
public static final int FLAG_EPHEMERAL_ON_CREATE = 0x00002000;
/**
* Indicates that this user is the designated main user on the device. This user may have access
* to certain features which are limited to at most one user.
*
* <p>Currently, this will be the first user to go through setup on the device, but in future
* releases this status may be transferable or may even not be given to any users.
*
* <p>This is not necessarily the system user. For example, it will not be the system user on
* devices for which {@link UserManager#isHeadlessSystemUserMode()} returns true.
*/
public static final int FLAG_MAIN = 0x00004000;
/**
* @hide
*/
@@ -175,7 +187,8 @@ public class UserInfo implements Parcelable {
FLAG_FULL,
FLAG_SYSTEM,
FLAG_PROFILE,
FLAG_EPHEMERAL_ON_CREATE
FLAG_EPHEMERAL_ON_CREATE,
FLAG_MAIN
})
@Retention(RetentionPolicy.SOURCE)
public @interface UserInfoFlag {
@@ -368,6 +381,13 @@ public class UserInfo implements Parcelable {
return (flags & FLAG_FULL) == FLAG_FULL;
}
/**
* @see #FLAG_MAIN
*/
public boolean isMain() {
return (flags & FLAG_MAIN) == FLAG_MAIN;
}
/**
* Returns true if the user is a split system user.
* <p>If {@link UserManager#isSplitSystemUser split system user mode} is not enabled,

View File

@@ -2341,12 +2341,18 @@ public class UserManager {
}
/**
* Used to check if the context user is the primary user. The primary user
* is the first human user on a device. This is not supported in headless system user mode.
* Used to check if the context user is the primary user. The primary user is the first human
* user on a device. This is not supported in headless system user mode.
*
* @return whether the context user is the primary user.
*
* @deprecated This method always returns true for the system user, who may not be a full user
* if {@link #isHeadlessSystemUserMode} is true. Use {@link #isSystemUser}, {@link #isAdminUser}
* or {@link #isMainUser} instead.
*
* @hide
*/
@Deprecated
@SystemApi
@RequiresPermission(anyOf = {
Manifest.permission.MANAGE_USERS,
@@ -2370,6 +2376,29 @@ public class UserManager {
return getContextUserIfAppropriate() == UserHandle.USER_SYSTEM;
}
/**
* Returns true if the context user is the designated "main user" of the device. This user may
* have access to certain features which are limited to at most one user.
*
* <p>Currently, the first human user on the device will be the main user; in the future, the
* concept may be transferable, so a different user (or even no user at all) may be designated
* the main user instead.
*
* <p>Note that this will be the not be the system user on devices for which
* {@link #isHeadlessSystemUserMode()} returns true.
* @hide
*/
@SystemApi
@RequiresPermission(anyOf = {
Manifest.permission.MANAGE_USERS,
Manifest.permission.CREATE_USERS,
Manifest.permission.QUERY_USERS})
@UserHandleAware
public boolean isMainUser() {
final UserInfo user = getUserInfo(mUserId);
return user != null && user.isMain();
}
/**
* Used to check if the context user is an admin user. An admin user is allowed to
* modify or configure certain settings that aren't available to non-admin users,

View File

@@ -265,7 +265,7 @@ public class UserManagerService extends IUserManager.Stub {
@VisibleForTesting
static final int MAX_RECENTLY_REMOVED_IDS_SIZE = 100;
private static final int USER_VERSION = 10;
private static final int USER_VERSION = 11;
private static final long EPOCH_PLUS_30_YEARS = 30L * 365 * 24 * 60 * 60 * 1000L; // ms
@@ -3355,6 +3355,7 @@ public class UserManagerService extends IUserManager.Stub {
final int oldFlags = systemUserData.info.flags;
final int newFlags;
final String newUserType;
// TODO(b/256624031): Also handle FLAG_MAIN
if (newHeadlessSystemUserMode) {
newUserType = UserManager.USER_TYPE_SYSTEM_HEADLESS;
newFlags = oldFlags & ~UserInfo.FLAG_FULL;
@@ -3647,6 +3648,22 @@ public class UserManagerService extends IUserManager.Stub {
userVersion = 10;
}
if (userVersion < 11) {
// Add FLAG_MAIN
if (isHeadlessSystemUserMode()) {
final UserInfo earliestCreatedUser = getEarliestCreatedFullUser();
earliestCreatedUser.flags |= UserInfo.FLAG_MAIN;
userIdsToWrite.add(earliestCreatedUser.id);
} else {
synchronized (mUsersLock) {
final UserData userData = mUsers.get(UserHandle.USER_SYSTEM);
userData.info.flags |= UserInfo.FLAG_MAIN;
userIdsToWrite.add(userData.info.id);
}
}
userVersion = 11;
}
// Reminder: If you add another upgrade, make sure to increment USER_VERSION too.
// Done with userVersion changes, moving on to deal with userTypeVersion upgrades
@@ -3776,6 +3793,21 @@ public class UserManagerService extends IUserManager.Stub {
userInfo.profileBadge = getFreeProfileBadgeLU(userInfo.profileGroupId, userInfo.userType);
}
private UserInfo getEarliestCreatedFullUser() {
final List<UserInfo> users = getUsersInternal(true, true, true);
UserInfo earliestUser = users.get(0);
long earliestCreationTime = earliestUser.creationTime;
for (int i = 0; i < users.size(); i++) {
final UserInfo info = users.get(i);
if (info.isFull() && info.creationTime > 0
&& info.creationTime < earliestCreationTime) {
earliestCreationTime = info.creationTime;
earliestUser = info;
}
}
return earliestUser;
}
@GuardedBy({"mPackagesLock"})
private void fallbackToSingleUserLP() {
int flags = UserInfo.FLAG_SYSTEM | UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_ADMIN

View File

@@ -262,7 +262,8 @@ public final class UserTypeFactory {
private static UserTypeDetails.Builder getDefaultTypeFullSystem() {
return new UserTypeDetails.Builder()
.setName(USER_TYPE_FULL_SYSTEM)
.setBaseType(FLAG_SYSTEM | FLAG_FULL);
.setBaseType(FLAG_SYSTEM | FLAG_FULL)
.setDefaultUserInfoPropertyFlags(UserInfo.FLAG_MAIN);
}
/**

View File

@@ -83,9 +83,10 @@ final class BootUserInitializer {
Slogf.d(TAG, "Creating initial user");
t.traceBegin("create-initial-user");
try {
int flags = UserInfo.FLAG_ADMIN | UserInfo.FLAG_MAIN;
// TODO(b/204091126): proper name for user
UserInfo newUser = um.createUserEvenWhenDisallowed("Real User",
UserManager.USER_TYPE_FULL_SECONDARY, UserInfo.FLAG_ADMIN,
UserManager.USER_TYPE_FULL_SECONDARY, flags,
/* disallowedPackages= */ null, /* token= */ null);
Slogf.i(TAG, "Created initial user: %s", newUser.toFullString());
initialUserId = newUser.id;