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

Commit f6eed4ba authored by Jovana Knezevic's avatar Jovana Knezevic Committed by android-build-merger
Browse files

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

am: b662f94c

Change-Id: I4c3d9e5e95cfafbc2f51e9379b516fa402836fe3
parents 351affae b662f94c
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;