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

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

Merge "BroadcastQueue: "offload" after other broadcasts."

parents 98e013f6 5d833082
Loading
Loading
Loading
Loading
+57 −22
Original line number Diff line number Diff line
@@ -114,7 +114,14 @@ class BroadcastProcessQueue {
     * dispatched to this process, in the same representation as
     * {@link #mPending}.
     */
    private final ArrayDeque<SomeArgs> mPendingUrgent = new ArrayDeque<>();
    private final ArrayDeque<SomeArgs> mPendingUrgent = new ArrayDeque<>(4);

    /**
     * Ordered collection of "offload" broadcasts that are waiting to be
     * dispatched to this process, in the same representation as
     * {@link #mPending}.
     */
    private final ArrayDeque<SomeArgs> mPendingOffload = new ArrayDeque<>(4);

    /**
     * Broadcast actively being dispatched to this process.
@@ -148,8 +155,7 @@ class BroadcastProcessQueue {
    private boolean mActiveViaColdStart;

    /**
     * Count of {@link #mPending} and {@link #mPendingUrgent} broadcasts of
     * these various flavors.
     * Count of pending broadcasts of these various flavors.
     */
    private int mCountForeground;
    private int mCountOrdered;
@@ -177,6 +183,16 @@ class BroadcastProcessQueue {
        this.uid = uid;
    }

    private @NonNull ArrayDeque<SomeArgs> getQueueForBroadcast(@NonNull BroadcastRecord record) {
        if (record.isUrgent()) {
            return mPendingUrgent;
        } else if (record.isOffload()) {
            return mPendingOffload;
        } else {
            return mPending;
        }
    }

    /**
     * Enqueue the given broadcast to be dispatched to this process at some
     * future point in time. The target receiver is indicated by the given index
@@ -193,10 +209,12 @@ class BroadcastProcessQueue {
    public void enqueueOrReplaceBroadcast(@NonNull BroadcastRecord record, int recordIndex,
            int blockedUntilTerminalCount) {
        if (record.isReplacePending()) {
            boolean didReplace = replaceBroadcastInQueue(mPending,
                    record, recordIndex, blockedUntilTerminalCount)
                    || replaceBroadcastInQueue(mPendingUrgent,
                    record, recordIndex, blockedUntilTerminalCount);
            boolean didReplace = replaceBroadcastInQueue(mPending, record, recordIndex,
                    blockedUntilTerminalCount)
                    || replaceBroadcastInQueue(mPendingUrgent, record, recordIndex,
                            blockedUntilTerminalCount)
                    || replaceBroadcastInQueue(mPendingOffload, record, recordIndex,
                            blockedUntilTerminalCount);
            if (didReplace) {
                return;
            }
@@ -213,8 +231,7 @@ class BroadcastProcessQueue {
        // issued ahead of others that are already pending, for example if this new
        // broadcast is in a different delivery class or is tied to a direct user interaction
        // with implicit responsiveness expectations.
        final ArrayDeque<SomeArgs> queue = record.isUrgent() ? mPendingUrgent : mPending;
        queue.addLast(newBroadcastArgs);
        getQueueForBroadcast(record).addLast(newBroadcastArgs);
        onBroadcastEnqueued(record, recordIndex);
    }

@@ -279,10 +296,13 @@ class BroadcastProcessQueue {
     */
    public boolean forEachMatchingBroadcast(@NonNull BroadcastPredicate predicate,
            @NonNull BroadcastConsumer consumer, boolean andRemove) {
        boolean didSomething = forEachMatchingBroadcastInQueue(mPending,
        boolean didSomething = false;
        didSomething |= forEachMatchingBroadcastInQueue(mPending,
                predicate, consumer, andRemove);
        didSomething |= forEachMatchingBroadcastInQueue(mPendingUrgent,
                predicate, consumer, andRemove);
        didSomething |= forEachMatchingBroadcastInQueue(mPendingOffload,
                predicate, consumer, andRemove);
        return didSomething;
    }

@@ -516,7 +536,7 @@ class BroadcastProcessQueue {
    }

    public boolean isEmpty() {
        return mPending.isEmpty() && mPendingUrgent.isEmpty();
        return mPending.isEmpty() && mPendingUrgent.isEmpty() && mPendingOffload.isEmpty();
    }

    public boolean isActive() {
@@ -537,6 +557,8 @@ class BroadcastProcessQueue {
            return mPendingUrgent;
        } else if (!mPending.isEmpty()) {
            return mPending;
        } else if (!mPendingOffload.isEmpty()) {
            return mPendingOffload;
        }
        return null;
    }
@@ -581,12 +603,15 @@ class BroadcastProcessQueue {
        }
        final SomeArgs next = mPending.peekFirst();
        final SomeArgs nextUrgent = mPendingUrgent.peekFirst();
        final SomeArgs nextOffload = mPendingOffload.peekFirst();
        // Empty queue is past any barrier
        final boolean nextLater = next == null
        final boolean nextLater = (next == null)
                || ((BroadcastRecord) next.arg1).enqueueTime > barrierTime;
        final boolean nextUrgentLater = nextUrgent == null
        final boolean nextUrgentLater = (nextUrgent == null)
                || ((BroadcastRecord) nextUrgent.arg1).enqueueTime > barrierTime;
        return nextLater && nextUrgentLater;
        final boolean nextOffloadLater = (nextOffload == null)
                || ((BroadcastRecord) nextOffload.arg1).enqueueTime > barrierTime;
        return nextLater && nextUrgentLater && nextOffloadLater;
    }

    public boolean isRunnable() {
@@ -726,8 +751,9 @@ class BroadcastProcessQueue {

            // If we have too many broadcasts pending, bypass any delays that
            // might have been applied above to aid draining
            if (mPending.size() + mPendingUrgent.size() >= constants.MAX_PENDING_BROADCASTS) {
                mRunnableAt = runnableAt;
            if (mPending.size() + mPendingUrgent.size()
                    + mPendingOffload.size() >= constants.MAX_PENDING_BROADCASTS) {
                mRunnableAt = Math.min(mRunnableAt, runnableAt);
                mRunnableAtReason = REASON_MAX_PENDING;
            }
        } else {
@@ -845,23 +871,28 @@ class BroadcastProcessQueue {
        pw.println();
        pw.increaseIndent();
        if (mActive != null) {
            dumpRecord(now, pw, mActive, mActiveIndex, mActiveBlockedUntilTerminalCount);
            dumpRecord("ACTIVE", now, pw, mActive, mActiveIndex, mActiveBlockedUntilTerminalCount);
        }
        for (SomeArgs args : mPendingUrgent) {
            final BroadcastRecord r = (BroadcastRecord) args.arg1;
            dumpRecord(now, pw, r, args.argi1, args.argi2);
            dumpRecord("URGENT", now, pw, r, args.argi1, args.argi2);
        }
        for (SomeArgs args : mPending) {
            final BroadcastRecord r = (BroadcastRecord) args.arg1;
            dumpRecord(now, pw, r, args.argi1, args.argi2);
            dumpRecord(null, now, pw, r, args.argi1, args.argi2);
        }
        for (SomeArgs args : mPendingOffload) {
            final BroadcastRecord r = (BroadcastRecord) args.arg1;
            dumpRecord("OFFLOAD", now, pw, r, args.argi1, args.argi2);
        }
        pw.decreaseIndent();
        pw.println();
    }

    @NeverCompile
    private void dumpRecord(@UptimeMillisLong long now, @NonNull IndentingPrintWriter pw,
            @NonNull BroadcastRecord record, int recordIndex, int blockedUntilTerminalCount) {
    private void dumpRecord(@Nullable String flavor, @UptimeMillisLong long now,
            @NonNull IndentingPrintWriter pw, @NonNull BroadcastRecord record, int recordIndex,
            int blockedUntilTerminalCount) {
        TimeUtils.formatDuration(record.enqueueTime, now, pw);
        pw.print(' ');
        pw.println(record.toShortString());
@@ -872,6 +903,10 @@ class BroadcastProcessQueue {
            pw.print(" at ");
            TimeUtils.formatDuration(record.scheduledTime[recordIndex], now, pw);
        }
        if (flavor != null) {
            pw.print(' ');
            pw.print(flavor);
        }
        final Object receiver = record.receivers.get(recordIndex);
        if (receiver instanceof BroadcastFilter) {
            final BroadcastFilter filter = (BroadcastFilter) receiver;
+4 −0
Original line number Diff line number Diff line
@@ -617,6 +617,10 @@ final class BroadcastRecord extends Binder {
        return (intent.getFlags() & Intent.FLAG_RECEIVER_NO_ABORT) != 0;
    }

    boolean isOffload() {
        return (intent.getFlags() & Intent.FLAG_RECEIVER_OFFLOAD) != 0;
    }

    /**
     * Core policy determination about this broadcast's delivery prioritization
     */