diff --git a/core/api/test-current.txt b/core/api/test-current.txt index cac13743461dd..4681d49432566 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -116,8 +116,8 @@ package android.app { method @RequiresPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) public void addHomeVisibilityListener(@NonNull java.util.concurrent.Executor, @NonNull android.app.HomeVisibilityListener); method public void alwaysShowUnsupportedCompileSdkWarning(android.content.ComponentName); method public long getTotalRam(); - method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public int getUidProcessCapabilities(int); - method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public int getUidProcessState(int); + method @RequiresPermission(allOf={android.Manifest.permission.PACKAGE_USAGE_STATS, android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}, conditional=true) public int getUidProcessCapabilities(int); + method @RequiresPermission(allOf={android.Manifest.permission.PACKAGE_USAGE_STATS, android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}, conditional=true) public int getUidProcessState(int); method public void holdLock(android.os.IBinder, int); method public static boolean isHighEndGfx(); method @RequiresPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) public void removeHomeVisibilityListener(@NonNull android.app.HomeVisibilityListener); diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 458dd5d804d14..abd60177f8844 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -3710,10 +3710,16 @@ public class ActivityManager { /** * Returns the process state of this uid. * + * If the caller does not hold {@link Manifest.permission#INTERACT_ACROSS_USERS_FULL} + * permission, they can only query process state of UIDs running in the same user as the caller. + * * @hide */ @TestApi - @RequiresPermission(Manifest.permission.PACKAGE_USAGE_STATS) + @RequiresPermission(allOf = { + Manifest.permission.PACKAGE_USAGE_STATS, + Manifest.permission.INTERACT_ACROSS_USERS_FULL + }, conditional = true) public int getUidProcessState(int uid) { try { return getService().getUidProcessState(uid, mContext.getOpPackageName()); @@ -3725,10 +3731,17 @@ public class ActivityManager { /** * Returns the process capability of this uid. * + * If the caller does not hold {@link Manifest.permission#INTERACT_ACROSS_USERS_FULL} + * permission, they can only query process capabilities of UIDs running in the same user + * as the caller. + * * @hide */ @TestApi - @RequiresPermission(Manifest.permission.PACKAGE_USAGE_STATS) + @RequiresPermission(allOf = { + Manifest.permission.PACKAGE_USAGE_STATS, + Manifest.permission.INTERACT_ACROSS_USERS_FULL + }, conditional = true) public @ProcessCapability int getUidProcessCapabilities(int uid) { try { return getService().getUidProcessCapabilities(uid, mContext.getOpPackageName()); diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index 49a61580ab3b8..4efe9dfe71855 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -100,6 +100,8 @@ interface IActivityManager { String callingPackage); void unregisterUidObserver(in IUidObserver observer); boolean isUidActive(int uid, String callingPackage); + @JavaPassthrough(annotation= + "@android.annotation.RequiresPermission(allOf = {android.Manifest.permission.PACKAGE_USAGE_STATS, android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}, conditional = true)") int getUidProcessState(int uid, in String callingPackage); @UnsupportedAppUsage int checkPermission(in String permission, int pid, int uid); @@ -742,6 +744,8 @@ interface IActivityManager { /** Called by PendingIntent.queryIntentComponents() */ ParceledListSlice queryIntentComponentsForIntentSender(in IIntentSender sender, int matchFlags); + @JavaPassthrough(annotation= + "@android.annotation.RequiresPermission(allOf = {android.Manifest.permission.PACKAGE_USAGE_STATS, android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}, conditional = true)") int getUidProcessCapabilities(int uid, in String callingPackage); /** Blocks until all broadcast queues become idle. */ diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 91f6eeb875f6f..7c6ccc95664ed 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -7166,6 +7166,11 @@ public class ActivityManagerService extends IActivityManager.Stub enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS, "getUidProcessState"); } + // In case the caller is requesting processState of an app in a different user, + // then verify the caller has INTERACT_ACROSS_USERS_FULL permission + mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), + UserHandle.getUserId(uid), false /* allowAll */, ALLOW_FULL_ONLY, + "getUidProcessState", callingPackage); // Ignore return value synchronized (mProcLock) { if (mPendingStartActivityUids.isPendingTopUid(uid)) { @@ -7181,6 +7186,11 @@ public class ActivityManagerService extends IActivityManager.Stub enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS, "getUidProcessState"); } + // In case the caller is requesting processCapabilities of an app in a different user, + // then verify the caller has INTERACT_ACROSS_USERS_FULL permission + mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), + UserHandle.getUserId(uid), false /* allowAll */, ALLOW_FULL_ONLY, + "getUidProcessCapabilities", callingPackage); // Ignore return value synchronized (mProcLock) { return mProcessList.getUidProcessCapabilityLOSP(uid);