From 32bef9c5caef0d40aafd7c14c8195cda3c411ee4 Mon Sep 17 00:00:00 2001 From: Jing Ji Date: Thu, 24 Mar 2022 10:09:11 -0700 Subject: [PATCH] Use the reason code from standby bucketing in bg restriction if needed If the bg restriction level is inferred from the app standby bucket, use the reason code from the app standby as the one of being in such a bg restriction level. Also fixed an issue where we'd need to restrict the offending bg apps when it's backgrounded. Bug: 225951652 Bug: 203105544 Test: atest FrameworksMockingServicesTests:BackgroundRestrictionTest Change-Id: I5925e90e19d2f8c99d43c0637560d8629c887ed4 --- .../server/usage/AppStandbyInternal.java | 7 +++ .../server/usage/AppStandbyController.java | 4 +- .../server/am/AppRestrictionController.java | 51 +++++++++++++++---- 3 files changed, 50 insertions(+), 12 deletions(-) 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 56811076e0136..c3fc4d1603b0a 100644 --- a/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java +++ b/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java @@ -1,6 +1,7 @@ package com.android.server.usage; import android.annotation.CurrentTimeMillisLong; +import android.annotation.ElapsedRealtimeLong; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; @@ -149,6 +150,12 @@ public interface AppStandbyInternal { int getAppMinStandbyBucket(String packageName, int appId, int userId, boolean shouldObfuscateInstantApps); + /** + * Return the bucketing reason code of the given app. + */ + int getAppStandbyBucketReason(@NonNull String packageName, @UserIdInt int userId, + @ElapsedRealtimeLong long elapsedRealtime); + /** * 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 1e4ecc2adfb2d..b520102b28309 100644 --- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java +++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java @@ -1436,8 +1436,8 @@ public class AppStandbyController } } - @VisibleForTesting - int getAppStandbyBucketReason(String packageName, int userId, long elapsedRealtime) { + @Override + public int getAppStandbyBucketReason(String packageName, int userId, long elapsedRealtime) { synchronized (mAppIdleLock) { return mAppIdleHistory.getAppStandbyReason(packageName, userId, elapsedRealtime); } diff --git a/services/core/java/com/android/server/am/AppRestrictionController.java b/services/core/java/com/android/server/am/AppRestrictionController.java index 41ff08309d89e..b8fb9e85ac08b 100644 --- a/services/core/java/com/android/server/am/AppRestrictionController.java +++ b/services/core/java/com/android/server/am/AppRestrictionController.java @@ -1086,6 +1086,12 @@ public final class AppRestrictionController { } final @RestrictionLevel int level = calcAppRestrictionLevel( userId, uid, info.mPackageName, info.mStandbyBucket, false, false); + if (DEBUG_BG_RESTRICTION_CONTROLLER) { + Slog.i(TAG, "Proposed restriction level of " + info.mPackageName + "/" + + UserHandle.formatUid(uid) + ": " + + ActivityManager.restrictionLevelToName(level) + + " " + info.mStandbyBucket); + } applyRestrictionLevel(info.mPackageName, uid, level, info.mStandbyBucket, true, reason, subReason); } @@ -1185,6 +1191,25 @@ public final class AppRestrictionController { return level; } + private static @RestrictionLevel int standbyBucketToRestrictionLevel( + @UsageStatsManager.StandbyBuckets int standbyBucket) { + switch (standbyBucket) { + case STANDBY_BUCKET_EXEMPTED: + return RESTRICTION_LEVEL_EXEMPTED; + case STANDBY_BUCKET_NEVER: + return RESTRICTION_LEVEL_BACKGROUND_RESTRICTED; + case STANDBY_BUCKET_ACTIVE: + case STANDBY_BUCKET_WORKING_SET: + case STANDBY_BUCKET_FREQUENT: + case STANDBY_BUCKET_RARE: + return RESTRICTION_LEVEL_ADAPTIVE_BUCKET; + case STANDBY_BUCKET_RESTRICTED: + return RESTRICTION_LEVEL_RESTRICTED_BUCKET; + default: + return RESTRICTION_LEVEL_UNKNOWN; + } + } + /** * Get the restriction level of the given UID, if it hosts multiple packages, * return least restricted one (or if any of them is exempted). @@ -1380,12 +1405,23 @@ public final class AppRestrictionController { int curBucket, boolean allowUpdateBucket, int reason, int subReason) { int curLevel; int prevReason; + final AppStandbyInternal appStandbyInternal = mInjector.getAppStandbyInternal(); synchronized (mSettingsLock) { curLevel = getRestrictionLevel(uid, pkgName); if (curLevel == level) { // Nothing to do. return; } + final int levelOfBucket = standbyBucketToRestrictionLevel(curBucket); + if (levelOfBucket == level) { + // If the standby bucket yield the same level, use the reason from standby bucket. + final int bucketReason = appStandbyInternal.getAppStandbyBucketReason( + pkgName, UserHandle.getUserId(uid), SystemClock.elapsedRealtime()); + if (bucketReason != 0) { + reason = bucketReason & REASON_MAIN_MASK; + subReason = bucketReason & REASON_SUB_MASK; + } + } if (DEBUG_BG_RESTRICTION_CONTROLLER) { Slog.i(TAG, "Updating the restriction level of " + pkgName + "/" + UserHandle.formatUid(uid) + " from " @@ -1393,7 +1429,6 @@ public final class AppRestrictionController { + ActivityManager.restrictionLevelToName(level) + " reason=" + reason + ", subReason=" + subReason); } - prevReason = mRestrictionSettings.getReason(pkgName, uid); mRestrictionSettings.update(pkgName, uid, level, reason, subReason); } @@ -1401,7 +1436,6 @@ public final class AppRestrictionController { if (!allowUpdateBucket || curBucket == STANDBY_BUCKET_EXEMPTED) { return; } - final AppStandbyInternal appStandbyInternal = mInjector.getAppStandbyInternal(); if (level >= RESTRICTION_LEVEL_RESTRICTED_BUCKET && curLevel < RESTRICTION_LEVEL_RESTRICTED_BUCKET) { if (!mConstantsObserver.mRestrictedBucketEnabled) { @@ -1422,8 +1456,10 @@ public final class AppRestrictionController { final int index = mActiveUids.indexOfKey(uid, pkgName); if (index >= 0) { // It's currently active, enqueue it. + final int localReason = reason; + final int localSubReason = subReason; mActiveUids.add(uid, pkgName, () -> appStandbyInternal.restrictApp( - pkgName, UserHandle.getUserId(uid), reason, subReason)); + pkgName, UserHandle.getUserId(uid), localReason, localSubReason)); doIt = false; } } @@ -1841,9 +1877,6 @@ public final class AppRestrictionController { } void handleUidInactive(int uid, boolean disabled) { - if (!mConstantsObserver.mBgAutoRestrictedBucket) { - return; - } final ArrayList pendingTasks = mTmpRunnables; synchronized (mSettingsLock) { final int index = mActiveUids.indexOfKey(uid); @@ -1866,14 +1899,12 @@ public final class AppRestrictionController { } void handleUidActive(int uid) { - if (!mConstantsObserver.mBgAutoRestrictedBucket) { - return; - } synchronized (mSettingsLock) { final AppStandbyInternal appStandbyInternal = mInjector.getAppStandbyInternal(); final int userId = UserHandle.getUserId(uid); mRestrictionSettings.forEachPackageInUidLocked(uid, (pkgName, level, reason) -> { - if (level == RESTRICTION_LEVEL_BACKGROUND_RESTRICTED) { + if (mConstantsObserver.mBgAutoRestrictedBucket + && level == RESTRICTION_LEVEL_BACKGROUND_RESTRICTED) { mActiveUids.add(uid, pkgName, () -> appStandbyInternal.restrictApp(pkgName, userId, reason & REASON_MAIN_MASK, reason & REASON_SUB_MASK)); } else {