From 9df9e30727b510fb37790085554e70423834a42b Mon Sep 17 00:00:00 2001 From: Michael Wachenschwanz Date: Tue, 15 Sep 2020 11:12:13 -0700 Subject: [PATCH] Prevent default wellbeing app from falling below WORKING_SET bucket Bug: 166301584 Test: atest AppStandbyControllerTests Change-Id: I5ef67308cabbe43801103e888165d488f4888ab9 --- .../server/usage/AppStandbyController.java | 16 ++++++++++ .../usage/AppStandbyControllerTests.java | 32 +++++++++++++++++++ 2 files changed, 48 insertions(+) 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 c033138d5f20a..22e1eec8883d6 100644 --- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java +++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java @@ -1159,6 +1159,10 @@ public class AppStandbyController implements AppStandbyInternal { if (isDeviceProvisioningPackage(packageName)) { return STANDBY_BUCKET_EXEMPTED; } + + if (mInjector.isWellbeingPackage(packageName)) { + return STANDBY_BUCKET_WORKING_SET; + } } // Check this last, as it can be the most expensive check @@ -1966,6 +1970,7 @@ public class AppStandbyController implements AppStandbyInternal { */ @GuardedBy("mPowerWhitelistedApps") private final ArraySet mPowerWhitelistedApps = new ArraySet<>(); + private String mWellbeingApp = null; Injector(Context context, Looper looper) { mContext = context; @@ -1999,6 +2004,9 @@ public class AppStandbyController implements AppStandbyInternal { if (activityManager.isLowRamDevice() || ActivityManager.isSmallBatteryDevice()) { mAutoRestrictedBucketDelayMs = 12 * ONE_HOUR; } + + final PackageManager packageManager = mContext.getPackageManager(); + mWellbeingApp = packageManager.getWellbeingPackageName(); } mBootPhase = phase; } @@ -2043,6 +2051,14 @@ public class AppStandbyController implements AppStandbyInternal { } } + /** + * Returns {@code true} if the supplied package is the wellbeing app. Otherwise, + * returns {@code false}. + */ + boolean isWellbeingPackage(String packageName) { + return mWellbeingApp != null && mWellbeingApp.equals(packageName); + } + void updatePowerWhitelistCache() { try { // Don't call out to DeviceIdleController with the lock held. 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 2aeab209162ab..2c645268e190f 100644 --- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java +++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java @@ -112,6 +112,8 @@ public class AppStandbyControllerTests { private static final int UID_SYSTEM_HEADFULL = 10002; private static final String PACKAGE_SYSTEM_HEADLESS = "com.example.system.headless"; private static final int UID_SYSTEM_HEADLESS = 10003; + private static final String PACKAGE_WELLBEING = "com.example.wellbeing"; + private static final int UID_WELLBEING = 10004; private static final int USER_ID = 0; private static final int USER_ID2 = 10; private static final UserHandle USER_HANDLE_USER2 = new UserHandle(USER_ID2); @@ -220,6 +222,11 @@ public class AppStandbyControllerTests { return mNonIdleWhitelistApps.contains(packageName); } + @Override + boolean isWellbeingPackage(String packageName) { + return PACKAGE_WELLBEING.equals(packageName); + } + @Override void updatePowerWhitelistCache() { } @@ -332,6 +339,12 @@ public class AppStandbyControllerTests { pish.packageName = PACKAGE_SYSTEM_HEADLESS; packages.add(pish); + PackageInfo piw = new PackageInfo(); + piw.applicationInfo = new ApplicationInfo(); + piw.applicationInfo.uid = UID_WELLBEING; + piw.packageName = PACKAGE_WELLBEING; + packages.add(piw); + doReturn(packages).when(mockPm).getInstalledPackagesAsUser(anyInt(), anyInt()); try { for (int i = 0; i < packages.size(); ++i) { @@ -1520,6 +1533,25 @@ public class AppStandbyControllerTests { assertBucket(STANDBY_BUCKET_RARE, PACKAGE_1); } + @Test + public void testWellbeingAppElevated() { + reportEvent(mController, USER_INTERACTION, mInjector.mElapsedRealtime, PACKAGE_WELLBEING); + assertBucket(STANDBY_BUCKET_ACTIVE, PACKAGE_WELLBEING); + reportEvent(mController, USER_INTERACTION, mInjector.mElapsedRealtime, PACKAGE_1); + assertBucket(STANDBY_BUCKET_ACTIVE, PACKAGE_1); + mInjector.mElapsedRealtime += RESTRICTED_THRESHOLD; + + // Make sure the default wellbeing app does not get lowered below WORKING_SET. + mController.setAppStandbyBucket(PACKAGE_WELLBEING, USER_ID, STANDBY_BUCKET_RARE, + REASON_MAIN_TIMEOUT); + assertBucket(STANDBY_BUCKET_WORKING_SET, PACKAGE_WELLBEING); + + // A non default wellbeing app should be able to fall lower than WORKING_SET. + mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RARE, + REASON_MAIN_TIMEOUT); + assertBucket(STANDBY_BUCKET_RARE, PACKAGE_1); + } + private String getAdminAppsStr(int userId) { return getAdminAppsStr(userId, mController.getActiveAdminAppsForTest(userId)); }