diff options
author | Michael Wachenschwanz <mwachens@google.com> | 2020-04-01 16:28:46 -0700 |
---|---|---|
committer | Michael Wachenschwanz <mwachens@google.com> | 2020-04-06 16:02:33 -0700 |
commit | d2b132fac44c38aea685db9170f24cf93a25ca99 (patch) | |
tree | 77ef7a9a75e74c31f21e26139cd598fd58d92ac9 | |
parent | 969e1e2759c0fad8862df2a9b4467e2e0bfb4594 (diff) |
Add permission check to UsageStatsManager#isAppInactive
UsageStatsManager#isAppInactive provides usage information that is
usually gated by the PACKAGE_USAGE_STATS permission in similar API.
This updates isAppInactive to also check for the PACKAGE_USAGE_STATS
permission.
Test: atest android.app.usage.cts android.app.usage.cts.UsageStatsTest#testIsAppInactive
Fixes: 148991455
Change-Id: I8ff8eb5d2e887bc164095f38d374e3992808fe79
4 files changed, 24 insertions, 7 deletions
diff --git a/core/java/android/app/usage/IUsageStatsManager.aidl b/core/java/android/app/usage/IUsageStatsManager.aidl index 1211c731e2e1..ed6ba0c5efa4 100644 --- a/core/java/android/app/usage/IUsageStatsManager.aidl +++ b/core/java/android/app/usage/IUsageStatsManager.aidl @@ -43,7 +43,7 @@ interface IUsageStatsManager { @UnsupportedAppUsage void setAppInactive(String packageName, boolean inactive, int userId); @UnsupportedAppUsage - boolean isAppInactive(String packageName, int userId); + boolean isAppInactive(String packageName, int userId, String callingPackage); void onCarrierPrivilegedAppsChanged(); void reportChooserSelection(String packageName, int userId, String contentType, in String[] annotations, String action); diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java index 2c701b48455c..5c6f07fd5100 100644 --- a/core/java/android/app/usage/UsageStatsManager.java +++ b/core/java/android/app/usage/UsageStatsManager.java @@ -601,12 +601,17 @@ public final class UsageStatsManager { * app hasn't been used directly or indirectly for a period of time defined by the system. This * could be of the order of several hours or days. Apps are not considered inactive when the * device is charging. + * <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} to query the + * inactive state of other apps</p> + * * @param packageName The package name of the app to query - * @return whether the app is currently considered inactive + * @return whether the app is currently considered inactive or false if querying another app + * without {@link android.Manifest.permission#PACKAGE_USAGE_STATS} */ public boolean isAppInactive(String packageName) { try { - return mService.isAppInactive(packageName, mContext.getUserId()); + return mService.isAppInactive(packageName, mContext.getUserId(), + mContext.getOpPackageName()); } catch (RemoteException e) { // fall through and return default } diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index bf797291380a..19b084b74a8f 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -2493,7 +2493,7 @@ final class ActivityManagerShellCommand extends ShellCommand { IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService( Context.USAGE_STATS_SERVICE)); - boolean isIdle = usm.isAppInactive(packageName, userId); + boolean isIdle = usm.isAppInactive(packageName, userId, SHELL_PACKAGE_NAME); pw.println("Idle=" + isIdle); return 0; } diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java index 0d1b3523bf9b..a2b15f323e18 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UsageStatsService.java @@ -1578,15 +1578,27 @@ public class UsageStatsService extends SystemService implements } @Override - public boolean isAppInactive(String packageName, int userId) { + public boolean isAppInactive(String packageName, int userId, String callingPackage) { + final int callingUid = Binder.getCallingUid(); try { userId = ActivityManager.getService().handleIncomingUser(Binder.getCallingPid(), - Binder.getCallingUid(), userId, false, false, "isAppInactive", null); + callingUid, userId, false, false, "isAppInactive", null); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } + + // If the calling app is asking about itself, continue, else check for permission. + if (packageName.equals(callingPackage)) { + final int actualCallingUid = mPackageManagerInternal.getPackageUidInternal( + callingPackage, 0, userId); + if (actualCallingUid != callingUid) { + return false; + } + } else if (!hasPermission(callingPackage)) { + return false; + } final boolean obfuscateInstantApps = shouldObfuscateInstantAppsForCaller( - Binder.getCallingUid(), userId); + callingUid, userId); final long token = Binder.clearCallingIdentity(); try { return mAppStandby.isAppIdleFiltered( |