From 071a10efdb1013d7c213bde5628cae5c0f0bbee6 Mon Sep 17 00:00:00 2001 From: Kweku Adams Date: Tue, 16 Mar 2021 13:18:20 -0700 Subject: [PATCH] Allow the system to specify user-force when restricting. There are certain situations where user-force is the right reason to apply when placing an app in the RESTRICTED bucket, but the previous APIs didn't allow for those situations. Introduce a new one to account for those scenarios. Bug: 183103253 Test: atest AppStandbyControllerTests Change-Id: Ifbdc7de8975f31110224b7c20328f9c53abe68d9 --- .../server/usage/AppStandbyInternal.java | 17 +++++++++++++++++ .../server/usage/AppStandbyController.java | 13 ++++++++++++- .../android/app/usage/UsageStatsManager.java | 8 ++++++++ .../server/usage/AppStandbyControllerTests.java | 15 +++++++++++++++ 4 files changed, 52 insertions(+), 1 deletion(-) 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 2ce85ee572055..8c06338560bf5 100644 --- a/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java +++ b/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java @@ -136,6 +136,23 @@ public interface AppStandbyInternal { void restrictApp(@NonNull String packageName, int userId, @SystemForcedReasons int restrictReason); + /** + * Put the specified app in the + * {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RESTRICTED} + * bucket. If it has been used by the user recently, the restriction will delayed + * until an appropriate time. This should only be used in cases where + * {@link #restrictApp(String, int, int)} is not sufficient. + * + * @param mainReason The main reason for restricting the app. Must be either {@link + * android.app.usage.UsageStatsManager#REASON_MAIN_FORCED_BY_SYSTEM} or + * {@link android.app.usage.UsageStatsManager#REASON_MAIN_FORCED_BY_USER}. + * Calls providing any other value will be ignored. + * @param restrictReason The restrictReason for restricting the app. Should be one of the + * UsageStatsManager.REASON_SUB_FORCED_SYSTEM_FLAG_* reasons. + */ + void restrictApp(@NonNull String packageName, int userId, int mainReason, + @SystemForcedReasons int restrictReason); + void addActiveDeviceAdmin(String adminPkg, int userId); void setActiveAdminApps(Set adminPkgs, int userId); 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 1a808c9b3c335..24f7b37aedac7 100644 --- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java +++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java @@ -1343,13 +1343,24 @@ public class AppStandbyController @Override public void restrictApp(@NonNull String packageName, int userId, @SystemForcedReasons int restrictReason) { + restrictApp(packageName, userId, REASON_MAIN_FORCED_BY_SYSTEM, restrictReason); + } + + @Override + public void restrictApp(@NonNull String packageName, int userId, int mainReason, + @SystemForcedReasons int restrictReason) { + if (mainReason != REASON_MAIN_FORCED_BY_SYSTEM + && mainReason != REASON_MAIN_FORCED_BY_USER) { + Slog.e(TAG, "Tried to restrict app " + packageName + " for an unsupported reason"); + return; + } // If the package is not installed, don't allow the bucket to be set. if (!mInjector.isPackageInstalled(packageName, 0, userId)) { Slog.e(TAG, "Tried to restrict uninstalled app: " + packageName); return; } - final int reason = REASON_MAIN_FORCED_BY_SYSTEM | (REASON_SUB_MASK & restrictReason); + final int reason = (REASON_MAIN_MASK & mainReason) | (REASON_SUB_MASK & restrictReason); final long nowElapsed = mInjector.elapsedRealtime(); final int bucket = mAllowRestrictedBucket ? STANDBY_BUCKET_RESTRICTED : STANDBY_BUCKET_RARE; setAppStandbyBucket(packageName, userId, bucket, reason, nowElapsed, false); diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java index 31781ec79203a..1db7e9da0bcb7 100644 --- a/core/java/android/app/usage/UsageStatsManager.java +++ b/core/java/android/app/usage/UsageStatsManager.java @@ -1104,6 +1104,14 @@ public final class UsageStatsManager { break; case REASON_MAIN_FORCED_BY_USER: sb.append("f"); + if (subReason > 0) { + // Although not expected and shouldn't happen, this could potentially have a + // sub-reason if the system tries to give a reason when applying the + // FORCED_BY_USER reason. The sub-reason is undefined (though most likely a + // REASON_SUB_FORCED_SYSTEM_FLAG_ sub-reason), but it's better to note it in the + // log than to exclude it altogether. + sb.append("-").append(Integer.toBinaryString(subReason)); + } break; case REASON_MAIN_PREDICTED: sb.append("p"); diff --git a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java index 624c3de650aa9..86b162087f612 100644 --- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java +++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java @@ -1389,6 +1389,21 @@ public class AppStandbyControllerTests { getStandbyBucketReason(PACKAGE_1)); } + @Test + public void testRestrictApp_MainReason() throws Exception { + mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE, + REASON_MAIN_DEFAULT); + mInjector.mElapsedRealtime += 4 * RESTRICTED_THRESHOLD; + + mController.restrictApp(PACKAGE_1, USER_ID, REASON_MAIN_PREDICTED, 0); + // Call should be ignored. + assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController, PACKAGE_1)); + + mController.restrictApp(PACKAGE_1, USER_ID, REASON_MAIN_FORCED_BY_USER, 0); + // Call should go through + assertEquals(STANDBY_BUCKET_RESTRICTED, getStandbyBucket(mController, PACKAGE_1)); + } + @Test public void testAddActiveDeviceAdmin() throws Exception { assertActiveAdmins(USER_ID, (String[]) null);