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 {