Merge "Add isMainUser system API."
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user