Add concepts of related users and managed profiles to user manager.

Related users are a group that will share things like notifications.
Managed profiles are a profile of another user.

Change-Id: I2d0532f1abf939810f0fa3fc7c77ad13fa567833
This commit is contained in:
Kenny Guy
2014-02-11 15:33:14 +00:00
parent e666350e12
commit a52dc3eb40
4 changed files with 126 additions and 0 deletions

View File

@@ -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;
@@ -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;
@@ -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() {
@@ -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() {
}
@@ -113,6 +128,7 @@ public class UserInfo implements Parcelable {
creationTime = orig.creationTime;
lastLoggedInTime = orig.lastLoggedInTime;
partial = orig.partial;
relatedGroupId = orig.relatedGroupId;
}
public UserHandle getUserHandle() {
@@ -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
@@ -158,5 +175,6 @@ public class UserInfo implements Parcelable {
creationTime = source.readLong();
lastLoggedInTime = source.readLong();
partial = source.readInt() != 0;
relatedGroupId = source.readInt();
}
}

View File

@@ -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);

View File

@@ -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.
*/
@@ -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.

View File

@@ -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";
@@ -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");
@@ -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);
@@ -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();
@@ -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;
@@ -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);
@@ -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 {
@@ -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;