diff options
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( |