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

Commit ea8d14b9 authored by Jeff Sharkey's avatar Jeff Sharkey Committed by Automerger Merge Worker
Browse files

Merge "Store "cached" state separate from ProcessRecord." into udc-dev am: fb094246

parents f520316d fb094246
Loading
Loading
Loading
Loading
+11 −12
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 mProcessCached;
    private boolean mUidCached;
    private boolean mProcessInstrumented;
    private boolean mProcessPersistent;

@@ -382,14 +382,14 @@ class BroadcastProcessQueue {
    /**
     * Update the actively running "warm" process for this process.
     */
    public void setProcess(@Nullable ProcessRecord app) {
    public void setProcessAndUidCached(@Nullable ProcessRecord app, boolean uidCached) {
        this.app = app;
        if (app != null) {
            setProcessCached(app.isCached());
            setUidCached(uidCached);
            setProcessInstrumented(app.getActiveInstrumentation() != null);
            setProcessPersistent(app.isPersistent());
        } else {
            setProcessCached(false);
            setUidCached(uidCached);
            setProcessInstrumented(false);
            setProcessPersistent(false);
        }
@@ -403,10 +403,9 @@ class BroadcastProcessQueue {
     * Update if this process is in the "cached" state, typically signaling that
     * broadcast dispatch should be paused or delayed.
     */
    @VisibleForTesting
    void setProcessCached(boolean cached) {
        if (mProcessCached != cached) {
            mProcessCached = cached;
    private void setUidCached(boolean uidCached) {
        if (mUidCached != uidCached) {
            mUidCached = uidCached;
            invalidateRunnableAt();
        }
    }
@@ -416,7 +415,7 @@ class BroadcastProcessQueue {
     * signaling that broadcast dispatch should bypass all pauses or delays, to
     * avoid holding up test suites.
     */
    public void setProcessInstrumented(boolean instrumented) {
    private void setProcessInstrumented(boolean instrumented) {
        if (mProcessInstrumented != instrumented) {
            mProcessInstrumented = instrumented;
            invalidateRunnableAt();
@@ -427,7 +426,7 @@ class BroadcastProcessQueue {
     * Update if this process is in the "persistent" state, which signals broadcast dispatch should
     * bypass all pauses or delays to prevent the system from becoming out of sync with itself.
     */
    public void setProcessPersistent(boolean persistent) {
    private void setProcessPersistent(boolean persistent) {
        if (mProcessPersistent != persistent) {
            mProcessPersistent = persistent;
            invalidateRunnableAt();
@@ -986,7 +985,7 @@ class BroadcastProcessQueue {
            } else if (mProcessPersistent) {
                mRunnableAt = runnableAt;
                mRunnableAtReason = REASON_PERSISTENT;
            } else if (mProcessCached) {
            } else if (mUidCached) {
                if (r.deferUntilActive) {
                    // All enqueued broadcasts are deferrable, defer
                    if (mCountDeferred == mCountEnqueued) {
@@ -1195,7 +1194,7 @@ class BroadcastProcessQueue {
    @NeverCompile
    private void dumpProcessState(@NonNull IndentingPrintWriter pw) {
        final StringBuilder sb = new StringBuilder();
        if (mProcessCached) {
        if (mUidCached) {
            sb.append("CACHED");
        }
        if (mProcessInstrumented) {
+38 −6
Original line number Diff line number Diff line
@@ -72,6 +72,7 @@ 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;

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

    /**
     * Map from UID to its last known "cached" 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 mUidCached = new SparseBooleanArray();

    private final BroadcastConstants mConstants;
    private final BroadcastConstants mFgConstants;
    private final BroadcastConstants mBgConstants;
@@ -485,7 +496,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
        // relevant per-process queue
        final BroadcastProcessQueue queue = getProcessQueue(app);
        if (queue != null) {
            queue.setProcess(app);
            setQueueProcess(queue, app);
        }

        boolean didSomething = false;
@@ -526,7 +537,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
        // relevant per-process queue
        final BroadcastProcessQueue queue = getProcessQueue(app);
        if (queue != null) {
            queue.setProcess(null);
            setQueueProcess(queue, null);
        }

        if ((mRunningColdStart != null) && (mRunningColdStart == queue)) {
@@ -1332,11 +1343,17 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
            @Override
            public void onUidCachedChanged(int uid, boolean cached) {
                synchronized (mService) {
                    if (cached) {
                        mUidCached.put(uid, true);
                    } else {
                        mUidCached.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);
                        setQueueProcess(leaf, leaf.app);
                        updateQueueDeferred(leaf);
                        updateRunnableList(leaf);
                        leaf = leaf.processNameNext;
@@ -1498,10 +1515,19 @@ class BroadcastQueueModernImpl extends BroadcastQueue {

    private void updateWarmProcess(@NonNull BroadcastProcessQueue queue) {
        if (!queue.isProcessWarm()) {
            queue.setProcess(mService.getProcessRecordLocked(queue.processName, queue.uid));
            setQueueProcess(queue, mService.getProcessRecordLocked(queue.processName, queue.uid));
        }
    }

    /**
     * Update the {@link ProcessRecord} associated with the given
     * {@link BroadcastProcessQueue}.
     */
    private void setQueueProcess(@NonNull BroadcastProcessQueue queue,
            @Nullable ProcessRecord app) {
        queue.setProcessAndUidCached(app, mUidCached.get(queue.uid, false));
    }

    /**
     * Inform other parts of OS that the given broadcast queue has started
     * running, typically for internal bookkeeping.
@@ -1692,7 +1718,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
        }

        BroadcastProcessQueue created = new BroadcastProcessQueue(mConstants, processName, uid);
        created.setProcess(mService.getProcessRecordLocked(processName, uid));
        setQueueProcess(created, mService.getProcessRecordLocked(processName, uid));

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

        ipw.println("Cached UIDs:");
        ipw.increaseIndent();
        ipw.println(mUidCached.toString());
        ipw.decreaseIndent();
        ipw.println();

        if (dumpConstants) {
            mConstants.dump(ipw);
        }
+7 −7
Original line number Diff line number Diff line
@@ -372,9 +372,9 @@ public final class BroadcastQueueModernImplTest {
                List.of(makeMockRegisteredReceiver()), false);
        queue.enqueueOrReplaceBroadcast(airplaneRecord, 0, false);

        queue.setProcessCached(false);
        queue.setProcessAndUidCached(null, false);
        final long notCachedRunnableAt = queue.getRunnableAt();
        queue.setProcessCached(true);
        queue.setProcessAndUidCached(null, true);
        final long cachedRunnableAt = queue.getRunnableAt();
        assertThat(cachedRunnableAt).isGreaterThan(notCachedRunnableAt);
        assertFalse(queue.isRunnable());
@@ -399,9 +399,9 @@ public final class BroadcastQueueModernImplTest {
                List.of(makeMockRegisteredReceiver()), false);
        queue.enqueueOrReplaceBroadcast(airplaneRecord, 0, false);

        queue.setProcessCached(false);
        queue.setProcessAndUidCached(null, false);
        final long notCachedRunnableAt = queue.getRunnableAt();
        queue.setProcessCached(true);
        queue.setProcessAndUidCached(null, true);
        final long cachedRunnableAt = queue.getRunnableAt();
        assertThat(cachedRunnableAt).isGreaterThan(notCachedRunnableAt);
        assertTrue(queue.isRunnable());
@@ -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.setProcessCached(false);
        queue.setProcessAndUidCached(null, false);
        assertTrue(queue.isRunnable());
        assertThat(queue.getRunnableAt()).isAtMost(airplaneRecord.enqueueClockTime);
        assertEquals(ProcessList.SCHED_GROUP_DEFAULT, queue.getPreferredSchedulingGroupLocked());
        assertEquals(queue.peekNextBroadcastRecord(), airplaneRecord);

        queue.setProcessCached(true);
        queue.setProcessAndUidCached(null, true);
        assertTrue(queue.isRunnable());
        assertThat(queue.getRunnableAt()).isAtMost(airplaneRecord.enqueueClockTime);
        assertEquals(ProcessList.SCHED_GROUP_DEFAULT, queue.getPreferredSchedulingGroupLocked());
@@ -500,7 +500,7 @@ public final class BroadcastQueueModernImplTest {
    private void doRunnableAt_Cached(BroadcastRecord testRecord, int testRunnableAtReason) {
        final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants,
                PACKAGE_GREEN, getUidForPackage(PACKAGE_GREEN));
        queue.setProcessCached(true);
        queue.setProcessAndUidCached(null, true);

        final BroadcastRecord lazyRecord = makeBroadcastRecord(
                new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED),
+5 −8
Original line number Diff line number Diff line
@@ -1659,8 +1659,8 @@ public class BroadcastQueueTest {
        final ProcessRecord receiverYellowApp = makeActiveProcessRecord(PACKAGE_YELLOW);
        final ProcessRecord receiverOrangeApp = makeActiveProcessRecord(PACKAGE_ORANGE);

        receiverGreenApp.setCached(true);
        receiverBlueApp.setCached(true);
        mUidObserver.onUidCachedChanged(getUidForPackage(PACKAGE_GREEN), true);
        mUidObserver.onUidCachedChanged(getUidForPackage(PACKAGE_BLUE), true);

        final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK);
        final BroadcastOptions opts = BroadcastOptions.makeBasic()
@@ -1704,13 +1704,11 @@ public class BroadcastQueueTest {
                eq(UserHandle.USER_SYSTEM), anyInt(), anyInt(), any());

        // Shift blue to be active and confirm that deferred broadcast is delivered
        receiverBlueApp.setCached(false);
        mUidObserver.onUidCachedChanged(getUidForPackage(PACKAGE_BLUE), false);
        waitForIdle();
        verifyScheduleRegisteredReceiver(times(1), receiverBlueApp, timeTick);

        // Shift green to be active and confirm that deferred broadcast is delivered
        receiverGreenApp.setCached(false);
        mUidObserver.onUidCachedChanged(getUidForPackage(PACKAGE_GREEN), false);
        waitForIdle();
        verifyScheduleRegisteredReceiver(times(1), receiverGreenApp, timeTick);
@@ -2044,9 +2042,9 @@ public class BroadcastQueueTest {
        final ProcessRecord receiverBlueApp = makeActiveProcessRecord(PACKAGE_BLUE);
        final ProcessRecord receiverYellowApp = makeActiveProcessRecord(PACKAGE_YELLOW);

        receiverGreenApp.setCached(true);
        receiverBlueApp.setCached(true);
        receiverYellowApp.setCached(false);
        mUidObserver.onUidCachedChanged(getUidForPackage(PACKAGE_GREEN), true);
        mUidObserver.onUidCachedChanged(getUidForPackage(PACKAGE_BLUE), true);
        mUidObserver.onUidCachedChanged(getUidForPackage(PACKAGE_YELLOW), false);

        final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
        final BroadcastOptions opts = BroadcastOptions.makeBasic()
@@ -2069,7 +2067,6 @@ public class BroadcastQueueTest {
        verifyScheduleRegisteredReceiver(times(1), receiverYellowApp, airplane);

        // Shift green to be active and confirm that deferred broadcast is delivered
        receiverGreenApp.setCached(false);
        mUidObserver.onUidCachedChanged(getUidForPackage(PACKAGE_GREEN), false);
        waitForIdle();
        verifyScheduleRegisteredReceiver(times(1), receiverGreenApp, airplane);