From 9d999938df75d07253dfb901dbaeac0dda99becc Mon Sep 17 00:00:00 2001 From: Kweku Adams Date: Mon, 28 Feb 2022 20:43:56 +0000 Subject: [PATCH] Let settings query an app's minimum bucket. Bug: 156509848 Test: manual Change-Id: Ife3869524f93b3341fa6eb1379619142ede5ca73 --- .../server/usage/AppStandbyInternal.java | 5 +++ .../server/usage/AppStandbyController.java | 12 +++++++ .../android/app/usage/IUsageStatsManager.aidl | 1 + .../android/app/usage/UsageStatsManager.java | 17 ++++++++++ .../server/usage/UsageStatsService.java | 34 +++++++++++++++++++ 5 files changed, 69 insertions(+) diff --git a/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java b/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java index 13ecd25d429ab..e2426c2f17581 100644 --- a/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java +++ b/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java @@ -143,6 +143,11 @@ public interface AppStandbyInternal { void setAppStandbyBuckets(@NonNull List appBuckets, int userId, int callingUid, int callingPid); + /** Return the lowest bucket this app can enter. */ + @StandbyBuckets + int getAppMinStandbyBucket(String packageName, int appId, int userId, + boolean shouldObfuscateInstantApps); + /** * Put the specified app in the * {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RESTRICTED} diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java index 54c3db48231d3..849354bd1d972 100644 --- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java +++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java @@ -1436,6 +1436,18 @@ public class AppStandbyController } } + @Override + @StandbyBuckets + public int getAppMinStandbyBucket(String packageName, int appId, int userId, + boolean shouldObfuscateInstantApps) { + if (shouldObfuscateInstantApps && mInjector.isPackageEphemeral(userId, packageName)) { + return STANDBY_BUCKET_NEVER; + } + synchronized (mAppIdleLock) { + return getAppMinBucket(packageName, appId, userId); + } + } + @Override public void restrictApp(@NonNull String packageName, int userId, @ForcedReasons int restrictReason) { diff --git a/core/java/android/app/usage/IUsageStatsManager.aidl b/core/java/android/app/usage/IUsageStatsManager.aidl index a43071418b2f6..2a2a9c6e703ee 100644 --- a/core/java/android/app/usage/IUsageStatsManager.aidl +++ b/core/java/android/app/usage/IUsageStatsManager.aidl @@ -53,6 +53,7 @@ interface IUsageStatsManager { void setAppStandbyBucket(String packageName, int bucket, int userId); ParceledListSlice getAppStandbyBuckets(String callingPackage, int userId); void setAppStandbyBuckets(in ParceledListSlice appBuckets, int userId); + int getAppMinStandbyBucket(String packageName, String callingPackage, int userId); void setEstimatedLaunchTime(String packageName, long estimatedLaunchTime, int userId); void setEstimatedLaunchTimes(in ParceledListSlice appLaunchTimes, int userId); void registerAppUsageObserver(int observerId, in String[] packages, long timeLimitMs, diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java index d7152b3676df2..3a335f9d151bc 100644 --- a/core/java/android/app/usage/UsageStatsManager.java +++ b/core/java/android/app/usage/UsageStatsManager.java @@ -786,6 +786,23 @@ public final class UsageStatsManager { } } + /** + * Return the lowest bucket this app can ever enter. + * + * @param packageName the package for which to fetch the minimum allowed standby bucket. + * {@hide} + */ + @StandbyBuckets + @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) + public int getAppMinStandbyBucket(String packageName) { + try { + return mService.getAppMinStandbyBucket(packageName, mContext.getOpPackageName(), + mContext.getUserId()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * Changes an app's estimated launch time. An app is considered "launched" when a user opens * one of its {@link android.app.Activity Activities}. The provided time is persisted across diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java index 06aa8f05179ce..b9abbf09e74d4 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UsageStatsService.java @@ -2378,6 +2378,40 @@ public class UsageStatsService extends SystemService implements } } + @Override + public int getAppMinStandbyBucket(String packageName, String callingPackage, int userId) { + final int callingUid = Binder.getCallingUid(); + try { + userId = ActivityManager.getService().handleIncomingUser( + Binder.getCallingPid(), callingUid, userId, false, false, + "getAppStandbyBucket", null); + } catch (RemoteException re) { + throw re.rethrowFromSystemServer(); + } + final int packageUid = mPackageManagerInternal.getPackageUid(packageName, 0, userId); + // If the calling app is asking about itself, continue, else check for permission. + if (packageUid != callingUid) { + if (!hasPermission(callingPackage)) { + throw new SecurityException( + "Don't have permission to query min app standby bucket"); + } + } + if (packageUid < 0) { + throw new IllegalArgumentException( + "Cannot get min standby bucket for non existent package (" + + packageName + ")"); + } + final boolean obfuscateInstantApps = shouldObfuscateInstantAppsForCaller(callingUid, + userId); + final long token = Binder.clearCallingIdentity(); + try { + return mAppStandby.getAppMinStandbyBucket( + packageName, UserHandle.getAppId(packageUid), userId, obfuscateInstantApps); + } finally { + Binder.restoreCallingIdentity(token); + } + } + @Override public void setEstimatedLaunchTime(String packageName, long estimatedLaunchTime, int userId) {