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

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

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

parents ecabe75d cd35145e
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);