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

Commit 29277ce0 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Revert "More robust updating of "runnable" list."" into udc-dev am:...

Merge "Revert "More robust updating of "runnable" list."" into udc-dev am: 5b7d07f5 am: 08374532

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



Change-Id: I278be547fcf29d82d2531a5e747270695b72d77e
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 68e95689 08374532
Loading
Loading
Loading
Loading
+15 −68
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import static com.android.server.am.BroadcastRecord.deliveryStateToString;
import static com.android.server.am.BroadcastRecord.isDeliveryStateTerminal;
import static com.android.server.am.BroadcastRecord.isReceiverEquals;

import android.annotation.CheckResult;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -342,12 +341,7 @@ class BroadcastProcessQueue {
     * Predicates that choose to remove a broadcast <em>must</em> finish
     * delivery of the matched broadcast, to ensure that situations like ordered
     * broadcasts are handled consistently.
     *
     * @return if this operation may have changed internal state, indicating
     *         that the caller is responsible for invoking
     *         {@link BroadcastQueueModernImpl#updateRunnableList}
     */
    @CheckResult
    public boolean forEachMatchingBroadcast(@NonNull BroadcastPredicate predicate,
            @NonNull BroadcastConsumer consumer, boolean andRemove) {
        boolean didSomething = false;
@@ -360,7 +354,6 @@ class BroadcastProcessQueue {
        return didSomething;
    }

    @CheckResult
    private boolean forEachMatchingBroadcastInQueue(@NonNull ArrayDeque<SomeArgs> queue,
            @NonNull BroadcastPredicate predicate, @NonNull BroadcastConsumer consumer,
            boolean andRemove) {
@@ -377,10 +370,6 @@ class BroadcastProcessQueue {
                    args.recycle();
                    it.remove();
                    onBroadcastDequeued(record, recordIndex, recordWouldBeSkipped);
                } else {
                    // Even if we're leaving broadcast in queue, it may have
                    // been mutated in such a way to change our runnable time
                    invalidateRunnableAt();
                }
                didSomething = true;
            }
@@ -392,43 +381,30 @@ class BroadcastProcessQueue {

    /**
     * Update the actively running "warm" process for this process.
     *
     * @return if this operation may have changed internal state, indicating
     *         that the caller is responsible for invoking
     *         {@link BroadcastQueueModernImpl#updateRunnableList}
     */
    @CheckResult
    public boolean setProcessAndUidFrozen(@Nullable ProcessRecord app, boolean uidFrozen) {
    public void setProcess(@Nullable ProcessRecord app) {
        this.app = app;
        if (app != null) {
            setProcessInstrumented(app.getActiveInstrumentation() != null);
            setProcessPersistent(app.isPersistent());
        } else {
            setProcessInstrumented(false);
            setProcessPersistent(false);
        }

        // Since we may have just changed our PID, invalidate cached strings
        mCachedToString = null;
        mCachedToShortString = null;

        boolean didSomething = false;
        if (app != null) {
            didSomething |= setProcessInstrumented(app.getActiveInstrumentation() != null);
            didSomething |= setProcessPersistent(app.isPersistent());
            didSomething |= setUidFrozen(uidFrozen);
        } else {
            didSomething |= setProcessInstrumented(false);
            didSomething |= setProcessPersistent(false);
            didSomething |= setUidFrozen(uidFrozen);
        }
        return didSomething;
    }

    /**
     * Update if this UID is in the "frozen" state, typically signaling that
     * broadcast dispatch should be paused or delayed.
     */
    private boolean setUidFrozen(boolean frozen) {
    public void setUidFrozen(boolean frozen) {
        if (mUidFrozen != frozen) {
            mUidFrozen = frozen;
            invalidateRunnableAt();
            return true;
        } else {
            return false;
        }
    }

@@ -437,13 +413,10 @@ class BroadcastProcessQueue {
     * signaling that broadcast dispatch should bypass all pauses or delays, to
     * avoid holding up test suites.
     */
    private boolean setProcessInstrumented(boolean instrumented) {
    public void setProcessInstrumented(boolean instrumented) {
        if (mProcessInstrumented != instrumented) {
            mProcessInstrumented = instrumented;
            invalidateRunnableAt();
            return true;
        } else {
            return false;
        }
    }

@@ -451,13 +424,10 @@ 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.
     */
    private boolean setProcessPersistent(boolean persistent) {
    public void setProcessPersistent(boolean persistent) {
        if (mProcessPersistent != persistent) {
            mProcessPersistent = persistent;
            invalidateRunnableAt();
            return true;
        } else {
            return false;
        }
    }

@@ -677,20 +647,8 @@ class BroadcastProcessQueue {
        return mActive != null;
    }

    /**
     * @return if this operation may have changed internal state, indicating
     *         that the caller is responsible for invoking
     *         {@link BroadcastQueueModernImpl#updateRunnableList}
     */
    @CheckResult
    boolean forceDelayBroadcastDelivery(long delayedDurationMs) {
        if (mForcedDelayedDurationMs != delayedDurationMs) {
    void forceDelayBroadcastDelivery(long delayedDurationMs) {
        mForcedDelayedDurationMs = delayedDurationMs;
            invalidateRunnableAt();
            return true;
        } else {
            return false;
        }
    }

    /**
@@ -762,21 +720,10 @@ class BroadcastProcessQueue {
     * broadcasts would be prioritized for dispatching, even if there are urgent broadcasts
     * waiting. This is typically used in case there are callers waiting for "barrier" to be
     * reached.
     *
     * @return if this operation may have changed internal state, indicating
     *         that the caller is responsible for invoking
     *         {@link BroadcastQueueModernImpl#updateRunnableList}
     */
    @CheckResult
    @VisibleForTesting
    boolean setPrioritizeEarliest(boolean prioritizeEarliest) {
        if (mPrioritizeEarliest != prioritizeEarliest) {
    void setPrioritizeEarliest(boolean prioritizeEarliest) {
        mPrioritizeEarliest = prioritizeEarliest;
            invalidateRunnableAt();
            return true;
        } else {
            return false;
        }
    }

    /**
+17 −37
Original line number Diff line number Diff line
@@ -361,6 +361,8 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
        // If app isn't running, and there's nothing in the queue, clean up
        if (queue.isEmpty() && !queue.isActive() && !queue.isProcessWarm()) {
            removeProcessQueue(queue.processName, queue.uid);
        } else {
            updateQueueDeferred(queue);
        }
    }

@@ -495,7 +497,8 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
        // relevant per-process queue
        final BroadcastProcessQueue queue = getProcessQueue(app);
        if (queue != null) {
            setQueueProcess(queue, app);
            queue.setProcess(app);
            queue.setUidFrozen(mUidFrozen.get(queue.uid, false));
        }

        boolean didSomething = false;
@@ -536,7 +539,8 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
        // relevant per-process queue
        final BroadcastProcessQueue queue = getProcessQueue(app);
        if (queue != null) {
            setQueueProcess(queue, null);
            queue.setProcess(null);
            queue.setUidFrozen(mUidFrozen.get(queue.uid, false));
        }

        if ((mRunningColdStart != null) && (mRunningColdStart == queue)) {
@@ -563,7 +567,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
                return (r.receivers.get(i) instanceof BroadcastFilter);
            }, mBroadcastConsumerSkip, true);
            if (didSomething || queue.isEmpty()) {
                updateQueueDeferred(queue);
                updateRunnableList(queue);
                enqueueUpdateRunningList();
            }
@@ -629,7 +632,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
                setDeliveryState(queue, null, r, i, receiver, BroadcastRecord.DELIVERY_DEFERRED,
                        "deferred at enqueue time");
            }
            updateQueueDeferred(queue);
            updateRunnableList(queue);
            enqueueUpdateRunningList();
        }
@@ -1078,7 +1080,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue {

            final int queueIndex = getRunningIndexOf(queue);
            mRunning[queueIndex] = null;
            updateQueueDeferred(queue);
            updateRunnableList(queue);
            enqueueUpdateRunningList();

@@ -1161,7 +1162,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
                                getReceiverUid(otherReceiver));
                        if (otherQueue != null) {
                            otherQueue.invalidateRunnableAt();
                            updateQueueDeferred(otherQueue);
                            updateRunnableList(otherQueue);
                        }
                    }
@@ -1294,7 +1294,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
                if (queuePredicate.test(leaf)) {
                    if (leaf.forEachMatchingBroadcast(broadcastPredicate,
                            broadcastConsumer, andRemove)) {
                        updateQueueDeferred(leaf);
                        updateRunnableList(leaf);
                        didSomething = true;
                    }
@@ -1308,40 +1307,29 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
        return didSomething;
    }

    private boolean forEachMatchingQueue(
    private void forEachMatchingQueue(
            @NonNull Predicate<BroadcastProcessQueue> queuePredicate,
            @NonNull Consumer<BroadcastProcessQueue> queueConsumer) {
        boolean didSomething = false;
        for (int i = mProcessQueues.size() - 1; i >= 0; i--) {
            BroadcastProcessQueue leaf = mProcessQueues.valueAt(i);
            while (leaf != null) {
                if (queuePredicate.test(leaf)) {
                    queueConsumer.accept(leaf);
                    updateQueueDeferred(leaf);
                    updateRunnableList(leaf);
                    didSomething = true;
                }
                leaf = leaf.processNameNext;
            }
        }
        if (didSomething) {
            enqueueUpdateRunningList();
        }
        return didSomething;
    }

    @SuppressWarnings("CheckResult")
    private void updateQueueDeferred(@NonNull BroadcastProcessQueue leaf) {
    private void updateQueueDeferred(
            @NonNull BroadcastProcessQueue leaf) {
        if (leaf.isDeferredUntilActive()) {
            // We ignore the returned value here since callers are invoking us
            // just before updateRunnableList()
            leaf.forEachMatchingBroadcast((r, i) -> {
                return r.deferUntilActive && (r.getDeliveryState(i)
                        == BroadcastRecord.DELIVERY_PENDING);
            }, mBroadcastConsumerDefer, false);
        } else if (leaf.hasDeferredBroadcasts()) {
            // We ignore the returned value here since callers are invoking us
            // just before updateRunnableList()
            leaf.forEachMatchingBroadcast((r, i) -> {
                return r.deferUntilActive && (r.getDeliveryState(i)
                        == BroadcastRecord.DELIVERY_DEFERRED);
@@ -1371,7 +1359,10 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
                        while (leaf != null) {
                            // Update internal state by refreshing values previously
                            // read from any known running process
                            setQueueProcess(leaf, leaf.app);
                            leaf.setProcess(leaf.app);
                            leaf.setUidFrozen(frozen);
                            updateQueueDeferred(leaf);
                            updateRunnableList(leaf);
                            leaf = leaf.processNameNext;
                        }
                        enqueueUpdateRunningList();
@@ -1534,20 +1525,8 @@ class BroadcastQueueModernImpl extends BroadcastQueue {

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

    /**
     * Update the {@link ProcessRecord} associated with the given
     * {@link BroadcastProcessQueue}. Also updates any runnable status that
     * might have changed as a side-effect.
     */
    private void setQueueProcess(@NonNull BroadcastProcessQueue queue,
            @Nullable ProcessRecord app) {
        if (queue.setProcessAndUidFrozen(app, mUidFrozen.get(queue.uid, false))) {
            updateQueueDeferred(queue);
            updateRunnableList(queue);
            queue.setProcess(mService.getProcessRecordLocked(queue.processName, queue.uid));
            queue.setUidFrozen(mUidFrozen.get(queue.uid, false));
        }
    }

@@ -1741,7 +1720,8 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
        }

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

        if (leaf == null) {
            mProcessQueues.put(uid, created);
+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.setProcessAndUidFrozen(null, false);
        queue.setUidFrozen(false);
        final long notCachedRunnableAt = queue.getRunnableAt();
        queue.setProcessAndUidFrozen(null, true);
        queue.setUidFrozen(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.setProcessAndUidFrozen(null, false);
        queue.setUidFrozen(false);
        final long notCachedRunnableAt = queue.getRunnableAt();
        queue.setProcessAndUidFrozen(null, true);
        queue.setUidFrozen(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.setProcessAndUidFrozen(null, false);
        queue.setUidFrozen(false);
        assertTrue(queue.isRunnable());
        assertThat(queue.getRunnableAt()).isAtMost(airplaneRecord.enqueueClockTime);
        assertEquals(ProcessList.SCHED_GROUP_DEFAULT, queue.getPreferredSchedulingGroupLocked());
        assertEquals(queue.peekNextBroadcastRecord(), airplaneRecord);

        queue.setProcessAndUidFrozen(null, true);
        queue.setUidFrozen(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_Frozen(BroadcastRecord testRecord, int testRunnableAtReason) {
        final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants,
                PACKAGE_GREEN, getUidForPackage(PACKAGE_GREEN));
        queue.setProcessAndUidFrozen(null, true);
        queue.setUidFrozen(true);

        final BroadcastRecord lazyRecord = makeBroadcastRecord(
                new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED),