Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3bf51b99 authored by Kweku Adams's avatar Kweku Adams Committed by Automerger Merge Worker
Browse files

Merge "Add master switch to enable/disable RESTRICTED bucket." into rvc-dev...

Merge "Add master switch to enable/disable RESTRICTED bucket." into rvc-dev am: 86a71e6e am: 158d28f1 am: 3acd3c40

Change-Id: I2f5e619bb19a358ef4de8c22401955e345affbb7
parents b0102b51 3acd3c40
Loading
Loading
Loading
Loading
+37 −3
Original line number Original line Diff line number Diff line
@@ -293,6 +293,13 @@ public class AppStandbyController implements AppStandbyInternal {
     * {@link #setAppStandbyBucket(String, int, int, int, int)} will not be propagated.
     * {@link #setAppStandbyBucket(String, int, int, int, int)} will not be propagated.
     */
     */
    boolean mLinkCrossProfileApps;
    boolean mLinkCrossProfileApps;
    /**
     * Whether we should allow apps into the
     * {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RESTRICTED} bucket or not.
     * If false, any attempts to put an app into the bucket will put the app into the
     * {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RARE} bucket instead.
     */
    private boolean mAllowRestrictedBucket;


    private volatile boolean mAppIdleEnabled;
    private volatile boolean mAppIdleEnabled;
    private boolean mIsCharging;
    private boolean mIsCharging;
@@ -688,6 +695,10 @@ public class AppStandbyController implements AppStandbyInternal {
                    return;
                    return;
                }
                }
                final int oldBucket = app.currentBucket;
                final int oldBucket = app.currentBucket;
                if (oldBucket == STANDBY_BUCKET_NEVER) {
                    // None of this should bring an app out of the NEVER bucket.
                    return;
                }
                int newBucket = Math.max(oldBucket, STANDBY_BUCKET_ACTIVE); // Undo EXEMPTED
                int newBucket = Math.max(oldBucket, STANDBY_BUCKET_ACTIVE); // Undo EXEMPTED
                boolean predictionLate = predictionTimedOut(app, elapsedRealtime);
                boolean predictionLate = predictionTimedOut(app, elapsedRealtime);
                // Compute age-based bucket
                // Compute age-based bucket
@@ -743,11 +754,18 @@ public class AppStandbyController implements AppStandbyInternal {
                        Slog.d(TAG, "Bringing down to RESTRICTED due to timeout");
                        Slog.d(TAG, "Bringing down to RESTRICTED due to timeout");
                    }
                    }
                }
                }
                if (newBucket == STANDBY_BUCKET_RESTRICTED && !mAllowRestrictedBucket) {
                    newBucket = STANDBY_BUCKET_RARE;
                    // Leave the reason alone.
                    if (DEBUG) {
                        Slog.d(TAG, "Bringing up from RESTRICTED to RARE due to off switch");
                    }
                }
                if (DEBUG) {
                if (DEBUG) {
                    Slog.d(TAG, "     Old bucket=" + oldBucket
                    Slog.d(TAG, "     Old bucket=" + oldBucket
                            + ", newBucket=" + newBucket);
                            + ", newBucket=" + newBucket);
                }
                }
                if (oldBucket < newBucket || predictionLate) {
                if (oldBucket != newBucket || predictionLate) {
                    mAppIdleHistory.setAppStandbyBucket(packageName, userId,
                    mAppIdleHistory.setAppStandbyBucket(packageName, userId,
                            elapsedRealtime, newBucket, reason);
                            elapsedRealtime, newBucket, reason);
                    maybeInformListeners(packageName, userId, elapsedRealtime,
                    maybeInformListeners(packageName, userId, elapsedRealtime,
@@ -1197,8 +1215,8 @@ public class AppStandbyController implements AppStandbyInternal {


        final int reason = REASON_MAIN_FORCED_BY_SYSTEM | (REASON_SUB_MASK & restrictReason);
        final int reason = REASON_MAIN_FORCED_BY_SYSTEM | (REASON_SUB_MASK & restrictReason);
        final long nowElapsed = mInjector.elapsedRealtime();
        final long nowElapsed = mInjector.elapsedRealtime();
        setAppStandbyBucket(packageName, userId, STANDBY_BUCKET_RESTRICTED, reason,
        final int bucket = mAllowRestrictedBucket ? STANDBY_BUCKET_RESTRICTED : STANDBY_BUCKET_RARE;
                nowElapsed, false);
        setAppStandbyBucket(packageName, userId, bucket, reason, nowElapsed, false);
    }
    }


    @Override
    @Override
@@ -1268,6 +1286,9 @@ public class AppStandbyController implements AppStandbyInternal {
                Slog.e(TAG, "Tried to set bucket of uninstalled app: " + packageName);
                Slog.e(TAG, "Tried to set bucket of uninstalled app: " + packageName);
                return;
                return;
            }
            }
            if (newBucket == STANDBY_BUCKET_RESTRICTED && !mAllowRestrictedBucket) {
                newBucket = STANDBY_BUCKET_RARE;
            }
            AppIdleHistory.AppUsageHistory app = mAppIdleHistory.getAppUsageHistory(packageName,
            AppIdleHistory.AppUsageHistory app = mAppIdleHistory.getAppUsageHistory(packageName,
                    userId, elapsedRealtime);
                    userId, elapsedRealtime);
            boolean predicted = (reason & REASON_MAIN_MASK) == REASON_MAIN_PREDICTED;
            boolean predicted = (reason & REASON_MAIN_MASK) == REASON_MAIN_PREDICTED;
@@ -1386,6 +1407,7 @@ public class AppStandbyController implements AppStandbyInternal {
                        Slog.d(TAG, "    Keeping at WORKING_SET due to min timeout");
                        Slog.d(TAG, "    Keeping at WORKING_SET due to min timeout");
                    }
                    }
                } else if (newBucket == STANDBY_BUCKET_RARE
                } else if (newBucket == STANDBY_BUCKET_RARE
                        && mAllowRestrictedBucket
                        && getBucketForLocked(packageName, userId, elapsedRealtime)
                        && getBucketForLocked(packageName, userId, elapsedRealtime)
                        == STANDBY_BUCKET_RESTRICTED) {
                        == STANDBY_BUCKET_RESTRICTED) {
                    // Prediction doesn't think the app will be used anytime soon and
                    // Prediction doesn't think the app will be used anytime soon and
@@ -1727,6 +1749,8 @@ public class AppStandbyController implements AppStandbyInternal {


        pw.println();
        pw.println();
        pw.print("mAppIdleEnabled="); pw.print(mAppIdleEnabled);
        pw.print("mAppIdleEnabled="); pw.print(mAppIdleEnabled);
        pw.print(" mAllowRestrictedBucket=");
        pw.print(mAllowRestrictedBucket);
        pw.print(" mIsCharging=");
        pw.print(" mIsCharging=");
        pw.print(mIsCharging);
        pw.print(mIsCharging);
        pw.println();
        pw.println();
@@ -1828,6 +1852,12 @@ public class AppStandbyController implements AppStandbyInternal {
            return mPowerWhitelistManager.isWhitelisted(packageName, false);
            return mPowerWhitelistManager.isWhitelisted(packageName, false);
        }
        }


        boolean isRestrictedBucketEnabled() {
            return Global.getInt(mContext.getContentResolver(),
                    Global.ENABLE_RESTRICTED_BUCKET,
                    Global.DEFAULT_ENABLE_RESTRICTED_BUCKET) == 1;
        }

        File getDataSystemDirectory() {
        File getDataSystemDirectory() {
            return Environment.getDataSystemDirectory();
            return Environment.getDataSystemDirectory();
        }
        }
@@ -2066,6 +2096,8 @@ public class AppStandbyController implements AppStandbyInternal {
            final ContentResolver cr = mContext.getContentResolver();
            final ContentResolver cr = mContext.getContentResolver();
            cr.registerContentObserver(Global.getUriFor(Global.APP_IDLE_CONSTANTS), false, this);
            cr.registerContentObserver(Global.getUriFor(Global.APP_IDLE_CONSTANTS), false, this);
            cr.registerContentObserver(Global.getUriFor(Global.APP_STANDBY_ENABLED), false, this);
            cr.registerContentObserver(Global.getUriFor(Global.APP_STANDBY_ENABLED), false, this);
            cr.registerContentObserver(Global.getUriFor(Global.ENABLE_RESTRICTED_BUCKET),
                    false, this);
            cr.registerContentObserver(Global.getUriFor(Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED),
            cr.registerContentObserver(Global.getUriFor(Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED),
                    false, this);
                    false, this);
        }
        }
@@ -2164,6 +2196,8 @@ public class AppStandbyController implements AppStandbyInternal {
                mLinkCrossProfileApps = mParser.getBoolean(
                mLinkCrossProfileApps = mParser.getBoolean(
                        KEY_CROSS_PROFILE_APPS_SHARE_STANDBY_BUCKETS,
                        KEY_CROSS_PROFILE_APPS_SHARE_STANDBY_BUCKETS,
                        DEFAULT_CROSS_PROFILE_APPS_SHARE_STANDBY_BUCKETS);
                        DEFAULT_CROSS_PROFILE_APPS_SHARE_STANDBY_BUCKETS);

                mAllowRestrictedBucket = mInjector.isRestrictedBucketEnabled();
            }
            }


            // Check if app_idle_enabled has changed. Do this after getting the rest of the settings
            // Check if app_idle_enabled has changed. Do this after getting the rest of the settings
+17 −1
Original line number Original line Diff line number Diff line
@@ -11955,6 +11955,22 @@ public final class Settings {
        public static final String ADAPTIVE_BATTERY_MANAGEMENT_ENABLED =
        public static final String ADAPTIVE_BATTERY_MANAGEMENT_ENABLED =
                "adaptive_battery_management_enabled";
                "adaptive_battery_management_enabled";
        /**
         * Whether or not apps are allowed into the
         * {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RESTRICTED} bucket.
         * Type: int (0 for false, 1 for true)
         * Default: {@value #DEFAULT_ENABLE_RESTRICTED_BUCKET}
         *
         * @hide
         */
        public static final String ENABLE_RESTRICTED_BUCKET = "enable_restricted_bucket";
        /**
         * @see #ENABLE_RESTRICTED_BUCKET
         * @hide
         */
        public static final int DEFAULT_ENABLE_RESTRICTED_BUCKET = 1;
        /**
        /**
         * Whether or not app auto restriction is enabled. When it is enabled, settings app will
         * Whether or not app auto restriction is enabled. When it is enabled, settings app will
         * auto restrict the app if it has bad behavior (e.g. hold wakelock for long time).
         * auto restrict the app if it has bad behavior (e.g. hold wakelock for long time).
+1 −0
Original line number Original line Diff line number Diff line
@@ -264,6 +264,7 @@ public class SettingsBackupTest {
                    Settings.Global.ENABLE_DELETION_HELPER_NO_THRESHOLD_TOGGLE,
                    Settings.Global.ENABLE_DELETION_HELPER_NO_THRESHOLD_TOGGLE,
                    Settings.Global.ENABLE_DISKSTATS_LOGGING,
                    Settings.Global.ENABLE_DISKSTATS_LOGGING,
                    Settings.Global.ENABLE_EPHEMERAL_FEATURE,
                    Settings.Global.ENABLE_EPHEMERAL_FEATURE,
                    Settings.Global.ENABLE_RESTRICTED_BUCKET,
                    Settings.Global.DYNAMIC_POWER_SAVINGS_ENABLED,
                    Settings.Global.DYNAMIC_POWER_SAVINGS_ENABLED,
                    Settings.Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD,
                    Settings.Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD,
                    Settings.Global.SMART_REPLIES_IN_NOTIFICATIONS_FLAGS,
                    Settings.Global.SMART_REPLIES_IN_NOTIFICATIONS_FLAGS,
+52 −0
Original line number Original line Diff line number Diff line
@@ -165,6 +165,7 @@ public class AppStandbyControllerTests {
        long mElapsedRealtime;
        long mElapsedRealtime;
        boolean mIsAppIdleEnabled = true;
        boolean mIsAppIdleEnabled = true;
        boolean mIsCharging;
        boolean mIsCharging;
        boolean mIsRestrictedBucketEnabled = true;
        List<String> mNonIdleWhitelistApps = new ArrayList<>();
        List<String> mNonIdleWhitelistApps = new ArrayList<>();
        boolean mDisplayOn;
        boolean mDisplayOn;
        DisplayManager.DisplayListener mDisplayListener;
        DisplayManager.DisplayListener mDisplayListener;
@@ -211,6 +212,11 @@ public class AppStandbyControllerTests {
            return mNonIdleWhitelistApps.contains(packageName);
            return mNonIdleWhitelistApps.contains(packageName);
        }
        }


        @Override
        boolean isRestrictedBucketEnabled() {
            return mIsRestrictedBucketEnabled;
        }

        @Override
        @Override
        File getDataSystemDirectory() {
        File getDataSystemDirectory() {
            return new File(getContext().getFilesDir(), Long.toString(Math.randomLongInternal()));
            return new File(getContext().getFilesDir(), Long.toString(Math.randomLongInternal()));
@@ -511,6 +517,10 @@ public class AppStandbyControllerTests {
        assertEquals(bucket, getStandbyBucket(mController, PACKAGE_1));
        assertEquals(bucket, getStandbyBucket(mController, PACKAGE_1));
    }
    }


    private void assertNotBucket(int bucket) {
        assertNotEquals(bucket, getStandbyBucket(mController, PACKAGE_1));
    }

    @Test
    @Test
    public void testBuckets() throws Exception {
    public void testBuckets() throws Exception {
        assertTimeout(mController, 0, STANDBY_BUCKET_NEVER);
        assertTimeout(mController, 0, STANDBY_BUCKET_NEVER);
@@ -945,6 +955,48 @@ public class AppStandbyControllerTests {
        assertBucket(STANDBY_BUCKET_RESTRICTED);
        assertBucket(STANDBY_BUCKET_RESTRICTED);
    }
    }


    @Test
    public void testRestrictedBucketDisabled() {
        mInjector.mIsRestrictedBucketEnabled = false;
        // Get the controller to read the new value. Capturing the ContentObserver isn't possible
        // at the moment.
        mController.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);

        reportEvent(mController, USER_INTERACTION, mInjector.mElapsedRealtime, PACKAGE_1);
        mInjector.mElapsedRealtime += RESTRICTED_THRESHOLD;

        // Nothing should be able to put it into the RESTRICTED bucket.
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RESTRICTED,
                REASON_MAIN_TIMEOUT);
        assertNotBucket(STANDBY_BUCKET_RESTRICTED);
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RESTRICTED,
                REASON_MAIN_PREDICTED);
        assertNotBucket(STANDBY_BUCKET_RESTRICTED);
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RESTRICTED,
                REASON_MAIN_FORCED_BY_SYSTEM);
        assertNotBucket(STANDBY_BUCKET_RESTRICTED);
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RESTRICTED,
                REASON_MAIN_FORCED_BY_USER);
        assertNotBucket(STANDBY_BUCKET_RESTRICTED);
    }

    @Test
    public void testRestrictedBucket_EnabledToDisabled() {
        reportEvent(mController, USER_INTERACTION, mInjector.mElapsedRealtime, PACKAGE_1);
        mInjector.mElapsedRealtime += RESTRICTED_THRESHOLD;
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RESTRICTED,
                REASON_MAIN_FORCED_BY_SYSTEM);
        assertBucket(STANDBY_BUCKET_RESTRICTED);

        mInjector.mIsRestrictedBucketEnabled = false;
        // Get the controller to read the new value. Capturing the ContentObserver isn't possible
        // at the moment.
        mController.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);

        mController.checkIdleStates(USER_ID);
        assertNotBucket(STANDBY_BUCKET_RESTRICTED);
    }

    @Test
    @Test
    public void testPredictionRaiseFromRestrictedTimeout_highBucket() {
    public void testPredictionRaiseFromRestrictedTimeout_highBucket() {
        reportEvent(mController, USER_INTERACTION, mInjector.mElapsedRealtime, PACKAGE_1);
        reportEvent(mController, USER_INTERACTION, mInjector.mElapsedRealtime, PACKAGE_1);