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

Commit 7ef29300 authored by Jing Ji's avatar Jing Ji
Browse files

Suppress the prompt for the apps with high bg battery usage

.. but it has an active FGS with visible notifications.

Bug: 203105544
Test: atest FrameworksMockingServicesTests:BackgroundRestrictionTest
Change-Id: I86b78bdbdc64b1dc4b94f3499db752895149dac5
parent 923eb82c
Loading
Loading
Loading
Loading
+45 −1
Original line number Diff line number Diff line
@@ -185,6 +185,12 @@ public final class AppRestrictionController {
     */
    private static final boolean ENABLE_SHOW_FOREGROUND_SERVICE_MANAGER = true;

    /**
     * Whether or not to show the action to the foreground service manager when
     * posting the notification for background restriction.
     */
    private static final boolean ENABLE_SHOW_FGS_MANAGER_ACTION_ON_BG_RESTRICTION = false;

    private final Context mContext;
    private final HandlerThread mBgHandlerThread;
    private final BgHandler mBgHandler;
@@ -664,6 +670,14 @@ public final class AppRestrictionController {
        static final String KEY_BG_PROMPT_FGS_WITH_NOTIFICATION_TO_BG_RESTRICTED =
                DEVICE_CONFIG_SUBNAMESPACE_PREFIX + "prompt_fgs_with_noti_to_bg_restricted";

        /**
         * The behavior for an app with a FGS and its notification is still showing, when the system
         * detects it's running for a very long time, should we prompt the user.
         * {@code true} - we'll show the prompt to user, {@code false} - we'll not show it.
         */
        static final String KEY_BG_PROMPT_FGS_WITH_NOTIFICATION_ON_LONG_RUNNING =
                DEVICE_CONFIG_SUBNAMESPACE_PREFIX + "prompt_fgs_with_noti_on_long_running";

        /**
         * The list of packages to be exempted from all these background restrictions.
         */
@@ -685,6 +699,11 @@ public final class AppRestrictionController {
         */
        static final long DEFAULT_BG_LONG_FGS_NOTIFICATION_MINIMAL_INTERVAL_MS = 30 * ONE_DAY;

        /**
         * Default value to {@link #mBgPromptFgsWithNotiOnLongRunning}.
         */
        static final boolean DEFAULT_BG_PROMPT_FGS_WITH_NOTIFICATION_ON_LONG_RUNNING = false;

        /**
         * Default value to {@link #mBgPromptFgsWithNotiToBgRestricted}.
         */
@@ -710,6 +729,11 @@ public final class AppRestrictionController {
         */
        volatile boolean mBgPromptFgsWithNotiToBgRestricted;

        /**
         * @see #KEY_BG_PROMPT_FGS_WITH_NOTIFICATION_ON_LONG_RUNNING.
         */
        volatile boolean mBgPromptFgsWithNotiOnLongRunning;

        ConstantsObserver(Handler handler, Context context) {
            super(handler);
            mDefaultBgPromptFgsWithNotiToBgRestricted = context.getResources().getBoolean(
@@ -735,6 +759,9 @@ public final class AppRestrictionController {
                    case KEY_BG_PROMPT_FGS_WITH_NOTIFICATION_TO_BG_RESTRICTED:
                        updateBgPromptFgsWithNotiToBgRestricted();
                        break;
                    case KEY_BG_PROMPT_FGS_WITH_NOTIFICATION_ON_LONG_RUNNING:
                        updateBgPromptFgsWithNotiOnLongRunning();
                        break;
                    case KEY_BG_RESTRICTION_EXEMPTED_PACKAGES:
                        updateBgRestrictionExemptedPackages();
                        break;
@@ -771,6 +798,7 @@ public final class AppRestrictionController {
            updateBgAbusiveNotificationMinimalInterval();
            updateBgLongFgsNotificationMinimalInterval();
            updateBgPromptFgsWithNotiToBgRestricted();
            updateBgPromptFgsWithNotiOnLongRunning();
            updateBgRestrictionExemptedPackages();
        }

@@ -806,6 +834,13 @@ public final class AppRestrictionController {
                    mDefaultBgPromptFgsWithNotiToBgRestricted);
        }

        private void updateBgPromptFgsWithNotiOnLongRunning() {
            mBgPromptFgsWithNotiOnLongRunning = DeviceConfig.getBoolean(
                    DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
                    KEY_BG_PROMPT_FGS_WITH_NOTIFICATION_ON_LONG_RUNNING,
                    DEFAULT_BG_PROMPT_FGS_WITH_NOTIFICATION_ON_LONG_RUNNING);
        }

        private void updateBgRestrictionExemptedPackages() {
            final String settings = DeviceConfig.getString(
                    DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
@@ -1685,7 +1720,9 @@ public final class AppRestrictionController {
                    return;
                }
            }
            if (ENABLE_SHOW_FOREGROUND_SERVICE_MANAGER && hasForegroundServices) {
            if (ENABLE_SHOW_FOREGROUND_SERVICE_MANAGER
                    && ENABLE_SHOW_FGS_MANAGER_ACTION_ON_BG_RESTRICTION
                    && hasForegroundServices) {
                final Intent trampoline = new Intent(ACTION_FGS_MANAGER_TRAMPOLINE);
                trampoline.setPackage("android");
                trampoline.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
@@ -1710,6 +1747,13 @@ public final class AppRestrictionController {

        void postLongRunningFgsIfNecessary(String packageName, int uid) {
            PendingIntent pendingIntent;
            if (!mBgController.mConstantsObserver.mBgPromptFgsWithNotiOnLongRunning
                    && mBgController.hasForegroundServiceNotifications(packageName, uid)) {
                if (DEBUG_BG_RESTRICTION_CONTROLLER) {
                    Slog.i(TAG, "Not prompt long-running due to FGS with notification");
                }
                return;
            }
            if (ENABLE_SHOW_FOREGROUND_SERVICE_MANAGER) {
                final Intent intent = new Intent(ACTION_SHOW_FOREGROUND_SERVICE_MANAGER);
                intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+51 −0
Original line number Diff line number Diff line
@@ -955,6 +955,8 @@ public final class BackgroundRestrictionTest {
        final int testUid2 = UserHandle.getUid(testUser2, TEST_PACKAGE_APPID_BASE + testPkgIndex2);
        final int testPid2 = 1235;

        final int fgsNotificationId = 1000;

        final long windowMs = 2_000;
        final long thresholdMs = 1_000;
        final long shortMs = 100;
@@ -962,6 +964,7 @@ public final class BackgroundRestrictionTest {
        DeviceConfigSession<Boolean> longRunningFGSMonitor = null;
        DeviceConfigSession<Long> longRunningFGSWindow = null;
        DeviceConfigSession<Long> longRunningFGSThreshold = null;
        DeviceConfigSession<Boolean> longRunningFGSWithNotification = null;

        try {
            longRunningFGSMonitor = new DeviceConfigSession<>(
@@ -985,6 +988,13 @@ public final class BackgroundRestrictionTest {
                    AppFGSPolicy.DEFAULT_BG_FGS_LONG_RUNNING_THRESHOLD);
            longRunningFGSThreshold.set(thresholdMs);

            longRunningFGSWithNotification = new DeviceConfigSession<>(
                    DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
                    ConstantsObserver.KEY_BG_PROMPT_FGS_WITH_NOTIFICATION_ON_LONG_RUNNING,
                    DeviceConfig::getBoolean,
                    ConstantsObserver.DEFAULT_BG_PROMPT_FGS_WITH_NOTIFICATION_ON_LONG_RUNNING);
            longRunningFGSWithNotification.set(true);

            // Basic case
            mAppFGSTracker.onForegroundServiceStateChanged(testPkgName1, testUid1,
                    testPid1, true);
@@ -1084,10 +1094,42 @@ public final class BackgroundRestrictionTest {
            mAppFGSTracker.onForegroundServiceStateChanged(testPkgName1, testUid1,
                    testPid1, false);
            checkNotificationGone(testPkgName1, timeout(windowMs), notificationId);

            // Start over with the flag to not show prompt when it has an active notification.
            clearInvocations(mInjector.getNotificationManager());
            mBgRestrictionController.resetRestrictionSettings();
            longRunningFGSWithNotification.set(false);

            // Start an FGS with notification.
            mAppFGSTracker.onForegroundServiceStateChanged(testPkgName1, testUid1,
                    testPid1, true);
            mAppFGSTracker.onForegroundServiceNotificationUpdated(
                    testPkgName1, testUid1, fgsNotificationId);
            mAppFGSTracker.mNotificationListener.onNotificationPosted(new StatusBarNotification(
                    testPkgName1, null, fgsNotificationId, null, testUid1, testPid1,
                    new Notification(), UserHandle.of(testUser1), null, mCurrentTimeMillis), null);

            // Verify we won't prompt the user because it has a visible FGS notification.
            checkNotificationShown(
                    new String[] {testPkgName1}, timeout(windowMs * 2).times(0), false);

            // Pretend we have the notification dismissed.
            mAppFGSTracker.onForegroundServiceNotificationUpdated(
                    testPkgName1, testUid1, -fgsNotificationId);

            // Verify we have the notification.
            notificationId = checkNotificationShown(
                    new String[] {testPkgName1}, timeout(windowMs * 2).times(2), true)[0];

            // Stop the FGS.
            mAppFGSTracker.onForegroundServiceStateChanged(testPkgName1, testUid1,
                    testPid1, false);
            checkNotificationGone(testPkgName1, timeout(windowMs), notificationId);
        } finally {
            closeIfNotNull(longRunningFGSMonitor);
            closeIfNotNull(longRunningFGSWindow);
            closeIfNotNull(longRunningFGSThreshold);
            closeIfNotNull(longRunningFGSWithNotification);
        }
    }

@@ -1113,6 +1155,7 @@ public final class BackgroundRestrictionTest {
        DeviceConfigSession<Long> longRunningFGSThreshold = null;
        DeviceConfigSession<Long> mediaPlaybackFGSThreshold = null;
        DeviceConfigSession<Long> locationFGSThreshold = null;
        DeviceConfigSession<Boolean> longRunningFGSWithNotification = null;

        doReturn(testPkgName1).when(mInjector).getPackageName(testPid1);
        doReturn(testPkgName2).when(mInjector).getPackageName(testPid2);
@@ -1153,6 +1196,13 @@ public final class BackgroundRestrictionTest {
                    AppFGSPolicy.DEFAULT_BG_FGS_LOCATION_THRESHOLD);
            locationFGSThreshold.set(thresholdMs);

            longRunningFGSWithNotification = new DeviceConfigSession<>(
                    DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
                    ConstantsObserver.KEY_BG_PROMPT_FGS_WITH_NOTIFICATION_ON_LONG_RUNNING,
                    DeviceConfig::getBoolean,
                    ConstantsObserver.DEFAULT_BG_PROMPT_FGS_WITH_NOTIFICATION_ON_LONG_RUNNING);
            longRunningFGSWithNotification.set(true);

            // Long-running FGS with type "location", but ran for a very short time.
            runTestLongFGSExemptionOnce(testPkgName1, testUid1, testPid1,
                    FOREGROUND_SERVICE_TYPE_LOCATION, 0, null, OP_NONE, null, null,
@@ -1260,6 +1310,7 @@ public final class BackgroundRestrictionTest {
            closeIfNotNull(longRunningFGSThreshold);
            closeIfNotNull(mediaPlaybackFGSThreshold);
            closeIfNotNull(locationFGSThreshold);
            closeIfNotNull(longRunningFGSWithNotification);
        }
    }