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

Commit b662f94c authored by Jovana Knezevic's avatar Jovana Knezevic Committed by Android (Google) Code Review
Browse files

Merge "Adding hidden APIs for assigning Admin flag to users." into pi-dev

parents 9e1024fb f24ad499
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ interface IUserManager {
            in String[] disallowedPackages);
    UserInfo createRestrictedProfile(String name, int parentUserHandle);
    void setUserEnabled(int userHandle);
    void setUserAdmin(int userId);
    void evictCredentialEncryptionKey(int userHandle);
    boolean removeUser(int userHandle);
    boolean removeUserEvenWhenDisallowed(int userHandle);
+24 −3
Original line number Diff line number Diff line
@@ -2087,12 +2087,33 @@ public class UserManager {
     * Also ephemeral users can be disabled to indicate that their removal is in progress and they
     * shouldn't be re-entered. Therefore ephemeral users should not be re-enabled once disabled.
     *
     * @param userHandle the id of the profile to enable
     * @param userId the id of the profile to enable
     * @hide
     */
    public void setUserEnabled(@UserIdInt int userHandle) {
    public void setUserEnabled(@UserIdInt int userId) {
        try {
            mService.setUserEnabled(userHandle);
            mService.setUserEnabled(userId);
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
    }

    /**
     * Assigns admin privileges to the user, if such a user exists.
     *
     * <p>Requires {@link android.Manifest.permission#MANAGE_USERS} and
     * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} permissions.
     *
     * @param userHandle the id of the user to become admin
     * @hide
     */
    @RequiresPermission(allOf = {
            Manifest.permission.INTERACT_ACROSS_USERS_FULL,
            Manifest.permission.MANAGE_USERS
    })
    public void setUserAdmin(@UserIdInt int userHandle) {
        try {
            mService.setUserAdmin(userHandle);
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
+50 −24
Original line number Diff line number Diff line
@@ -873,9 +873,8 @@ public class UserManagerService extends IUserManager.Stub {
            throw new SecurityException("MANAGE_USERS permission is required to start intent "
                    + "after disabling quiet mode.");
        }
        final boolean hasModifyQuietModePermission = ActivityManager.checkComponentPermission(
                Manifest.permission.MODIFY_QUIET_MODE,
                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED;
        final boolean hasModifyQuietModePermission = hasPermissionGranted(
                Manifest.permission.MODIFY_QUIET_MODE, callingUid);
        if (hasModifyQuietModePermission) {
            return;
        }
@@ -1002,6 +1001,30 @@ public class UserManagerService extends IUserManager.Stub {
        }
    }

    @Override
    public void setUserAdmin(int userId) {
        checkManageUserAndAcrossUsersFullPermission("set user admin");

        synchronized (mPackagesLock) {
            UserInfo info;
            synchronized (mUsersLock) {
                info = getUserInfoLU(userId);
            }
            if (info == null || info.isAdmin()) {
                // Exit if no user found with that id, or the user is already an Admin.
                return;
            }

            info.flags ^= UserInfo.FLAG_ADMIN;
            writeUserLP(getUserDataLU(info.id));
        }

        // Remove non-admin restrictions.
        // Keep synchronized with createUserEvenWhenDisallowed.
        setUserRestriction(UserManager.DISALLOW_SMS, false, userId);
        setUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS, false, userId);
    }

    /**
     * Evicts a user's CE key by stopping and restarting the user.
     *
@@ -1122,8 +1145,8 @@ public class UserManagerService extends IUserManager.Stub {
                hasManageUsersPermission()) {
            return;
        }
        if (ActivityManager.checkComponentPermission(Manifest.permission.INTERACT_ACROSS_USERS,
                Binder.getCallingUid(), -1, true) != PackageManager.PERMISSION_GRANTED) {
        if (!hasPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS,
                Binder.getCallingUid())) {
            throw new SecurityException("You need INTERACT_ACROSS_USERS or MANAGE_USERS permission "
                    + "to: check " + name);
        }
@@ -1801,17 +1824,26 @@ public class UserManagerService extends IUserManager.Stub {
     */
    private static final void checkManageUserAndAcrossUsersFullPermission(String message) {
        final int uid = Binder.getCallingUid();
        if (uid != Process.SYSTEM_UID && uid != 0
                && ActivityManager.checkComponentPermission(
                Manifest.permission.MANAGE_USERS,
                uid, -1, true) != PackageManager.PERMISSION_GRANTED
                && ActivityManager.checkComponentPermission(
                Manifest.permission.INTERACT_ACROSS_USERS_FULL,
                uid, -1, true) != PackageManager.PERMISSION_GRANTED) {

        if (uid == Process.SYSTEM_UID || uid == 0) {
            // System UID or root's UID are granted privilege.
            return;
        }

        if (hasPermissionGranted(Manifest.permission.MANAGE_USERS, uid)
                && hasPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS_FULL, uid)) {
            // Apps with both permissions are granted privilege.
            return;
        }

        throw new SecurityException(
                    "You need MANAGE_USERS and INTERACT_ACROSS_USERS_FULL permission to: "
                            + message);
                "You need MANAGE_USERS and INTERACT_ACROSS_USERS_FULL permission to: " + message);
    }

    private static boolean hasPermissionGranted(String permission, int uid) {
        return ActivityManager.checkComponentPermission(
                permission, uid, /* owningUid = */-1, /* exported = */ true) ==
                PackageManager.PERMISSION_GRANTED;
    }

    /**
@@ -1872,9 +1904,7 @@ public class UserManagerService extends IUserManager.Stub {
        final int callingUid = Binder.getCallingUid();
        return UserHandle.isSameApp(callingUid, Process.SYSTEM_UID)
                || callingUid == Process.ROOT_UID
                || ActivityManager.checkComponentPermission(
                        android.Manifest.permission.MANAGE_USERS,
                        callingUid, -1, true) == PackageManager.PERMISSION_GRANTED;
                || hasPermissionGranted(android.Manifest.permission.MANAGE_USERS, callingUid);
    }

    /**
@@ -1886,12 +1916,8 @@ public class UserManagerService extends IUserManager.Stub {
        final int callingUid = Binder.getCallingUid();
        return UserHandle.isSameApp(callingUid, Process.SYSTEM_UID)
                || callingUid == Process.ROOT_UID
                || ActivityManager.checkComponentPermission(
                        android.Manifest.permission.MANAGE_USERS,
                        callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
                || ActivityManager.checkComponentPermission(
                        android.Manifest.permission.CREATE_USERS,
                        callingUid, -1, true) == PackageManager.PERMISSION_GRANTED;
                || hasPermissionGranted(android.Manifest.permission.MANAGE_USERS, callingUid)
                || hasPermissionGranted(android.Manifest.permission.CREATE_USERS, callingUid);
    }

    /**
+25 −0
Original line number Diff line number Diff line
@@ -169,6 +169,31 @@ public class UserManagerTest extends AndroidTestCase {
        assertNull(userInfo2);
    }

    @MediumTest
    public void testSetUserAdmin() throws Exception {
        UserInfo userInfo = createUser("SecondaryUser", /*flags=*/ 0);

        // Assert user is not admin and has SMS and calls restrictions.
        assertFalse(userInfo.isAdmin());
        assertTrue(mUserManager.hasUserRestriction(UserManager.DISALLOW_SMS,
                userInfo.getUserHandle()));
        assertTrue(mUserManager.hasUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS,
                userInfo.getUserHandle()));

        // Assign admin privileges.
        mUserManager.setUserAdmin(userInfo.id);

        // Refresh.
        userInfo = mUserManager.getUserInfo(userInfo.id);

        // Verify user became admin and SMS and call restrictions are lifted.
        assertTrue(userInfo.isAdmin());
        assertFalse(mUserManager.hasUserRestriction(UserManager.DISALLOW_SMS,
                userInfo.getUserHandle()));
        assertFalse(mUserManager.hasUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS,
                userInfo.getUserHandle()));
    }

    @MediumTest
    public void testGetProfileParent() throws Exception {
        final int primaryUserId = mUserManager.getPrimaryUser().id;