Loading core/java/android/content/pm/UserInfo.java +18 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,15 @@ public class UserInfo implements Parcelable { */ public static final int FLAG_INITIALIZED = 0x00000010; /** * Indicates that this user is a profile of another user, for example holding a users * corporate data. */ public static final int FLAG_MANAGED_PROFILE = 0x00000020; public static final int NO_RELATED_GROUP_ID = -1; public int id; public int serialNumber; public String name; Loading @@ -70,6 +79,7 @@ public class UserInfo implements Parcelable { public int flags; public long creationTime; public long lastLoggedInTime; public int relatedGroupId; /** User is only partially created. */ public boolean partial; Loading @@ -83,6 +93,7 @@ public class UserInfo implements Parcelable { this.name = name; this.flags = flags; this.iconPath = iconPath; this.relatedGroupId = NO_RELATED_GROUP_ID; } public boolean isPrimary() { Loading @@ -101,6 +112,10 @@ public class UserInfo implements Parcelable { return (flags & FLAG_RESTRICTED) == FLAG_RESTRICTED; } public boolean isManagedProfile() { return (flags & FLAG_MANAGED_PROFILE) == FLAG_MANAGED_PROFILE; } public UserInfo() { } Loading @@ -113,6 +128,7 @@ public class UserInfo implements Parcelable { creationTime = orig.creationTime; lastLoggedInTime = orig.lastLoggedInTime; partial = orig.partial; relatedGroupId = orig.relatedGroupId; } public UserHandle getUserHandle() { Loading @@ -137,6 +153,7 @@ public class UserInfo implements Parcelable { dest.writeLong(creationTime); dest.writeLong(lastLoggedInTime); dest.writeInt(partial ? 1 : 0); dest.writeInt(relatedGroupId); } public static final Parcelable.Creator<UserInfo> CREATOR Loading @@ -158,5 +175,6 @@ public class UserInfo implements Parcelable { creationTime = source.readLong(); lastLoggedInTime = source.readLong(); partial = source.readInt() != 0; relatedGroupId = source.readInt(); } } core/java/android/os/IUserManager.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -28,11 +28,13 @@ import android.graphics.Bitmap; */ interface IUserManager { UserInfo createUser(in String name, int flags); UserInfo createRelatedUser(in String name, int flags, int relatedUserId); boolean removeUser(int userHandle); void setUserName(int userHandle, String name); void setUserIcon(int userHandle, in Bitmap icon); Bitmap getUserIcon(int userHandle); List<UserInfo> getUsers(boolean excludeDying); List<UserInfo> getRelatedUsers(int userHandle); UserInfo getUserInfo(int userHandle); boolean isRestricted(); void setGuestEnabled(boolean enable); Loading core/java/android/os/UserManager.java +37 −0 Original line number Diff line number Diff line Loading @@ -407,6 +407,27 @@ public class UserManager { } } /** * Creates a user with the specified name and options. * Requires {@link android.Manifest.permission#MANAGE_USERS} permission. * * @param name the user's name * @param flags flags that identify the type of user and other properties. * @see UserInfo * @param relatedUserId new user will be related to this user id. * * @return the UserInfo object for the created user, or null if the user could not be created. * @hide */ public UserInfo createRelatedUser(String name, int flags, int relatedUserId) { try { return mService.createRelatedUser(name, flags, relatedUserId); } catch (RemoteException re) { Log.w(TAG, "Could not create a user", re); return null; } } /** * Return the number of users currently created on the device. */ Loading @@ -430,6 +451,22 @@ public class UserManager { } } /** * Returns information for all users related to userId * Requires {@link android.Manifest.permission#MANAGE_USERS} permission. * @param userHandle users related to this user id will be returned. * @return the list of related users. * @hide */ public List<UserInfo> getRelatedUsers(int userHandle) { try { return mService.getRelatedUsers(userHandle); } catch (RemoteException re) { Log.w(TAG, "Could not get user list", re); return null; } } /** * Returns information for all users on this device. * Requires {@link android.Manifest.permission#MANAGE_USERS} permission. Loading services/core/java/com/android/server/pm/UserManagerService.java +69 −0 Original line number Diff line number Diff line Loading @@ -92,6 +92,7 @@ public class UserManagerService extends IUserManager.Stub { private static final String ATTR_NEXT_SERIAL_NO = "nextSerialNumber"; private static final String ATTR_PARTIAL = "partial"; private static final String ATTR_USER_VERSION = "version"; private static final String ATTR_RELATED_GROUP_ID = "relatedGroupId"; private static final String TAG_USERS = "users"; private static final String TAG_USER = "user"; private static final String TAG_RESTRICTIONS = "restrictions"; Loading Loading @@ -257,6 +258,29 @@ public class UserManagerService extends IUserManager.Stub { } } @Override public List<UserInfo> getRelatedUsers(int userId) { checkManageUsersPermission("query users"); synchronized (mPackagesLock) { UserInfo user = getUserInfoLocked(userId); ArrayList<UserInfo> users = new ArrayList<UserInfo>(mUsers.size()); for (int i = 0; i < mUsers.size(); i++) { UserInfo ui = mUsers.valueAt(i); if (!areRelatedUsers(user, ui)) { continue; } users.add(ui); } return users; } } private boolean areRelatedUsers(UserInfo user1, UserInfo user2) { return user1.relatedGroupId != UserInfo.NO_RELATED_GROUP_ID && user1.relatedGroupId == user2.relatedGroupId && user1.id != user2.id; } @Override public UserInfo getUserInfo(int userId) { checkManageUsersPermission("query user"); Loading Loading @@ -662,6 +686,10 @@ public class UserManagerService extends IUserManager.Stub { if (userInfo.partial) { serializer.attribute(null, ATTR_PARTIAL, "true"); } if (userInfo.relatedGroupId != UserInfo.NO_RELATED_GROUP_ID) { serializer.attribute(null, ATTR_RELATED_GROUP_ID, Integer.toString(userInfo.relatedGroupId)); } serializer.startTag(null, TAG_NAME); serializer.text(userInfo.name); Loading Loading @@ -745,6 +773,7 @@ public class UserManagerService extends IUserManager.Stub { long salt = 0L; String pinHash = null; int failedAttempts = 0; int relatedGroupId = UserInfo.NO_RELATED_GROUP_ID; long lastAttemptTime = 0L; boolean partial = false; Bundle restrictions = new Bundle(); Loading Loading @@ -782,6 +811,8 @@ public class UserManagerService extends IUserManager.Stub { pinHash = parser.getAttributeValue(null, ATTR_PIN_HASH); failedAttempts = readIntAttribute(parser, ATTR_FAILED_ATTEMPTS, 0); lastAttemptTime = readLongAttribute(parser, ATTR_LAST_RETRY_MS, 0L); relatedGroupId = readIntAttribute(parser, ATTR_RELATED_GROUP_ID, UserInfo.NO_RELATED_GROUP_ID); String valueString = parser.getAttributeValue(null, ATTR_PARTIAL); if ("true".equals(valueString)) { partial = true; Loading Loading @@ -820,6 +851,7 @@ public class UserManagerService extends IUserManager.Stub { userInfo.creationTime = creationTime; userInfo.lastLoggedInTime = lastLoggedInTime; userInfo.partial = partial; userInfo.relatedGroupId = relatedGroupId; mUserRestrictions.append(id, restrictions); if (salt != 0L) { RestrictionsPinState pinState = mRestrictionsPinStates.get(id); Loading Loading @@ -934,10 +966,40 @@ public class UserManagerService extends IUserManager.Stub { } } private int getNextRelatedGroupIdLocked() { int maxGroupId = UserInfo.NO_RELATED_GROUP_ID; for (int i = 0; i < mUsers.size(); i++) { UserInfo ui = mUsers.valueAt(i); if (maxGroupId < ui.relatedGroupId) { maxGroupId = ui.relatedGroupId; } } return maxGroupId + 1; } @Override public UserInfo createRelatedUser(String name, int flags, int relatedUserId) { checkManageUsersPermission("Only the system can create users"); if (relatedUserId != UserHandle.USER_OWNER) { Slog.w(LOG_TAG, "Only user owner can have related users"); return null; } synchronized (mPackagesLock) { UserInfo relatedUser = getUserInfoLocked(relatedUserId); if (relatedUser == null) { return null; } return createUserInternal(name, flags, relatedUser); } } @Override public UserInfo createUser(String name, int flags) { checkManageUsersPermission("Only the system can create users"); return createUserInternal(name, flags, null); } private UserInfo createUserInternal(String name, int flags, UserInfo relatedUser) { final long ident = Binder.clearCallingIdentity(); final UserInfo userInfo; try { Loading @@ -954,6 +1016,13 @@ public class UserManagerService extends IUserManager.Stub { Environment.getUserSystemDirectory(userInfo.id).mkdirs(); mUsers.put(userId, userInfo); writeUserListLocked(); if (relatedUser != null) { if (relatedUser.relatedGroupId == UserInfo.NO_RELATED_GROUP_ID) { relatedUser.relatedGroupId = getNextRelatedGroupIdLocked(); } userInfo.relatedGroupId = relatedUser.relatedGroupId; writeUserLocked(relatedUser); } writeUserLocked(userInfo); mPm.createNewUserLILPw(userId, userPath); userInfo.partial = false; Loading Loading
core/java/android/content/pm/UserInfo.java +18 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,15 @@ public class UserInfo implements Parcelable { */ public static final int FLAG_INITIALIZED = 0x00000010; /** * Indicates that this user is a profile of another user, for example holding a users * corporate data. */ public static final int FLAG_MANAGED_PROFILE = 0x00000020; public static final int NO_RELATED_GROUP_ID = -1; public int id; public int serialNumber; public String name; Loading @@ -70,6 +79,7 @@ public class UserInfo implements Parcelable { public int flags; public long creationTime; public long lastLoggedInTime; public int relatedGroupId; /** User is only partially created. */ public boolean partial; Loading @@ -83,6 +93,7 @@ public class UserInfo implements Parcelable { this.name = name; this.flags = flags; this.iconPath = iconPath; this.relatedGroupId = NO_RELATED_GROUP_ID; } public boolean isPrimary() { Loading @@ -101,6 +112,10 @@ public class UserInfo implements Parcelable { return (flags & FLAG_RESTRICTED) == FLAG_RESTRICTED; } public boolean isManagedProfile() { return (flags & FLAG_MANAGED_PROFILE) == FLAG_MANAGED_PROFILE; } public UserInfo() { } Loading @@ -113,6 +128,7 @@ public class UserInfo implements Parcelable { creationTime = orig.creationTime; lastLoggedInTime = orig.lastLoggedInTime; partial = orig.partial; relatedGroupId = orig.relatedGroupId; } public UserHandle getUserHandle() { Loading @@ -137,6 +153,7 @@ public class UserInfo implements Parcelable { dest.writeLong(creationTime); dest.writeLong(lastLoggedInTime); dest.writeInt(partial ? 1 : 0); dest.writeInt(relatedGroupId); } public static final Parcelable.Creator<UserInfo> CREATOR Loading @@ -158,5 +175,6 @@ public class UserInfo implements Parcelable { creationTime = source.readLong(); lastLoggedInTime = source.readLong(); partial = source.readInt() != 0; relatedGroupId = source.readInt(); } }
core/java/android/os/IUserManager.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -28,11 +28,13 @@ import android.graphics.Bitmap; */ interface IUserManager { UserInfo createUser(in String name, int flags); UserInfo createRelatedUser(in String name, int flags, int relatedUserId); boolean removeUser(int userHandle); void setUserName(int userHandle, String name); void setUserIcon(int userHandle, in Bitmap icon); Bitmap getUserIcon(int userHandle); List<UserInfo> getUsers(boolean excludeDying); List<UserInfo> getRelatedUsers(int userHandle); UserInfo getUserInfo(int userHandle); boolean isRestricted(); void setGuestEnabled(boolean enable); Loading
core/java/android/os/UserManager.java +37 −0 Original line number Diff line number Diff line Loading @@ -407,6 +407,27 @@ public class UserManager { } } /** * Creates a user with the specified name and options. * Requires {@link android.Manifest.permission#MANAGE_USERS} permission. * * @param name the user's name * @param flags flags that identify the type of user and other properties. * @see UserInfo * @param relatedUserId new user will be related to this user id. * * @return the UserInfo object for the created user, or null if the user could not be created. * @hide */ public UserInfo createRelatedUser(String name, int flags, int relatedUserId) { try { return mService.createRelatedUser(name, flags, relatedUserId); } catch (RemoteException re) { Log.w(TAG, "Could not create a user", re); return null; } } /** * Return the number of users currently created on the device. */ Loading @@ -430,6 +451,22 @@ public class UserManager { } } /** * Returns information for all users related to userId * Requires {@link android.Manifest.permission#MANAGE_USERS} permission. * @param userHandle users related to this user id will be returned. * @return the list of related users. * @hide */ public List<UserInfo> getRelatedUsers(int userHandle) { try { return mService.getRelatedUsers(userHandle); } catch (RemoteException re) { Log.w(TAG, "Could not get user list", re); return null; } } /** * Returns information for all users on this device. * Requires {@link android.Manifest.permission#MANAGE_USERS} permission. Loading
services/core/java/com/android/server/pm/UserManagerService.java +69 −0 Original line number Diff line number Diff line Loading @@ -92,6 +92,7 @@ public class UserManagerService extends IUserManager.Stub { private static final String ATTR_NEXT_SERIAL_NO = "nextSerialNumber"; private static final String ATTR_PARTIAL = "partial"; private static final String ATTR_USER_VERSION = "version"; private static final String ATTR_RELATED_GROUP_ID = "relatedGroupId"; private static final String TAG_USERS = "users"; private static final String TAG_USER = "user"; private static final String TAG_RESTRICTIONS = "restrictions"; Loading Loading @@ -257,6 +258,29 @@ public class UserManagerService extends IUserManager.Stub { } } @Override public List<UserInfo> getRelatedUsers(int userId) { checkManageUsersPermission("query users"); synchronized (mPackagesLock) { UserInfo user = getUserInfoLocked(userId); ArrayList<UserInfo> users = new ArrayList<UserInfo>(mUsers.size()); for (int i = 0; i < mUsers.size(); i++) { UserInfo ui = mUsers.valueAt(i); if (!areRelatedUsers(user, ui)) { continue; } users.add(ui); } return users; } } private boolean areRelatedUsers(UserInfo user1, UserInfo user2) { return user1.relatedGroupId != UserInfo.NO_RELATED_GROUP_ID && user1.relatedGroupId == user2.relatedGroupId && user1.id != user2.id; } @Override public UserInfo getUserInfo(int userId) { checkManageUsersPermission("query user"); Loading Loading @@ -662,6 +686,10 @@ public class UserManagerService extends IUserManager.Stub { if (userInfo.partial) { serializer.attribute(null, ATTR_PARTIAL, "true"); } if (userInfo.relatedGroupId != UserInfo.NO_RELATED_GROUP_ID) { serializer.attribute(null, ATTR_RELATED_GROUP_ID, Integer.toString(userInfo.relatedGroupId)); } serializer.startTag(null, TAG_NAME); serializer.text(userInfo.name); Loading Loading @@ -745,6 +773,7 @@ public class UserManagerService extends IUserManager.Stub { long salt = 0L; String pinHash = null; int failedAttempts = 0; int relatedGroupId = UserInfo.NO_RELATED_GROUP_ID; long lastAttemptTime = 0L; boolean partial = false; Bundle restrictions = new Bundle(); Loading Loading @@ -782,6 +811,8 @@ public class UserManagerService extends IUserManager.Stub { pinHash = parser.getAttributeValue(null, ATTR_PIN_HASH); failedAttempts = readIntAttribute(parser, ATTR_FAILED_ATTEMPTS, 0); lastAttemptTime = readLongAttribute(parser, ATTR_LAST_RETRY_MS, 0L); relatedGroupId = readIntAttribute(parser, ATTR_RELATED_GROUP_ID, UserInfo.NO_RELATED_GROUP_ID); String valueString = parser.getAttributeValue(null, ATTR_PARTIAL); if ("true".equals(valueString)) { partial = true; Loading Loading @@ -820,6 +851,7 @@ public class UserManagerService extends IUserManager.Stub { userInfo.creationTime = creationTime; userInfo.lastLoggedInTime = lastLoggedInTime; userInfo.partial = partial; userInfo.relatedGroupId = relatedGroupId; mUserRestrictions.append(id, restrictions); if (salt != 0L) { RestrictionsPinState pinState = mRestrictionsPinStates.get(id); Loading Loading @@ -934,10 +966,40 @@ public class UserManagerService extends IUserManager.Stub { } } private int getNextRelatedGroupIdLocked() { int maxGroupId = UserInfo.NO_RELATED_GROUP_ID; for (int i = 0; i < mUsers.size(); i++) { UserInfo ui = mUsers.valueAt(i); if (maxGroupId < ui.relatedGroupId) { maxGroupId = ui.relatedGroupId; } } return maxGroupId + 1; } @Override public UserInfo createRelatedUser(String name, int flags, int relatedUserId) { checkManageUsersPermission("Only the system can create users"); if (relatedUserId != UserHandle.USER_OWNER) { Slog.w(LOG_TAG, "Only user owner can have related users"); return null; } synchronized (mPackagesLock) { UserInfo relatedUser = getUserInfoLocked(relatedUserId); if (relatedUser == null) { return null; } return createUserInternal(name, flags, relatedUser); } } @Override public UserInfo createUser(String name, int flags) { checkManageUsersPermission("Only the system can create users"); return createUserInternal(name, flags, null); } private UserInfo createUserInternal(String name, int flags, UserInfo relatedUser) { final long ident = Binder.clearCallingIdentity(); final UserInfo userInfo; try { Loading @@ -954,6 +1016,13 @@ public class UserManagerService extends IUserManager.Stub { Environment.getUserSystemDirectory(userInfo.id).mkdirs(); mUsers.put(userId, userInfo); writeUserListLocked(); if (relatedUser != null) { if (relatedUser.relatedGroupId == UserInfo.NO_RELATED_GROUP_ID) { relatedUser.relatedGroupId = getNextRelatedGroupIdLocked(); } userInfo.relatedGroupId = relatedUser.relatedGroupId; writeUserLocked(relatedUser); } writeUserLocked(userInfo); mPm.createNewUserLILPw(userId, userPath); userInfo.partial = false; Loading