Loading core/java/android/os/IUserManager.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -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); Loading core/java/android/os/UserManager.java +24 −3 Original line number Diff line number Diff line Loading @@ -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(); } Loading services/core/java/com/android/server/pm/UserManagerService.java +50 −24 Original line number Diff line number Diff line Loading @@ -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; } Loading Loading @@ -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. * Loading Loading @@ -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); } Loading Loading @@ -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; } /** Loading Loading @@ -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); } /** Loading @@ -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); } /** Loading services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java +25 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading
core/java/android/os/IUserManager.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -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); Loading
core/java/android/os/UserManager.java +24 −3 Original line number Diff line number Diff line Loading @@ -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(); } Loading
services/core/java/com/android/server/pm/UserManagerService.java +50 −24 Original line number Diff line number Diff line Loading @@ -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; } Loading Loading @@ -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. * Loading Loading @@ -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); } Loading Loading @@ -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; } /** Loading Loading @@ -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); } /** Loading @@ -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); } /** Loading
services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java +25 −0 Original line number Diff line number Diff line Loading @@ -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; Loading