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

Commit 4c62f6be authored by Jeff Sharkey's avatar Jeff Sharkey Committed by Android (Google) Code Review
Browse files

Merge "Revert "Use "frozen" state for broadcasts."" into udc-dev

parents 48720843 6b407ebf
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -18763,7 +18763,6 @@ public class ActivityManagerService extends IActivityManager.Stub
        // too quickly in parallel below
        pingCount.incrementAndGet();
        synchronized (this) {
        synchronized (mProcLock) {
            final ArrayMap<String, SparseArray<ProcessRecord>> pmap =
                    mProcessList.getProcessNamesLOSP().getMap();
@@ -18788,7 +18787,6 @@ public class ActivityManagerService extends IActivityManager.Stub
                }
            }
        }
        }
        // Now that we've dispatched all "ping" events above, we can send our
        // "pong" sentinel value
+8 −8
Original line number Diff line number Diff line
@@ -203,11 +203,11 @@ public class BroadcastConstants {

    /**
     * For {@link BroadcastQueueModernImpl}: Delay to apply to broadcasts
     * targeting frozen applications.
     * targeting cached applications.
     */
    public long DELAY_FROZEN_MILLIS = DEFAULT_DELAY_FROZEN_MILLIS;
    private static final String KEY_DELAY_FROZEN_MILLIS = "bcast_delay_frozen_millis";
    private static final long DEFAULT_DELAY_FROZEN_MILLIS = +120_000;
    public long DELAY_CACHED_MILLIS = DEFAULT_DELAY_CACHED_MILLIS;
    private static final String KEY_DELAY_CACHED_MILLIS = "bcast_delay_cached_millis";
    private static final long DEFAULT_DELAY_CACHED_MILLIS = +120_000;

    /**
     * For {@link BroadcastQueueModernImpl}: Delay to apply to urgent
@@ -373,8 +373,8 @@ public class BroadcastConstants {
                    DEFAULT_MAX_PENDING_BROADCASTS);
            DELAY_NORMAL_MILLIS = getDeviceConfigLong(KEY_DELAY_NORMAL_MILLIS,
                    DEFAULT_DELAY_NORMAL_MILLIS);
            DELAY_FROZEN_MILLIS = getDeviceConfigLong(KEY_DELAY_FROZEN_MILLIS,
                    DEFAULT_DELAY_FROZEN_MILLIS);
            DELAY_CACHED_MILLIS = getDeviceConfigLong(KEY_DELAY_CACHED_MILLIS,
                    DEFAULT_DELAY_CACHED_MILLIS);
            DELAY_URGENT_MILLIS = getDeviceConfigLong(KEY_DELAY_URGENT_MILLIS,
                    DEFAULT_DELAY_URGENT_MILLIS);
            MAX_HISTORY_COMPLETE_SIZE = getDeviceConfigInt(KEY_MAX_HISTORY_COMPLETE_SIZE,
@@ -421,8 +421,8 @@ public class BroadcastConstants {
            pw.print(KEY_MAX_PENDING_BROADCASTS, MAX_PENDING_BROADCASTS).println();
            pw.print(KEY_DELAY_NORMAL_MILLIS,
                    TimeUtils.formatDuration(DELAY_NORMAL_MILLIS)).println();
            pw.print(KEY_DELAY_FROZEN_MILLIS,
                    TimeUtils.formatDuration(DELAY_FROZEN_MILLIS)).println();
            pw.print(KEY_DELAY_CACHED_MILLIS,
                    TimeUtils.formatDuration(DELAY_CACHED_MILLIS)).println();
            pw.print(KEY_DELAY_URGENT_MILLIS,
                    TimeUtils.formatDuration(DELAY_URGENT_MILLIS)).println();
            pw.print(KEY_MAX_HISTORY_COMPLETE_SIZE, MAX_HISTORY_COMPLETE_SIZE).println();
+23 −20
Original line number Diff line number Diff line
@@ -188,7 +188,7 @@ class BroadcastProcessQueue {
    private @Reason int mRunnableAtReason = REASON_EMPTY;
    private boolean mRunnableAtInvalidated;

    private boolean mUidFrozen;
    private boolean mProcessCached;
    private boolean mProcessInstrumented;
    private boolean mProcessPersistent;

@@ -385,9 +385,11 @@ class BroadcastProcessQueue {
    public void setProcess(@Nullable ProcessRecord app) {
        this.app = app;
        if (app != null) {
            setProcessCached(app.isCached());
            setProcessInstrumented(app.getActiveInstrumentation() != null);
            setProcessPersistent(app.isPersistent());
        } else {
            setProcessCached(false);
            setProcessInstrumented(false);
            setProcessPersistent(false);
        }
@@ -398,12 +400,13 @@ class BroadcastProcessQueue {
    }

    /**
     * Update if this UID is in the "frozen" state, typically signaling that
     * Update if this process is in the "cached" state, typically signaling that
     * broadcast dispatch should be paused or delayed.
     */
    public void setUidFrozen(boolean frozen) {
        if (mUidFrozen != frozen) {
            mUidFrozen = frozen;
    @VisibleForTesting
    void setProcessCached(boolean cached) {
        if (mProcessCached != cached) {
            mProcessCached = cached;
            invalidateRunnableAt();
        }
    }
@@ -810,7 +813,7 @@ class BroadcastProcessQueue {

    public boolean isDeferredUntilActive() {
        if (mRunnableAtInvalidated) updateRunnableAt();
        return mRunnableAtReason == BroadcastProcessQueue.REASON_INFINITE_DEFER;
        return mRunnableAtReason == BroadcastProcessQueue.REASON_CACHED_INFINITE_DEFER;
    }

    public boolean hasDeferredBroadcasts() {
@@ -845,14 +848,14 @@ class BroadcastProcessQueue {
    }

    static final int REASON_EMPTY = 0;
    static final int REASON_FROZEN = 1;
    static final int REASON_CACHED = 1;
    static final int REASON_NORMAL = 2;
    static final int REASON_MAX_PENDING = 3;
    static final int REASON_BLOCKED = 4;
    static final int REASON_INSTRUMENTED = 5;
    static final int REASON_PERSISTENT = 6;
    static final int REASON_FORCE_DELAYED = 7;
    static final int REASON_INFINITE_DEFER = 8;
    static final int REASON_CACHED_INFINITE_DEFER = 8;
    static final int REASON_CONTAINS_FOREGROUND = 10;
    static final int REASON_CONTAINS_ORDERED = 11;
    static final int REASON_CONTAINS_ALARM = 12;
@@ -865,14 +868,14 @@ class BroadcastProcessQueue {

    @IntDef(flag = false, prefix = { "REASON_" }, value = {
            REASON_EMPTY,
            REASON_FROZEN,
            REASON_CACHED,
            REASON_NORMAL,
            REASON_MAX_PENDING,
            REASON_BLOCKED,
            REASON_INSTRUMENTED,
            REASON_PERSISTENT,
            REASON_FORCE_DELAYED,
            REASON_INFINITE_DEFER,
            REASON_CACHED_INFINITE_DEFER,
            REASON_CONTAINS_FOREGROUND,
            REASON_CONTAINS_ORDERED,
            REASON_CONTAINS_ALARM,
@@ -889,14 +892,14 @@ class BroadcastProcessQueue {
    static @NonNull String reasonToString(@Reason int reason) {
        switch (reason) {
            case REASON_EMPTY: return "EMPTY";
            case REASON_FROZEN: return "FROZEN";
            case REASON_CACHED: return "CACHED";
            case REASON_NORMAL: return "NORMAL";
            case REASON_MAX_PENDING: return "MAX_PENDING";
            case REASON_BLOCKED: return "BLOCKED";
            case REASON_INSTRUMENTED: return "INSTRUMENTED";
            case REASON_PERSISTENT: return "PERSISTENT";
            case REASON_FORCE_DELAYED: return "FORCE_DELAYED";
            case REASON_INFINITE_DEFER: return "INFINITE_DEFER";
            case REASON_CACHED_INFINITE_DEFER: return "INFINITE_DEFER";
            case REASON_CONTAINS_FOREGROUND: return "CONTAINS_FOREGROUND";
            case REASON_CONTAINS_ORDERED: return "CONTAINS_ORDERED";
            case REASON_CONTAINS_ALARM: return "CONTAINS_ALARM";
@@ -983,12 +986,12 @@ class BroadcastProcessQueue {
            } else if (mProcessPersistent) {
                mRunnableAt = runnableAt;
                mRunnableAtReason = REASON_PERSISTENT;
            } else if (mUidFrozen) {
            } else if (mProcessCached) {
                if (r.deferUntilActive) {
                    // All enqueued broadcasts are deferrable, defer
                    if (mCountDeferred == mCountEnqueued) {
                        mRunnableAt = Long.MAX_VALUE;
                        mRunnableAtReason = REASON_INFINITE_DEFER;
                        mRunnableAtReason = REASON_CACHED_INFINITE_DEFER;
                    } else {
                        // At least one enqueued broadcast isn't deferrable, repick time and reason
                        // for this record. If a later record is not deferrable and is one of these
@@ -1003,14 +1006,14 @@ class BroadcastProcessQueue {
                            mRunnableAt = runnableAt;
                            mRunnableAtReason = REASON_CONTAINS_RESULT_TO;
                        } else {
                            mRunnableAt = runnableAt + constants.DELAY_FROZEN_MILLIS;
                            mRunnableAtReason = REASON_FROZEN;
                            mRunnableAt = runnableAt + constants.DELAY_CACHED_MILLIS;
                            mRunnableAtReason = REASON_CACHED;
                        }
                    }
                } else {
                    // This record isn't deferrable
                    mRunnableAt = runnableAt + constants.DELAY_FROZEN_MILLIS;
                    mRunnableAtReason = REASON_FROZEN;
                    mRunnableAt = runnableAt + constants.DELAY_CACHED_MILLIS;
                    mRunnableAtReason = REASON_CACHED;
                }
            } else if (mCountResultTo > 0) {
                // All resultTo broadcasts are infinitely deferrable, so if the app
@@ -1192,8 +1195,8 @@ class BroadcastProcessQueue {
    @NeverCompile
    private void dumpProcessState(@NonNull IndentingPrintWriter pw) {
        final StringBuilder sb = new StringBuilder();
        if (mUidFrozen) {
            sb.append("FROZEN");
        if (mProcessCached) {
            sb.append("CACHED");
        }
        if (mProcessInstrumented) {
            if (sb.length() > 0) sb.append("|");
+14 −47
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

package com.android.server.am;

import static android.app.ActivityManager.UidFrozenStateChangedCallback.UID_FROZEN_STATE_FROZEN;
import static android.os.Process.ZYGOTE_POLICY_FLAG_EMPTY;
import static android.os.Process.ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE;

@@ -49,7 +48,7 @@ import android.app.ActivityManager;
import android.app.ApplicationExitInfo;
import android.app.BroadcastOptions;
import android.app.IApplicationThread;
import android.app.IUidFrozenStateChangedCallback;
import android.app.UidObserver;
import android.app.usage.UsageEvents.Event;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -73,7 +72,6 @@ import android.util.MathUtils;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;

@@ -211,16 +209,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
    private final AtomicReference<ArraySet<BroadcastRecord>> mReplacedBroadcastsCache =
            new AtomicReference<>();

    /**
     * Map from UID to its last known "frozen" state.
     * <p>
     * We manually maintain this data structure since the lifecycle of
     * {@link ProcessRecord} and {@link BroadcastProcessQueue} can be
     * mismatched.
     */
    @GuardedBy("mService")
    private final SparseBooleanArray mUidFrozen = new SparseBooleanArray();

    private final BroadcastConstants mConstants;
    private final BroadcastConstants mFgConstants;
    private final BroadcastConstants mBgConstants;
@@ -498,7 +486,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
        final BroadcastProcessQueue queue = getProcessQueue(app);
        if (queue != null) {
            queue.setProcess(app);
            queue.setUidFrozen(mUidFrozen.get(queue.uid, false));
        }

        boolean didSomething = false;
@@ -540,7 +527,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
        final BroadcastProcessQueue queue = getProcessQueue(app);
        if (queue != null) {
            queue.setProcess(null);
            queue.setUidFrozen(mUidFrozen.get(queue.uid, false));
        }

        if ((mRunningColdStart != null) && (mRunningColdStart == queue)) {
@@ -1342,25 +1328,15 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
        mFgConstants.startObserving(mHandler, resolver);
        mBgConstants.startObserving(mHandler, resolver);

        mService.registerUidFrozenStateChangedCallback(new IUidFrozenStateChangedCallback.Stub() {
        mService.registerUidObserver(new UidObserver() {
            @Override
            public void onUidFrozenStateChanged(int[] uids, int[] frozenStates) {
            public void onUidCachedChanged(int uid, boolean cached) {
                synchronized (mService) {
                    for (int i = 0; i < uids.length; i++) {
                        final int uid = uids[i];
                        final boolean frozen = frozenStates[i] == UID_FROZEN_STATE_FROZEN;
                        if (frozen) {
                            mUidFrozen.put(uid, true);
                        } else {
                            mUidFrozen.delete(uid);
                        }

                    BroadcastProcessQueue leaf = mProcessQueues.get(uid);
                    while (leaf != null) {
                        // Update internal state by refreshing values previously
                        // read from any known running process
                        leaf.setProcess(leaf.app);
                            leaf.setUidFrozen(frozen);
                        updateQueueDeferred(leaf);
                        updateRunnableList(leaf);
                        leaf = leaf.processNameNext;
@@ -1368,8 +1344,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
                    enqueueUpdateRunningList();
                }
            }
            }
        });
        }, ActivityManager.UID_OBSERVER_CACHED, 0, "android");

        // Kick off periodic health checks
        mLocalHandler.sendEmptyMessage(MSG_CHECK_HEALTH);
@@ -1524,7 +1499,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
    private void updateWarmProcess(@NonNull BroadcastProcessQueue queue) {
        if (!queue.isProcessWarm()) {
            queue.setProcess(mService.getProcessRecordLocked(queue.processName, queue.uid));
            queue.setUidFrozen(mUidFrozen.get(queue.uid, false));
        }
    }

@@ -1719,7 +1693,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue {

        BroadcastProcessQueue created = new BroadcastProcessQueue(mConstants, processName, uid);
        created.setProcess(mService.getProcessRecordLocked(processName, uid));
        created.setUidFrozen(mUidFrozen.get(uid, false));

        if (leaf == null) {
            mProcessQueues.put(uid, created);
@@ -1848,12 +1821,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
        ipw.decreaseIndent();
        ipw.println();

        ipw.println("Frozen UIDs:");
        ipw.increaseIndent();
        ipw.println(mUidFrozen.toString());
        ipw.decreaseIndent();
        ipw.println();

        if (dumpConstants) {
            mConstants.dump(ipw);
        }
+23 −23
Original line number Diff line number Diff line
@@ -130,7 +130,7 @@ public final class BroadcastQueueModernImplTest {
        mConstants = new BroadcastConstants(Settings.Global.BROADCAST_FG_CONSTANTS);
        mConstants.DELAY_URGENT_MILLIS = -120_000;
        mConstants.DELAY_NORMAL_MILLIS = 10_000;
        mConstants.DELAY_FROZEN_MILLIS = 120_000;
        mConstants.DELAY_CACHED_MILLIS = 120_000;

        final BroadcastSkipPolicy emptySkipPolicy = new BroadcastSkipPolicy(mAms) {
            public boolean shouldSkip(BroadcastRecord r, Object o) {
@@ -372,13 +372,13 @@ public final class BroadcastQueueModernImplTest {
                List.of(makeMockRegisteredReceiver()), false);
        queue.enqueueOrReplaceBroadcast(airplaneRecord, 0, false);

        queue.setUidFrozen(false);
        queue.setProcessCached(false);
        final long notCachedRunnableAt = queue.getRunnableAt();
        queue.setUidFrozen(true);
        queue.setProcessCached(true);
        final long cachedRunnableAt = queue.getRunnableAt();
        assertThat(cachedRunnableAt).isGreaterThan(notCachedRunnableAt);
        assertFalse(queue.isRunnable());
        assertEquals(BroadcastProcessQueue.REASON_INFINITE_DEFER,
        assertEquals(BroadcastProcessQueue.REASON_CACHED_INFINITE_DEFER,
                queue.getRunnableAtReason());
        assertEquals(ProcessList.SCHED_GROUP_UNDEFINED, queue.getPreferredSchedulingGroupLocked());
    }
@@ -399,13 +399,13 @@ public final class BroadcastQueueModernImplTest {
                List.of(makeMockRegisteredReceiver()), false);
        queue.enqueueOrReplaceBroadcast(airplaneRecord, 0, false);

        queue.setUidFrozen(false);
        queue.setProcessCached(false);
        final long notCachedRunnableAt = queue.getRunnableAt();
        queue.setUidFrozen(true);
        queue.setProcessCached(true);
        final long cachedRunnableAt = queue.getRunnableAt();
        assertThat(cachedRunnableAt).isGreaterThan(notCachedRunnableAt);
        assertTrue(queue.isRunnable());
        assertEquals(BroadcastProcessQueue.REASON_FROZEN, queue.getRunnableAtReason());
        assertEquals(BroadcastProcessQueue.REASON_CACHED, queue.getRunnableAtReason());
        assertEquals(ProcessList.SCHED_GROUP_BACKGROUND, queue.getPreferredSchedulingGroupLocked());
    }

@@ -431,13 +431,13 @@ public final class BroadcastQueueModernImplTest {
        // verify that:
        // (a) the queue is immediately runnable by existence of a fg-priority broadcast
        // (b) the next one up is the fg-priority broadcast despite its later enqueue time
        queue.setUidFrozen(false);
        queue.setProcessCached(false);
        assertTrue(queue.isRunnable());
        assertThat(queue.getRunnableAt()).isAtMost(airplaneRecord.enqueueClockTime);
        assertEquals(ProcessList.SCHED_GROUP_DEFAULT, queue.getPreferredSchedulingGroupLocked());
        assertEquals(queue.peekNextBroadcastRecord(), airplaneRecord);

        queue.setUidFrozen(true);
        queue.setProcessCached(true);
        assertTrue(queue.isRunnable());
        assertThat(queue.getRunnableAt()).isAtMost(airplaneRecord.enqueueClockTime);
        assertEquals(ProcessList.SCHED_GROUP_DEFAULT, queue.getPreferredSchedulingGroupLocked());
@@ -497,10 +497,10 @@ public final class BroadcastQueueModernImplTest {
     * Verify that a cached process that would normally be delayed becomes
     * immediately runnable when the given broadcast is enqueued.
     */
    private void doRunnableAt_Frozen(BroadcastRecord testRecord, int testRunnableAtReason) {
    private void doRunnableAt_Cached(BroadcastRecord testRecord, int testRunnableAtReason) {
        final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants,
                PACKAGE_GREEN, getUidForPackage(PACKAGE_GREEN));
        queue.setUidFrozen(true);
        queue.setProcessCached(true);

        final BroadcastRecord lazyRecord = makeBroadcastRecord(
                new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED),
@@ -516,49 +516,49 @@ public final class BroadcastQueueModernImplTest {
    }

    @Test
    public void testRunnableAt_Frozen_Manifest() {
        doRunnableAt_Frozen(makeBroadcastRecord(makeMockIntent(), null,
    public void testRunnableAt_Cached_Manifest() {
        doRunnableAt_Cached(makeBroadcastRecord(makeMockIntent(), null,
                List.of(makeMockManifestReceiver()), null, false), REASON_CONTAINS_MANIFEST);
    }

    @Test
    public void testRunnableAt_Frozen_Ordered() {
        doRunnableAt_Frozen(makeBroadcastRecord(makeMockIntent(), null,
    public void testRunnableAt_Cached_Ordered() {
        doRunnableAt_Cached(makeBroadcastRecord(makeMockIntent(), null,
                List.of(makeMockRegisteredReceiver()), null, true), REASON_CONTAINS_ORDERED);
    }

    @Test
    public void testRunnableAt_Frozen_Foreground() {
    public void testRunnableAt_Cached_Foreground() {
        final Intent foregroundIntent = new Intent();
        foregroundIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
        doRunnableAt_Frozen(makeBroadcastRecord(foregroundIntent, null,
        doRunnableAt_Cached(makeBroadcastRecord(foregroundIntent, null,
                List.of(makeMockRegisteredReceiver()), null, false), REASON_CONTAINS_FOREGROUND);
    }

    @Test
    public void testRunnableAt_Frozen_Interactive() {
    public void testRunnableAt_Cached_Interactive() {
        final BroadcastOptions options = BroadcastOptions.makeBasic();
        options.setInteractive(true);
        doRunnableAt_Frozen(makeBroadcastRecord(makeMockIntent(), options,
        doRunnableAt_Cached(makeBroadcastRecord(makeMockIntent(), options,
                List.of(makeMockRegisteredReceiver()), null, false), REASON_CONTAINS_INTERACTIVE);
    }

    @Test
    public void testRunnableAt_Frozen_Alarm() {
    public void testRunnableAt_Cached_Alarm() {
        final BroadcastOptions options = BroadcastOptions.makeBasic();
        options.setAlarmBroadcast(true);
        doRunnableAt_Frozen(makeBroadcastRecord(makeMockIntent(), options,
        doRunnableAt_Cached(makeBroadcastRecord(makeMockIntent(), options,
                List.of(makeMockRegisteredReceiver()), null, false), REASON_CONTAINS_ALARM);
    }

    @Test
    public void testRunnableAt_Frozen_Prioritized_NonDeferrable() {
    public void testRunnableAt_Cached_Prioritized_NonDeferrable() {
        final List receivers = List.of(
                withPriority(makeManifestReceiver(PACKAGE_RED, PACKAGE_RED), 10),
                withPriority(makeManifestReceiver(PACKAGE_GREEN, PACKAGE_GREEN), -10));
        final BroadcastOptions options = BroadcastOptions.makeBasic()
                .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_NONE);
        doRunnableAt_Frozen(makeBroadcastRecord(makeMockIntent(), options,
        doRunnableAt_Cached(makeBroadcastRecord(makeMockIntent(), options,
                receivers, null, false), REASON_CONTAINS_PRIORITIZED);
    }

Loading