Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 826e51c4 authored by Kenny Guy's avatar Kenny Guy Committed by Android (Google) Code Review
Browse files

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

parents 0d148c8b a52dc3eb
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -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();
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -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);
+37 −0
Original line number Diff line number Diff line
@@ -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.
+69 −0
Original line number Diff line number Diff line
@@ -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;