diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl index eeb641d33c20d..394866941d43e 100644 --- a/core/java/android/os/IUserManager.aidl +++ b/core/java/android/os/IUserManager.aidl @@ -82,4 +82,7 @@ interface IUserManager { boolean someUserHasSeedAccount(in String accountName, in String accountType); boolean isManagedProfile(int userId); boolean isDemoUser(int userId); + boolean isUserUnlocked(int userId); + boolean isUserUnlockingOrUnlocked(int userId); + boolean isUserRunning(int userId); } diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index a4db940d4fdb8..2278414f3a03f 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -976,9 +976,8 @@ public class UserManager { /** {@hide} */ public boolean isUserRunning(int userId) { - // TODO Switch to using UMS internal isUserRunning try { - return ActivityManagerNative.getDefault().isUserRunning(userId, 0); + return mService.isUserRunning(userId); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } @@ -1075,8 +1074,7 @@ public class UserManager { /** {@hide} */ public boolean isUserUnlocked(@UserIdInt int userId) { try { - return ActivityManagerNative.getDefault().isUserRunning(userId, - ActivityManager.FLAG_AND_UNLOCKED); + return mService.isUserUnlocked(userId); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } @@ -1089,10 +1087,8 @@ public class UserManager { /** {@hide} */ public boolean isUserUnlockingOrUnlocked(@UserIdInt int userId) { - // TODO Switch to using UMS internal isUserUnlockingOrUnlocked try { - return ActivityManagerNative.getDefault().isUserRunning(userId, - ActivityManager.FLAG_AND_UNLOCKING_OR_UNLOCKED); + return mService.isUserUnlockingOrUnlocked(userId); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } diff --git a/core/java/android/os/UserManagerInternal.java b/core/java/android/os/UserManagerInternal.java index 93afb4376cf29..e42704ca2141c 100644 --- a/core/java/android/os/UserManagerInternal.java +++ b/core/java/android/os/UserManagerInternal.java @@ -134,6 +134,12 @@ public abstract class UserManagerInternal { */ public abstract boolean isUserUnlockingOrUnlocked(int userId); + /** + * Return whether the given user is running in an + * {@code UserState.STATE_RUNNING_UNLOCKED} state. + */ + public abstract boolean isUserUnlocked(int userId); + /** * Return whether the given user is running */ diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 0a385f3329fac..4326fd12b6b03 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -654,12 +654,10 @@ public class UserManagerService extends IUserManager.Stub { public boolean isSameProfileGroup(int userId, int otherUserId) { if (userId == otherUserId) return true; checkManageUsersPermission("check if in the same profile group"); - synchronized (mPackagesLock) { - return isSameProfileGroupLP(userId, otherUserId); - } + return isSameProfileGroupNoChecks(userId, otherUserId); } - private boolean isSameProfileGroupLP(int userId, int otherUserId) { + private boolean isSameProfileGroupNoChecks(int userId, int otherUserId) { synchronized (mUsersLock) { UserInfo userInfo = getUserInfoLU(userId); if (userInfo == null || userInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) { @@ -861,12 +859,10 @@ public class UserManagerService extends IUserManager.Stub { public boolean isManagedProfile(int userId) { int callingUserId = UserHandle.getCallingUserId(); if (callingUserId != userId && !hasManageUsersPermission()) { - synchronized (mPackagesLock) { - if (!isSameProfileGroupLP(callingUserId, userId)) { - throw new SecurityException( - "You need MANAGE_USERS permission to: check if specified user a " + - "managed profile outside your profile group"); - } + if (!isSameProfileGroupNoChecks(callingUserId, userId)) { + throw new SecurityException( + "You need MANAGE_USERS permission to: check if specified user a " + + "managed profile outside your profile group"); } } synchronized (mUsersLock) { @@ -875,6 +871,37 @@ public class UserManagerService extends IUserManager.Stub { } } + @Override + public boolean isUserUnlockingOrUnlocked(int userId) { + checkManageOrInteractPermIfCallerInOtherProfileGroup(userId, "isUserUnlockingOrUnlocked"); + return mLocalService.isUserUnlockingOrUnlocked(userId); + } + + @Override + public boolean isUserUnlocked(int userId) { + checkManageOrInteractPermIfCallerInOtherProfileGroup(userId, "isUserUnlocked"); + return mLocalService.isUserUnlockingOrUnlocked(userId); + } + + @Override + public boolean isUserRunning(int userId) { + checkManageOrInteractPermIfCallerInOtherProfileGroup(userId, "isUserRunning"); + return mLocalService.isUserRunning(userId); + } + + private void checkManageOrInteractPermIfCallerInOtherProfileGroup(int userId, String name) { + int callingUserId = UserHandle.getCallingUserId(); + if (callingUserId == userId || isSameProfileGroupNoChecks(callingUserId, userId) || + hasManageUsersPermission()) { + return; + } + if (ActivityManager.checkComponentPermission(Manifest.permission.INTERACT_ACROSS_USERS, + Binder.getCallingUid(), -1, true) != PackageManager.PERMISSION_GRANTED) { + throw new SecurityException("You need INTERACT_ACROSS_USERS or MANAGE_USERS permission " + + "to: check " + name); + } + } + @Override public boolean isDemoUser(int userId) { int callingUserId = UserHandle.getCallingUserId(); @@ -3484,6 +3511,14 @@ public class UserManagerService extends IUserManager.Stub { || (state == UserState.STATE_RUNNING_UNLOCKED); } } + + @Override + public boolean isUserUnlocked(int userId) { + synchronized (mUserStates) { + int state = mUserStates.get(userId, -1); + return state == UserState.STATE_RUNNING_UNLOCKED; + } + } } /* Remove all the users except of the system one. */