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

Commit 51fdd148 authored by Chris Tate's avatar Chris Tate Committed by Automerger Merge Worker
Browse files

Merge "Improve test flakiness around FGS notifications" into sc-dev am: 86ed597d

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14829740

Change-Id: I656b22e791c5883ea56b3c085a6f72da0b7b124f
parents 5b6fc849 86ed597d
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -685,6 +685,14 @@ interface IActivityManager {
     */
    boolean enableAppFreezer(in boolean enable);

    /**
     * Suppress or reenable the rate limit on foreground service notification deferral.
     * This is for use within CTS and is protected by android.permission.WRITE_DEVICE_CONFIG.
     *
     * @param enable false to suppress rate-limit policy; true to reenable it.
     */
    boolean enableFgsNotificationRateLimit(in boolean enable);

    /**
     * Holds the AM lock for the specified amount of milliseconds.
     * This is intended for use by the tests that need to imitate lock contention.
+45 −2
Original line number Diff line number Diff line
@@ -249,6 +249,14 @@ public final class ActiveServices {
     */
    final ArrayList<ServiceRecord> mPendingFgsNotifications = new ArrayList<>();

    /**
     * Whether there is a rate limit that suppresses immediate re-deferral of new FGS
     * notifications from each app.  On by default, disabled only by shell command for
     * test-suite purposes.  To disable the behavior more generally, use the usual
     * DeviceConfig mechanism to set the rate limit interval to zero.
     */
    private boolean mFgsDeferralRateLimited = true;

    /**
     * Uptime at which a given uid becomes eliglible again for FGS notification deferral
     */
@@ -2142,8 +2150,10 @@ public final class ActiveServices {
            }
        }

        if (mFgsDeferralRateLimited) {
            final long nextEligible = when + mAm.mConstants.mFgsNotificationDeferralExclusionTime;
            mFgsDeferralEligible.put(uid, nextEligible);
        }
        r.fgDisplayTime = when;
        r.mFgsNotificationDeferred = true;
        r.mFgsNotificationShown = false;
@@ -2204,6 +2214,38 @@ public final class ActiveServices {
        }
    };

    /**
     * Suppress or reenable the rate limit on foreground service notification deferral.
     * Invoked from the activity manager shell command.
     *
     * @param enable false to suppress rate-limit policy; true to reenable it.
     */
    boolean enableFgsNotificationRateLimitLocked(final boolean enable) {
        if (enable != mFgsDeferralRateLimited) {
            mFgsDeferralRateLimited = enable;
            if (!enable) {
                // make sure to reset any active rate limiting
                mFgsDeferralEligible.clear();
            }
        }
        return enable;
    }

    private void removeServiceNotificationDeferralsLocked(String packageName,
            final @UserIdInt int userId) {
        for (int i = mPendingFgsNotifications.size() - 1; i >= 0; i--) {
            final ServiceRecord r = mPendingFgsNotifications.get(i);
            if (userId == r.userId
                    && r.appInfo.packageName.equals(packageName)) {
                mPendingFgsNotifications.remove(i);
                if (DEBUG_FOREGROUND_SERVICE) {
                    Slog.d(TAG_SERVICE, "Removing notification deferral for "
                            + r);
                }
            }
        }
    }

    private void maybeLogFGSStateEnteredLocked(ServiceRecord r) {
        if (r.mLogEntering) {
            logFGSStateChangeLocked(r,
@@ -4689,6 +4731,7 @@ public final class ActiveServices {
            }
        }
        removeServiceRestartBackoffEnabledLocked(packageName);
        removeServiceNotificationDeferralsLocked(packageName, userId);
    }

    void cleanUpServices(int userId, ComponentName component, Intent baseIntent) {
+13 −0
Original line number Diff line number Diff line
@@ -17073,6 +17073,19 @@ public class ActivityManagerService extends IActivityManager.Stub
        }
    }
    /**
     * Suppress or reenable the rate limit on foreground service notification deferral.
     * @param enable false to suppress rate-limit policy; true to reenable it.
     */
    @Override
    public boolean enableFgsNotificationRateLimit(boolean enable) {
        enforceCallingPermission(permission.WRITE_DEVICE_CONFIG,
                "enableFgsNotificationRateLimit");
        synchronized (this) {
            return mServices.enableFgsNotificationRateLimitLocked(enable);
        }
    }
    /**
     * Holds the AM lock for the specified amount of milliseconds.
     * Intended for use by the tests that need to imitate lock contention.
+22 −0
Original line number Diff line number Diff line
@@ -230,6 +230,8 @@ final class ActivityManagerShellCommand extends ShellCommand {
                    return runBugReport(pw);
                case "force-stop":
                    return runForceStop(pw);
                case "fgs-notification-rate-limit":
                    return runFgsNotificationRateLimit(pw);
                case "crash":
                    return runCrash(pw);
                case "kill":
@@ -1103,6 +1105,24 @@ final class ActivityManagerShellCommand extends ShellCommand {
        return 0;
    }

    int runFgsNotificationRateLimit(PrintWriter pw) throws RemoteException {
        final String toggleValue = getNextArgRequired();
        final boolean enable;
        switch (toggleValue) {
            case "enable":
                enable = true;
                break;
            case "disable":
                enable = false;
                break;
            default:
                throw new IllegalArgumentException(
                        "Argument must be either 'enable' or 'disable'");
        }
        mInterface.enableFgsNotificationRateLimit(enable);
        return 0;
    }

    int runCrash(PrintWriter pw) throws RemoteException {
        int userId = UserHandle.USER_ALL;

@@ -3303,6 +3323,8 @@ final class ActivityManagerShellCommand extends ShellCommand {
            pw.println("        when done to select where it should be delivered. Options are:");
            pw.println("     --progress: will launch a notification right away to show its progress.");
            pw.println("     --telephony: will dump only telephony sections.");
            pw.println("  fgs-notification-rate-limit {enable | disable}");
            pw.println("     Enable/disable rate limit on FGS notification deferral policy.");
            pw.println("  force-stop [--user <USER_ID> | all | current] <PACKAGE>");
            pw.println("      Completely stop the given application package.");
            pw.println("  crash [--user <USER_ID>] <PACKAGE|PID>");