1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.am;
18 
19 import static com.android.internal.util.Preconditions.checkState;
20 import static com.android.server.am.BroadcastRecord.deliveryStateToString;
21 import static com.android.server.am.BroadcastRecord.isReceiverEquals;
22 
23 import android.annotation.CheckResult;
24 import android.annotation.IntDef;
25 import android.annotation.NonNull;
26 import android.annotation.Nullable;
27 import android.annotation.UptimeMillisLong;
28 import android.app.ActivityManager;
29 import android.app.BroadcastOptions;
30 import android.content.Intent;
31 import android.content.pm.ResolveInfo;
32 import android.os.SystemClock;
33 import android.os.Trace;
34 import android.os.UserHandle;
35 import android.text.format.DateUtils;
36 import android.util.IndentingPrintWriter;
37 import android.util.TimeUtils;
38 
39 import com.android.internal.annotations.VisibleForTesting;
40 import com.android.internal.os.SomeArgs;
41 
42 import dalvik.annotation.optimization.NeverCompile;
43 
44 import java.lang.annotation.Retention;
45 import java.lang.annotation.RetentionPolicy;
46 import java.util.ArrayDeque;
47 import java.util.ArrayList;
48 import java.util.Iterator;
49 import java.util.Objects;
50 
51 /**
52  * Queue of pending {@link BroadcastRecord} entries intended for delivery to a
53  * specific process.
54  * <p>
55  * Each queue has a concept of being "runnable at" a particular time in the
56  * future, which supports arbitrarily pausing or delaying delivery on a
57  * per-process basis.
58  * <p>
59  * Internally each queue consists of a pending broadcasts which are waiting to
60  * be dispatched, and a single active broadcast which is currently being
61  * dispatched.
62  * <p>
63  * This entire class is marked as {@code NotThreadSafe} since it's the
64  * responsibility of the caller to always interact with a relevant lock held.
65  */
66 // @NotThreadSafe
67 class BroadcastProcessQueue {
68     static final boolean VERBOSE = false;
69     final @NonNull BroadcastConstants constants;
70     final @NonNull String processName;
71     final int uid;
72 
73     /**
74      * Linked list connection to another process under this {@link #uid} which
75      * has a different {@link #processName}.
76      */
77     @Nullable BroadcastProcessQueue processNameNext;
78 
79     /**
80      * Linked list connections to runnable process with lower and higher
81      * {@link #getRunnableAt()} times.
82      */
83     @Nullable BroadcastProcessQueue runnableAtNext;
84     @Nullable BroadcastProcessQueue runnableAtPrev;
85 
86     /**
87      * Currently known details about the target process; typically undefined
88      * when the process isn't actively running.
89      */
90     @Nullable ProcessRecord app;
91 
92     /**
93      * Track name to use for {@link Trace} events, defined as part of upgrading
94      * into a running slot.
95      */
96     @Nullable String runningTraceTrackName;
97 
98     /**
99      * Flag indicating if this process should be OOM adjusted, defined as part
100      * of upgrading into a running slot.
101      */
102     boolean runningOomAdjusted;
103 
104     /**
105      * True if a timer has been started against this queue.
106      */
107     private boolean mTimeoutScheduled;
108 
109     /**
110      * Snapshotted value of {@link ProcessRecord#getCpuDelayTime()}, typically
111      * used when deciding if we should extend the soft ANR timeout.
112      *
113      * Required when Flags.anrTimerServiceEnabled is false.
114      */
115     long lastCpuDelayTime;
116 
117      /**
118      * Snapshotted value of {@link ProcessStateRecord#getCurProcState()} before
119      * dispatching the current broadcast to the receiver in this process.
120      */
121     int lastProcessState;
122 
123     /**
124      * Ordered collection of broadcasts that are waiting to be dispatched to
125      * this process, as a pair of {@link BroadcastRecord} and the index into
126      * {@link BroadcastRecord#receivers} that represents the receiver.
127      */
128     private final ArrayDeque<SomeArgs> mPending = new ArrayDeque<>();
129 
130     /**
131      * Ordered collection of "urgent" broadcasts that are waiting to be
132      * dispatched to this process, in the same representation as
133      * {@link #mPending}.
134      */
135     private final ArrayDeque<SomeArgs> mPendingUrgent = new ArrayDeque<>(4);
136 
137     /**
138      * Ordered collection of "offload" broadcasts that are waiting to be
139      * dispatched to this process, in the same representation as
140      * {@link #mPending}.
141      */
142     private final ArrayDeque<SomeArgs> mPendingOffload = new ArrayDeque<>(4);
143 
144     /**
145      * Broadcast actively being dispatched to this process.
146      */
147     private @Nullable BroadcastRecord mActive;
148 
149     /**
150      * Receiver actively being dispatched to in this process. This is an index
151      * into the {@link BroadcastRecord#receivers} list of {@link #mActive}.
152      */
153     private int mActiveIndex;
154 
155     /**
156      * True if the broadcast actively being dispatched to this process was re-enqueued previously.
157      */
158     private boolean mActiveReEnqueued;
159 
160     /**
161      * Count of {@link #mActive} broadcasts that have been dispatched since this
162      * queue was last idle.
163      */
164     private int mActiveCountSinceIdle;
165 
166     /**
167      * Count of {@link #mActive} broadcasts with assumed delivery that have been dispatched
168      * since this queue was last idle.
169      */
170     private int mActiveAssumedDeliveryCountSinceIdle;
171 
172     /**
173      * Flag indicating that the currently active broadcast is being dispatched
174      * was scheduled via a cold start.
175      */
176     private boolean mActiveViaColdStart;
177 
178     /**
179      * Flag indicating that the currently active broadcast is being dispatched
180      * to a package that was in the stopped state.
181      */
182     private boolean mActiveWasStopped;
183 
184     /**
185      * Flag indicating that the currently active broadcast is being dispatched
186      * to a package that was never launched before.
187      */
188     private boolean mActiveFirstLaunch;
189 
190     /**
191      * Number of consecutive urgent broadcasts that have been dispatched
192      * since the last non-urgent dispatch.
193      */
194     private int mActiveCountConsecutiveUrgent;
195 
196     /**
197      * Number of consecutive normal broadcasts that have been dispatched
198      * since the last offload dispatch.
199      */
200     private int mActiveCountConsecutiveNormal;
201 
202     /**
203      * Count of pending broadcasts of these various flavors.
204      */
205     private int mCountEnqueued;
206     private int mCountDeferred;
207     private int mCountForeground;
208     private int mCountForegroundDeferred;
209     private int mCountOrdered;
210     private int mCountAlarm;
211     private int mCountPrioritized;
212     private int mCountPrioritizedDeferred;
213     private int mCountInteractive;
214     private int mCountResultTo;
215     private int mCountInstrumented;
216     private int mCountManifest;
217 
218     private int mCountPrioritizeEarliestRequests;
219 
220     private @UptimeMillisLong long mRunnableAt = Long.MAX_VALUE;
221     private @Reason int mRunnableAtReason = REASON_EMPTY;
222     private boolean mRunnableAtInvalidated;
223 
224     /**
225      * Last state applied by {@link #updateDeferredStates}, used to quickly
226      * determine if a state transition is occurring.
227      */
228     private boolean mLastDeferredStates;
229 
230     private boolean mUidForeground;
231     private boolean mProcessFreezable;
232     private boolean mProcessInstrumented;
233     private boolean mProcessPersistent;
234 
235     private String mCachedToString;
236     private String mCachedToShortString;
237 
238     /**
239      * The duration by which any broadcasts to this process need to be delayed
240      */
241     private long mForcedDelayedDurationMs;
242 
243     /**
244      * List of outgoing broadcasts from a freezable process.
245      */
246     private final ArrayList<BroadcastRecord> mOutgoingBroadcasts = new ArrayList<>();
247 
BroadcastProcessQueue(@onNull BroadcastConstants constants, @NonNull String processName, int uid)248     public BroadcastProcessQueue(@NonNull BroadcastConstants constants,
249             @NonNull String processName, int uid) {
250         this.constants = Objects.requireNonNull(constants);
251         this.processName = Objects.requireNonNull(processName);
252         this.uid = uid;
253     }
254 
getQueueForBroadcast(@onNull BroadcastRecord record)255     private @NonNull ArrayDeque<SomeArgs> getQueueForBroadcast(@NonNull BroadcastRecord record) {
256         if (record.isUrgent()) {
257             return mPendingUrgent;
258         } else if (record.isOffload()) {
259             return mPendingOffload;
260         } else {
261             return mPending;
262         }
263     }
264 
enqueueOutgoingBroadcast(@onNull BroadcastRecord record)265     public void enqueueOutgoingBroadcast(@NonNull BroadcastRecord record) {
266         mOutgoingBroadcasts.add(record);
267     }
268 
getOutgoingBroadcastCount()269     public int getOutgoingBroadcastCount() {
270         return mOutgoingBroadcasts.size();
271     }
272 
enqueueOutgoingBroadcasts(@onNull BroadcastRecordConsumer consumer)273     public void enqueueOutgoingBroadcasts(@NonNull BroadcastRecordConsumer consumer) {
274         for (int i = 0; i < mOutgoingBroadcasts.size(); ++i) {
275             consumer.accept(mOutgoingBroadcasts.get(i));
276         }
277         mOutgoingBroadcasts.clear();
278     }
279 
clearOutgoingBroadcasts()280     public void clearOutgoingBroadcasts() {
281         mOutgoingBroadcasts.clear();
282     }
283 
284     /**
285      * Enqueue the given broadcast to be dispatched to this process at some
286      * future point in time. The target receiver is indicated by the given index
287      * into {@link BroadcastRecord#receivers}.
288      * <p>
289      * If the broadcast is marked as {@link BroadcastRecord#isReplacePending()},
290      * then this call will replace any pending dispatch; otherwise it will
291      * enqueue as a normal broadcast.
292      * <p>
293      * When defined, this receiver is considered "blocked" until at least the
294      * given count of other receivers have reached a terminal state; typically
295      * used for ordered broadcasts and priority traunches.
296      *
297      * @return the existing broadcast record in the queue that was replaced with a newer broadcast
298      *         sent with {@link Intent#FLAG_RECEIVER_REPLACE_PENDING} or {@code null} if there
299      *         wasn't any broadcast that was replaced.
300      */
301     @Nullable
enqueueOrReplaceBroadcast(@onNull BroadcastRecord record, int recordIndex, @NonNull BroadcastConsumer deferredStatesApplyConsumer)302     public BroadcastRecord enqueueOrReplaceBroadcast(@NonNull BroadcastRecord record,
303             int recordIndex, @NonNull BroadcastConsumer deferredStatesApplyConsumer) {
304         // Ignore FLAG_RECEIVER_REPLACE_PENDING if the sender specified the policy using the
305         // BroadcastOptions delivery group APIs.
306         if (record.isReplacePending()
307                 && record.getDeliveryGroupPolicy() == BroadcastOptions.DELIVERY_GROUP_POLICY_ALL) {
308             final BroadcastRecord replacedBroadcastRecord = replaceBroadcast(record, recordIndex);
309             if (replacedBroadcastRecord != null) {
310                 if (mLastDeferredStates && shouldBeDeferred()
311                         && (record.getDeliveryState(recordIndex)
312                                 == BroadcastRecord.DELIVERY_PENDING)) {
313                     deferredStatesApplyConsumer.accept(record, recordIndex);
314                 }
315                 return replacedBroadcastRecord;
316             }
317         }
318 
319         // Caller isn't interested in replacing, or we didn't find any pending
320         // item to replace above, so enqueue as a new broadcast
321         SomeArgs newBroadcastArgs = SomeArgs.obtain();
322         newBroadcastArgs.arg1 = record;
323         newBroadcastArgs.argi1 = recordIndex;
324 
325         // Cross-broadcast prioritization policy:  some broadcasts might warrant being
326         // issued ahead of others that are already pending, for example if this new
327         // broadcast is in a different delivery class or is tied to a direct user interaction
328         // with implicit responsiveness expectations.
329         getQueueForBroadcast(record).addLast(newBroadcastArgs);
330         onBroadcastEnqueued(record, recordIndex);
331 
332         // When updateDeferredStates() has already applied a deferred state to
333         // all pending items, apply to this new broadcast too
334         if (mLastDeferredStates && shouldBeDeferred()
335                 && (record.getDeliveryState(recordIndex) == BroadcastRecord.DELIVERY_PENDING)) {
336             deferredStatesApplyConsumer.accept(record, recordIndex);
337         }
338         return null;
339     }
340 
341     /**
342      * Re-enqueue the active broadcast so that it can be made active and delivered again. In order
343      * to keep its previous position same to avoid issues with reordering, insert it at the head
344      * of the queue.
345      *
346      * Callers are responsible for clearing the active broadcast by calling
347      * {@link #makeActiveIdle()} after re-enqueuing it.
348      */
reEnqueueActiveBroadcast()349     public void reEnqueueActiveBroadcast() {
350         final BroadcastRecord record = getActive();
351         final int recordIndex = getActiveIndex();
352 
353         final SomeArgs broadcastArgs = SomeArgs.obtain();
354         broadcastArgs.arg1 = record;
355         broadcastArgs.argi1 = recordIndex;
356         broadcastArgs.argi2 = 1;
357         getQueueForBroadcast(record).addFirst(broadcastArgs);
358         onBroadcastEnqueued(record, recordIndex);
359     }
360 
361     /**
362      * Searches from newest to oldest in the pending broadcast queues, and at the first matching
363      * pending broadcast it finds, replaces it in-place and returns -- does not attempt to handle
364      * "duplicate" broadcasts in the queue.
365      *
366      * @return the existing broadcast record in the queue that was replaced with a newer broadcast
367      *         sent with {@link Intent#FLAG_RECEIVER_REPLACE_PENDING} or {@code null} if there
368      *         wasn't any broadcast that was replaced.
369      */
370     @Nullable
replaceBroadcast(@onNull BroadcastRecord record, int recordIndex)371     private BroadcastRecord replaceBroadcast(@NonNull BroadcastRecord record, int recordIndex) {
372         final ArrayDeque<SomeArgs> queue = getQueueForBroadcast(record);
373         return replaceBroadcastInQueue(queue, record, recordIndex);
374     }
375 
376     /**
377      * Searches from newest to oldest, and at the first matching pending broadcast
378      * it finds, replaces it in-place and returns -- does not attempt to handle
379      * "duplicate" broadcasts in the queue.
380      *
381      * @return the existing broadcast record in the queue that was replaced with a newer broadcast
382      *         sent with {@link Intent#FLAG_RECEIVER_REPLACE_PENDING} or {@code null} if there
383      *         wasn't any broadcast that was replaced.
384      */
385     @Nullable
replaceBroadcastInQueue(@onNull ArrayDeque<SomeArgs> queue, @NonNull BroadcastRecord record, int recordIndex)386     private BroadcastRecord replaceBroadcastInQueue(@NonNull ArrayDeque<SomeArgs> queue,
387             @NonNull BroadcastRecord record, int recordIndex) {
388         final Iterator<SomeArgs> it = queue.descendingIterator();
389         final Object receiver = record.receivers.get(recordIndex);
390         while (it.hasNext()) {
391             final SomeArgs args = it.next();
392             final BroadcastRecord testRecord = (BroadcastRecord) args.arg1;
393             final int testRecordIndex = args.argi1;
394             final Object testReceiver = testRecord.receivers.get(testRecordIndex);
395             // If we come across the record that's being enqueued in the queue, then that means
396             // we already enqueued it for a receiver in this process and trying to insert a new
397             // one past this could create priority inversion in the queue, so bail out.
398             if (record == testRecord) {
399                 break;
400             }
401             if ((record.callingUid == testRecord.callingUid)
402                     && (record.userId == testRecord.userId)
403                     && record.intent.filterEquals(testRecord.intent)
404                     && isReceiverEquals(receiver, testReceiver)
405                     && testRecord.allReceiversPending()
406                     && record.isMatchingRecord(testRecord)) {
407                 // Exact match found; perform in-place swap
408                 args.arg1 = record;
409                 args.argi1 = recordIndex;
410                 record.copyEnqueueTimeFrom(testRecord);
411                 onBroadcastDequeued(testRecord, testRecordIndex);
412                 onBroadcastEnqueued(record, recordIndex);
413                 return testRecord;
414             }
415         }
416         return null;
417     }
418 
419     /**
420      * Functional interface that tests a {@link BroadcastRecord} and an index in the
421      * {@link BroadcastRecord} that has been previously enqueued in {@link BroadcastProcessQueue}.
422      */
423     @FunctionalInterface
424     public interface BroadcastPredicate {
test(@onNull BroadcastRecord r, int index)425         boolean test(@NonNull BroadcastRecord r, int index);
426     }
427 
428     /**
429      * Functional interface that consumes a {@link BroadcastRecord} and an index in the
430      * {@link BroadcastRecord} that has been previously enqueued in {@link BroadcastProcessQueue}.
431      */
432     @FunctionalInterface
433     public interface BroadcastConsumer {
accept(@onNull BroadcastRecord r, int index)434         void accept(@NonNull BroadcastRecord r, int index);
435     }
436 
437     /**
438      * Functional interface that consumes a {@link BroadcastRecord} that has
439      * been previously enqueued in {@link BroadcastProcessQueue}.
440      */
441     @FunctionalInterface
442     public interface BroadcastRecordConsumer {
accept(@onNull BroadcastRecord r)443         void accept(@NonNull BroadcastRecord r);
444     }
445 
446     /**
447      * Invoke given consumer for any broadcasts matching given predicate. If
448      * requested, matching broadcasts will also be removed from this queue.
449      * <p>
450      * Predicates that choose to remove a broadcast <em>must</em> finish
451      * delivery of the matched broadcast, to ensure that situations like ordered
452      * broadcasts are handled consistently.
453      *
454      * @return if this operation may have changed internal state, indicating
455      *         that the caller is responsible for invoking
456      *         {@link BroadcastQueueModernImpl#updateRunnableList}
457      */
458     @CheckResult
forEachMatchingBroadcast(@onNull BroadcastPredicate predicate, @NonNull BroadcastConsumer consumer, boolean andRemove)459     public boolean forEachMatchingBroadcast(@NonNull BroadcastPredicate predicate,
460             @NonNull BroadcastConsumer consumer, boolean andRemove) {
461         boolean didSomething = false;
462         didSomething |= forEachMatchingBroadcastInQueue(mPending,
463                 predicate, consumer, andRemove);
464         didSomething |= forEachMatchingBroadcastInQueue(mPendingUrgent,
465                 predicate, consumer, andRemove);
466         didSomething |= forEachMatchingBroadcastInQueue(mPendingOffload,
467                 predicate, consumer, andRemove);
468         return didSomething;
469     }
470 
471     @CheckResult
forEachMatchingBroadcastInQueue(@onNull ArrayDeque<SomeArgs> queue, @NonNull BroadcastPredicate predicate, @NonNull BroadcastConsumer consumer, boolean andRemove)472     private boolean forEachMatchingBroadcastInQueue(@NonNull ArrayDeque<SomeArgs> queue,
473             @NonNull BroadcastPredicate predicate, @NonNull BroadcastConsumer consumer,
474             boolean andRemove) {
475         boolean didSomething = false;
476         final Iterator<SomeArgs> it = queue.iterator();
477         while (it.hasNext()) {
478             final SomeArgs args = it.next();
479             final BroadcastRecord record = (BroadcastRecord) args.arg1;
480             final int recordIndex = args.argi1;
481             if (predicate.test(record, recordIndex)) {
482                 consumer.accept(record, recordIndex);
483                 if (andRemove) {
484                     args.recycle();
485                     it.remove();
486                     onBroadcastDequeued(record, recordIndex);
487                 } else {
488                     // Even if we're leaving broadcast in queue, it may have
489                     // been mutated in such a way to change our runnable time
490                     invalidateRunnableAt();
491                 }
492                 didSomething = true;
493             }
494         }
495         // TODO: also check any active broadcast once we have a better "nonce"
496         // representing each scheduled broadcast to avoid races
497         return didSomething;
498     }
499 
500     /**
501      * Update the actively running "warm" process for this process.
502      *
503      * @return if this operation may have changed internal state, indicating
504      *         that the caller is responsible for invoking
505      *         {@link BroadcastQueueModernImpl#updateRunnableList}
506      */
507     @CheckResult
setProcessAndUidState(@ullable ProcessRecord app, boolean uidForeground, boolean processFreezable)508     public boolean setProcessAndUidState(@Nullable ProcessRecord app, boolean uidForeground,
509             boolean processFreezable) {
510         this.app = app;
511 
512         // Since we may have just changed our PID, invalidate cached strings
513         mCachedToString = null;
514         mCachedToShortString = null;
515 
516         boolean didSomething = false;
517         if (app != null) {
518             didSomething |= setUidForeground(uidForeground);
519             didSomething |= setProcessFreezable(processFreezable);
520             didSomething |= setProcessInstrumented(app.getActiveInstrumentation() != null);
521             didSomething |= setProcessPersistent(app.isPersistent());
522         } else {
523             didSomething |= setUidForeground(false);
524             didSomething |= setProcessFreezable(false);
525             didSomething |= setProcessInstrumented(false);
526             didSomething |= setProcessPersistent(false);
527         }
528         return didSomething;
529     }
530 
531     /**
532      * Update if the UID this process is belongs to is in "foreground" state, which signals
533      * broadcast dispatch should prioritize delivering broadcasts to this process to minimize any
534      * delays in UI updates.
535      */
536     @CheckResult
setUidForeground(boolean uidForeground)537     private boolean setUidForeground(boolean uidForeground) {
538         if (mUidForeground != uidForeground) {
539             mUidForeground = uidForeground;
540             invalidateRunnableAt();
541             return true;
542         } else {
543             return false;
544         }
545     }
546 
547     /**
548      * Update if this process is in the "freezable" state, typically signaling that
549      * broadcast dispatch should be paused or delayed.
550      */
551     @CheckResult
setProcessFreezable(boolean freezable)552     private boolean setProcessFreezable(boolean freezable) {
553         if (mProcessFreezable != freezable) {
554             mProcessFreezable = freezable;
555             invalidateRunnableAt();
556             return true;
557         } else {
558             return false;
559         }
560     }
561 
562     /**
563      * Update if this process is in the "instrumented" state, typically
564      * signaling that broadcast dispatch should bypass all pauses or delays, to
565      * avoid holding up test suites.
566      */
567     @CheckResult
setProcessInstrumented(boolean instrumented)568     private boolean setProcessInstrumented(boolean instrumented) {
569         if (mProcessInstrumented != instrumented) {
570             mProcessInstrumented = instrumented;
571             invalidateRunnableAt();
572             return true;
573         } else {
574             return false;
575         }
576     }
577 
578     /**
579      * Update if this process is in the "persistent" state, which signals broadcast dispatch should
580      * bypass all pauses or delays to prevent the system from becoming out of sync with itself.
581      */
582     @CheckResult
setProcessPersistent(boolean persistent)583     private boolean setProcessPersistent(boolean persistent) {
584         if (mProcessPersistent != persistent) {
585             mProcessPersistent = persistent;
586             invalidateRunnableAt();
587             return true;
588         } else {
589             return false;
590         }
591     }
592 
593     /**
594      * Return if we know of an actively running "warm" process for this queue.
595      */
isProcessWarm()596     public boolean isProcessWarm() {
597         return (app != null) && (app.getOnewayThread() != null) && !app.isKilled();
598     }
599 
getPreferredSchedulingGroupLocked()600     public int getPreferredSchedulingGroupLocked() {
601         if (!isActive()) {
602             return ProcessList.SCHED_GROUP_UNDEFINED;
603         } else if (mCountForeground > mCountForegroundDeferred) {
604             // We have a foreground broadcast somewhere down the queue, so
605             // boost priority until we drain them all
606             return ProcessList.SCHED_GROUP_DEFAULT;
607         } else if ((mActive != null) && mActive.isForeground()) {
608             // We have a foreground broadcast right now, so boost priority
609             return ProcessList.SCHED_GROUP_DEFAULT;
610         } else {
611             return ProcessList.SCHED_GROUP_BACKGROUND;
612         }
613     }
614 
615     /**
616      * Count of {@link #mActive} broadcasts that have been dispatched since this
617      * queue was last idle.
618      */
getActiveCountSinceIdle()619     public int getActiveCountSinceIdle() {
620         return mActiveCountSinceIdle;
621     }
622 
623     /**
624      * Count of {@link #mActive} broadcasts with assumed delivery that have been dispatched
625      * since this queue was last idle.
626      */
getActiveAssumedDeliveryCountSinceIdle()627     public int getActiveAssumedDeliveryCountSinceIdle() {
628         return mActiveAssumedDeliveryCountSinceIdle;
629     }
630 
setActiveViaColdStart(boolean activeViaColdStart)631     public void setActiveViaColdStart(boolean activeViaColdStart) {
632         mActiveViaColdStart = activeViaColdStart;
633     }
634 
setActiveWasStopped(boolean activeWasStopped)635     public void setActiveWasStopped(boolean activeWasStopped) {
636         mActiveWasStopped = activeWasStopped;
637     }
638 
setActiveFirstLaunch(boolean activeFirstLaunch)639     public void setActiveFirstLaunch(boolean activeFirstLaunch) {
640         mActiveFirstLaunch = activeFirstLaunch;
641     }
642 
getActiveViaColdStart()643     public boolean getActiveViaColdStart() {
644         return mActiveViaColdStart;
645     }
646 
getActiveWasStopped()647     public boolean getActiveWasStopped() {
648         return mActiveWasStopped;
649     }
650 
getActiveFirstLaunch()651     public boolean getActiveFirstLaunch() {
652         return mActiveFirstLaunch;
653     }
654 
655     /**
656      * Get package name of the first application loaded into this process.
657      */
658     @Nullable
getPackageName()659     public String getPackageName() {
660         return app == null ? null : app.getApplicationInfo().packageName;
661     }
662 
663     /**
664      * Set the currently active broadcast to the next pending broadcast.
665      */
makeActiveNextPending()666     public void makeActiveNextPending() {
667         // TODO: what if the next broadcast isn't runnable yet?
668         final SomeArgs next = removeNextBroadcast();
669         mActive = (BroadcastRecord) next.arg1;
670         mActiveIndex = next.argi1;
671         mActiveReEnqueued = (next.argi2 == 1);
672         mActiveCountSinceIdle++;
673         mActiveAssumedDeliveryCountSinceIdle +=
674                 (mActive.isAssumedDelivered(mActiveIndex) ? 1 : 0);
675         mActiveViaColdStart = false;
676         mActiveWasStopped = false;
677         next.recycle();
678         onBroadcastDequeued(mActive, mActiveIndex);
679     }
680 
681     /**
682      * Set the currently running broadcast to be idle.
683      */
makeActiveIdle()684     public void makeActiveIdle() {
685         mActive = null;
686         mActiveIndex = 0;
687         mActiveReEnqueued = false;
688         mActiveCountSinceIdle = 0;
689         mActiveAssumedDeliveryCountSinceIdle = 0;
690         mActiveViaColdStart = false;
691         invalidateRunnableAt();
692     }
693 
wasActiveBroadcastReEnqueued()694     public boolean wasActiveBroadcastReEnqueued() {
695         // If the flag is not enabled, treat as if the broadcast was never re-enqueued.
696         if (!Flags.avoidRepeatedBcastReEnqueues()) {
697             return false;
698         }
699         return mActiveReEnqueued;
700     }
701 
702     /**
703      * Update summary statistics when the given record has been enqueued.
704      */
onBroadcastEnqueued(@onNull BroadcastRecord record, int recordIndex)705     private void onBroadcastEnqueued(@NonNull BroadcastRecord record, int recordIndex) {
706         mCountEnqueued++;
707         if (record.deferUntilActive) {
708             mCountDeferred++;
709         }
710         if (record.isForeground()) {
711             if (record.deferUntilActive) {
712                 mCountForegroundDeferred++;
713             }
714             mCountForeground++;
715         }
716         if (record.ordered) {
717             mCountOrdered++;
718         }
719         if (record.alarm) {
720             mCountAlarm++;
721         }
722         if (record.prioritized) {
723             if (record.deferUntilActive) {
724                 mCountPrioritizedDeferred++;
725             }
726             mCountPrioritized++;
727         }
728         if (record.interactive) {
729             mCountInteractive++;
730         }
731         if (record.resultTo != null) {
732             mCountResultTo++;
733         }
734         if (record.callerInstrumented) {
735             mCountInstrumented++;
736         }
737         if (record.receivers.get(recordIndex) instanceof ResolveInfo) {
738             mCountManifest++;
739         }
740         invalidateRunnableAt();
741     }
742 
743     /**
744      * Update summary statistics when the given record has been dequeued.
745      */
onBroadcastDequeued(@onNull BroadcastRecord record, int recordIndex)746     private void onBroadcastDequeued(@NonNull BroadcastRecord record, int recordIndex) {
747         mCountEnqueued--;
748         if (record.deferUntilActive) {
749             mCountDeferred--;
750         }
751         if (record.isForeground()) {
752             if (record.deferUntilActive) {
753                 mCountForegroundDeferred--;
754             }
755             mCountForeground--;
756         }
757         if (record.ordered) {
758             mCountOrdered--;
759         }
760         if (record.alarm) {
761             mCountAlarm--;
762         }
763         if (record.prioritized) {
764             if (record.deferUntilActive) {
765                 mCountPrioritizedDeferred--;
766             }
767             mCountPrioritized--;
768         }
769         if (record.interactive) {
770             mCountInteractive--;
771         }
772         if (record.resultTo != null) {
773             mCountResultTo--;
774         }
775         if (record.callerInstrumented) {
776             mCountInstrumented--;
777         }
778         if (record.receivers.get(recordIndex) instanceof ResolveInfo) {
779             mCountManifest--;
780         }
781         invalidateRunnableAt();
782     }
783 
traceProcessStartingBegin()784     public void traceProcessStartingBegin() {
785         Trace.asyncTraceForTrackBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
786                 runningTraceTrackName, toShortString() + " starting", hashCode());
787     }
788 
traceProcessRunningBegin()789     public void traceProcessRunningBegin() {
790         Trace.asyncTraceForTrackBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
791                 runningTraceTrackName, toShortString() + " running", hashCode());
792     }
793 
traceProcessEnd()794     public void traceProcessEnd() {
795         Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER,
796                 runningTraceTrackName, hashCode());
797     }
798 
traceActiveBegin()799     public void traceActiveBegin() {
800         Trace.asyncTraceForTrackBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
801                 runningTraceTrackName, mActive.toShortString() + " scheduled", hashCode());
802     }
803 
traceActiveEnd()804     public void traceActiveEnd() {
805         Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER,
806                 runningTraceTrackName, hashCode());
807     }
808 
809     /**
810      * Return the broadcast being actively dispatched in this process.
811      */
getActive()812     public @NonNull BroadcastRecord getActive() {
813         return Objects.requireNonNull(mActive);
814     }
815 
816     /**
817      * Return the index into {@link BroadcastRecord#receivers} of the receiver
818      * being actively dispatched in this process.
819      */
getActiveIndex()820     public int getActiveIndex() {
821         Objects.requireNonNull(mActive);
822         return mActiveIndex;
823     }
824 
isOutgoingEmpty()825     public boolean isOutgoingEmpty() {
826         return mOutgoingBroadcasts.isEmpty();
827     }
828 
isEmpty()829     public boolean isEmpty() {
830         return mPending.isEmpty() && mPendingUrgent.isEmpty() && mPendingOffload.isEmpty();
831     }
832 
isActive()833     public boolean isActive() {
834         return mActive != null;
835     }
836 
837     /**
838      * @return if this operation may have changed internal state, indicating
839      *         that the caller is responsible for invoking
840      *         {@link BroadcastQueueModernImpl#updateRunnableList}
841      */
842     @CheckResult
forceDelayBroadcastDelivery(long delayedDurationMs)843     boolean forceDelayBroadcastDelivery(long delayedDurationMs) {
844         if (mForcedDelayedDurationMs != delayedDurationMs) {
845             mForcedDelayedDurationMs = delayedDurationMs;
846             invalidateRunnableAt();
847             return true;
848         } else {
849             return false;
850         }
851     }
852 
853     /**
854      * Will thrown an exception if there are no pending broadcasts; relies on
855      * {@link #isEmpty()} being false.
856      */
removeNextBroadcast()857     private @Nullable SomeArgs removeNextBroadcast() {
858         final ArrayDeque<SomeArgs> queue = queueForNextBroadcast();
859         if (queue == mPendingUrgent) {
860             mActiveCountConsecutiveUrgent++;
861         } else if (queue == mPending) {
862             mActiveCountConsecutiveUrgent = 0;
863             mActiveCountConsecutiveNormal++;
864         } else if (queue == mPendingOffload) {
865             mActiveCountConsecutiveUrgent = 0;
866             mActiveCountConsecutiveNormal = 0;
867         }
868         return !isQueueEmpty(queue) ? queue.removeFirst() : null;
869     }
870 
queueForNextBroadcast()871     @Nullable ArrayDeque<SomeArgs> queueForNextBroadcast() {
872         final ArrayDeque<SomeArgs> nextNormal = queueForNextBroadcast(
873                 mPending, mPendingOffload,
874                 mActiveCountConsecutiveNormal, constants.MAX_CONSECUTIVE_NORMAL_DISPATCHES);
875         final ArrayDeque<SomeArgs> nextBroadcastQueue = queueForNextBroadcast(
876                 mPendingUrgent, nextNormal,
877                 mActiveCountConsecutiveUrgent, constants.MAX_CONSECUTIVE_URGENT_DISPATCHES);
878         return nextBroadcastQueue;
879     }
880 
queueForNextBroadcast( @ullable ArrayDeque<SomeArgs> highPriorityQueue, @Nullable ArrayDeque<SomeArgs> lowPriorityQueue, int consecutiveHighPriorityCount, int maxHighPriorityDispatchLimit)881     private @Nullable ArrayDeque<SomeArgs> queueForNextBroadcast(
882             @Nullable ArrayDeque<SomeArgs> highPriorityQueue,
883             @Nullable ArrayDeque<SomeArgs> lowPriorityQueue,
884             int consecutiveHighPriorityCount,
885             int maxHighPriorityDispatchLimit) {
886         // nothing high priority pending, no further decisionmaking
887         if (isQueueEmpty(highPriorityQueue)) {
888             return lowPriorityQueue;
889         }
890         // nothing but high priority pending, also no further decisionmaking
891         if (isQueueEmpty(lowPriorityQueue)) {
892             return highPriorityQueue;
893         }
894 
895         // Starvation mitigation: although we prioritize high priority queues by default,
896         // we allow low priority queues to make steady progress even if broadcasts in
897         // high priority queue are arriving faster than they can be dispatched.
898         //
899         // We do not try to defer to the next broadcast in low priority queues if that broadcast
900         // is ordered and still blocked on delivery to other recipients.
901         final SomeArgs nextLPArgs = lowPriorityQueue.peekFirst();
902         final BroadcastRecord nextLPRecord = (BroadcastRecord) nextLPArgs.arg1;
903         final int nextLPRecordIndex = nextLPArgs.argi1;
904         final BroadcastRecord nextHPRecord = (BroadcastRecord) highPriorityQueue.peekFirst().arg1;
905         final boolean shouldConsiderLPQueue = (mCountPrioritizeEarliestRequests > 0
906                 || consecutiveHighPriorityCount >= maxHighPriorityDispatchLimit);
907         final boolean isLPQueueEligible = shouldConsiderLPQueue
908                 && nextLPRecord.enqueueTime <= nextHPRecord.enqueueTime
909                 && !nextLPRecord.isBlocked(nextLPRecordIndex);
910         return isLPQueueEligible ? lowPriorityQueue : highPriorityQueue;
911     }
912 
isQueueEmpty(@ullable ArrayDeque<SomeArgs> queue)913     private static boolean isQueueEmpty(@Nullable ArrayDeque<SomeArgs> queue) {
914         return (queue == null || queue.isEmpty());
915     }
916 
917     /**
918      * Add a request to prioritize dispatching of broadcasts that have been enqueued the earliest,
919      * even if there are urgent broadcasts waiting to be dispatched. This is typically used in
920      * case there are callers waiting for "barrier" to be reached.
921      *
922      * @return if this operation may have changed internal state, indicating
923      *         that the caller is responsible for invoking
924      *         {@link BroadcastQueueModernImpl#updateRunnableList}
925      */
926     @CheckResult
927     @VisibleForTesting
addPrioritizeEarliestRequest()928     boolean addPrioritizeEarliestRequest() {
929         if (mCountPrioritizeEarliestRequests == 0) {
930             mCountPrioritizeEarliestRequests++;
931             invalidateRunnableAt();
932             return true;
933         } else {
934             mCountPrioritizeEarliestRequests++;
935             return false;
936         }
937     }
938 
939     /**
940      * Remove a request to prioritize dispatching of broadcasts that have been enqueued the
941      * earliest, even if there are urgent broadcasts waiting to be dispatched. This is typically
942      * used in case there are callers waiting for "barrier" to be reached.
943      *
944      * <p> Once there are no more remaining requests, the dispatching order reverts back to normal.
945      *
946      * @return if this operation may have changed internal state, indicating
947      *         that the caller is responsible for invoking
948      *         {@link BroadcastQueueModernImpl#updateRunnableList}
949      */
950     @CheckResult
removePrioritizeEarliestRequest()951     boolean removePrioritizeEarliestRequest() {
952         mCountPrioritizeEarliestRequests--;
953         if (mCountPrioritizeEarliestRequests == 0) {
954             invalidateRunnableAt();
955             return true;
956         } else if (mCountPrioritizeEarliestRequests < 0) {
957             mCountPrioritizeEarliestRequests = 0;
958             return false;
959         } else {
960             return false;
961         }
962     }
963 
964     /**
965      * Returns null if there are no pending broadcasts
966      */
peekNextBroadcast()967     @Nullable SomeArgs peekNextBroadcast() {
968         ArrayDeque<SomeArgs> queue = queueForNextBroadcast();
969         return !isQueueEmpty(queue) ? queue.peekFirst() : null;
970     }
971 
972     @VisibleForTesting
peekNextBroadcastRecord()973     @Nullable BroadcastRecord peekNextBroadcastRecord() {
974         ArrayDeque<SomeArgs> queue = queueForNextBroadcast();
975         return !isQueueEmpty(queue) ? (BroadcastRecord) queue.peekFirst().arg1 : null;
976     }
977 
978     /**
979      * Quickly determine if this queue has broadcasts waiting to be delivered to
980      * manifest receivers, which indicates we should request an OOM adjust.
981      */
isPendingManifest()982     public boolean isPendingManifest() {
983         return mCountManifest > 0;
984     }
985 
986     /**
987      * Quickly determine if this queue has ordered broadcasts waiting to be delivered,
988      * which indicates we should request an OOM adjust.
989      */
isPendingOrdered()990     public boolean isPendingOrdered() {
991         return mCountOrdered > 0;
992     }
993 
994     /**
995      * Quickly determine if this queue has broadcasts waiting to be delivered for which result is
996      * expected from the senders, which indicates we should request an OOM adjust.
997      */
isPendingResultTo()998     public boolean isPendingResultTo() {
999         return mCountResultTo > 0;
1000     }
1001 
1002     /**
1003      * Report whether this queue is currently handling an urgent broadcast.
1004      */
isPendingUrgent()1005     public boolean isPendingUrgent() {
1006         BroadcastRecord next = peekNextBroadcastRecord();
1007         return (next != null) ? next.isUrgent() : false;
1008     }
1009 
1010     /**
1011      * Quickly determine if this queue has broadcasts that are still waiting to
1012      * be delivered at some point in the future.
1013      */
isIdle()1014     public boolean isIdle() {
1015         return (!isActive() && isEmpty()) || isDeferredUntilActive();
1016     }
1017 
1018     /**
1019      * Quickly determine if this queue has non-deferred broadcasts enqueued before the given
1020      * barrier timestamp that are still waiting to be delivered.
1021      */
isBeyondBarrierLocked(@ptimeMillisLong long barrierTime)1022     public boolean isBeyondBarrierLocked(@UptimeMillisLong long barrierTime) {
1023         final SomeArgs next = mPending.peekFirst();
1024         final SomeArgs nextUrgent = mPendingUrgent.peekFirst();
1025         final SomeArgs nextOffload = mPendingOffload.peekFirst();
1026 
1027         // Empty records are always past any barrier
1028         final boolean activeBeyond = (mActive == null)
1029                 || mActive.enqueueTime > barrierTime;
1030         final boolean nextBeyond = (next == null)
1031                 || ((BroadcastRecord) next.arg1).enqueueTime > barrierTime;
1032         final boolean nextUrgentBeyond = (nextUrgent == null)
1033                 || ((BroadcastRecord) nextUrgent.arg1).enqueueTime > barrierTime;
1034         final boolean nextOffloadBeyond = (nextOffload == null)
1035                 || ((BroadcastRecord) nextOffload.arg1).enqueueTime > barrierTime;
1036 
1037         return (activeBeyond && nextBeyond && nextUrgentBeyond && nextOffloadBeyond)
1038                 || isDeferredUntilActive();
1039     }
1040 
1041     /**
1042      * Quickly determine if this queue has non-deferred broadcasts waiting to be dispatched,
1043      * that match {@code intent}, as defined by {@link Intent#filterEquals(Intent)}.
1044      */
isDispatched(@onNull Intent intent)1045     public boolean isDispatched(@NonNull Intent intent) {
1046         final boolean activeDispatched = (mActive == null)
1047                 || (!intent.filterEquals(mActive.intent));
1048         final boolean dispatched = isDispatchedInQueue(mPending, intent);
1049         final boolean urgentDispatched = isDispatchedInQueue(mPendingUrgent, intent);
1050         final boolean offloadDispatched = isDispatchedInQueue(mPendingOffload, intent);
1051 
1052         return (activeDispatched && dispatched && urgentDispatched && offloadDispatched)
1053                 || isDeferredUntilActive();
1054     }
1055 
1056     /**
1057      * Quickly determine if the {@code queue} has non-deferred broadcasts waiting to be dispatched,
1058      * that match {@code intent}, as defined by {@link Intent#filterEquals(Intent)}.
1059      */
isDispatchedInQueue(@onNull ArrayDeque<SomeArgs> queue, @NonNull Intent intent)1060     private boolean isDispatchedInQueue(@NonNull ArrayDeque<SomeArgs> queue,
1061             @NonNull Intent intent) {
1062         final Iterator<SomeArgs> it = queue.iterator();
1063         while (it.hasNext()) {
1064             final SomeArgs args = it.next();
1065             if (args == null) {
1066                 return true;
1067             }
1068             final BroadcastRecord record = (BroadcastRecord) args.arg1;
1069             if (intent.filterEquals(record.intent)) {
1070                 return false;
1071             }
1072         }
1073         return true;
1074     }
1075 
isRunnable()1076     public boolean isRunnable() {
1077         if (mRunnableAtInvalidated) updateRunnableAt();
1078         return mRunnableAt != Long.MAX_VALUE;
1079     }
1080 
isDeferredUntilActive()1081     public boolean isDeferredUntilActive() {
1082         if (mRunnableAtInvalidated) updateRunnableAt();
1083         return mRunnableAtReason == BroadcastProcessQueue.REASON_CACHED_INFINITE_DEFER;
1084     }
1085 
hasDeferredBroadcasts()1086     public boolean hasDeferredBroadcasts() {
1087         return (mCountDeferred > 0);
1088     }
1089 
1090     /**
1091      * Return time at which this process is considered runnable. This is
1092      * typically the time at which the next pending broadcast was first
1093      * enqueued, but it also reflects any pauses or delays that should be
1094      * applied to the process.
1095      * <p>
1096      * Returns {@link Long#MAX_VALUE} when this queue isn't currently runnable,
1097      * typically when the queue is empty or when paused.
1098      */
getRunnableAt()1099     public @UptimeMillisLong long getRunnableAt() {
1100         if (mRunnableAtInvalidated) updateRunnableAt();
1101         return mRunnableAt;
1102     }
1103 
1104     /**
1105      * Return the "reason" behind the current {@link #getRunnableAt()} value,
1106      * such as indicating why the queue is being delayed or paused.
1107      */
getRunnableAtReason()1108     public @Reason int getRunnableAtReason() {
1109         if (mRunnableAtInvalidated) updateRunnableAt();
1110         return mRunnableAtReason;
1111     }
1112 
invalidateRunnableAt()1113     public void invalidateRunnableAt() {
1114         mRunnableAtInvalidated = true;
1115     }
1116 
1117     static final int REASON_EMPTY = 0;
1118     static final int REASON_CACHED = 1;
1119     static final int REASON_NORMAL = 2;
1120     static final int REASON_MAX_PENDING = 3;
1121     static final int REASON_BLOCKED = 4;
1122     static final int REASON_INSTRUMENTED = 5;
1123     static final int REASON_PERSISTENT = 6;
1124     static final int REASON_FORCE_DELAYED = 7;
1125     static final int REASON_CACHED_INFINITE_DEFER = 8;
1126     static final int REASON_CONTAINS_FOREGROUND = 10;
1127     static final int REASON_CONTAINS_ORDERED = 11;
1128     static final int REASON_CONTAINS_ALARM = 12;
1129     static final int REASON_CONTAINS_PRIORITIZED = 13;
1130     static final int REASON_CONTAINS_INTERACTIVE = 14;
1131     static final int REASON_CONTAINS_RESULT_TO = 15;
1132     static final int REASON_CONTAINS_INSTRUMENTED = 16;
1133     static final int REASON_CONTAINS_MANIFEST = 17;
1134     static final int REASON_FOREGROUND = 18;
1135     static final int REASON_CORE_UID = 19;
1136     static final int REASON_TOP_PROCESS = 20;
1137 
1138     @IntDef(flag = false, prefix = { "REASON_" }, value = {
1139             REASON_EMPTY,
1140             REASON_CACHED,
1141             REASON_NORMAL,
1142             REASON_MAX_PENDING,
1143             REASON_BLOCKED,
1144             REASON_INSTRUMENTED,
1145             REASON_PERSISTENT,
1146             REASON_FORCE_DELAYED,
1147             REASON_CACHED_INFINITE_DEFER,
1148             REASON_CONTAINS_FOREGROUND,
1149             REASON_CONTAINS_ORDERED,
1150             REASON_CONTAINS_ALARM,
1151             REASON_CONTAINS_PRIORITIZED,
1152             REASON_CONTAINS_INTERACTIVE,
1153             REASON_CONTAINS_RESULT_TO,
1154             REASON_CONTAINS_INSTRUMENTED,
1155             REASON_CONTAINS_MANIFEST,
1156             REASON_FOREGROUND,
1157             REASON_CORE_UID,
1158             REASON_TOP_PROCESS,
1159     })
1160     @Retention(RetentionPolicy.SOURCE)
1161     public @interface Reason {}
1162 
reasonToString(@eason int reason)1163     static @NonNull String reasonToString(@Reason int reason) {
1164         switch (reason) {
1165             case REASON_EMPTY: return "EMPTY";
1166             case REASON_CACHED: return "CACHED";
1167             case REASON_NORMAL: return "NORMAL";
1168             case REASON_MAX_PENDING: return "MAX_PENDING";
1169             case REASON_BLOCKED: return "BLOCKED";
1170             case REASON_INSTRUMENTED: return "INSTRUMENTED";
1171             case REASON_PERSISTENT: return "PERSISTENT";
1172             case REASON_FORCE_DELAYED: return "FORCE_DELAYED";
1173             case REASON_CACHED_INFINITE_DEFER: return "INFINITE_DEFER";
1174             case REASON_CONTAINS_FOREGROUND: return "CONTAINS_FOREGROUND";
1175             case REASON_CONTAINS_ORDERED: return "CONTAINS_ORDERED";
1176             case REASON_CONTAINS_ALARM: return "CONTAINS_ALARM";
1177             case REASON_CONTAINS_PRIORITIZED: return "CONTAINS_PRIORITIZED";
1178             case REASON_CONTAINS_INTERACTIVE: return "CONTAINS_INTERACTIVE";
1179             case REASON_CONTAINS_RESULT_TO: return "CONTAINS_RESULT_TO";
1180             case REASON_CONTAINS_INSTRUMENTED: return "CONTAINS_INSTRUMENTED";
1181             case REASON_CONTAINS_MANIFEST: return "CONTAINS_MANIFEST";
1182             case REASON_FOREGROUND: return "FOREGROUND";
1183             case REASON_CORE_UID: return "CORE_UID";
1184             case REASON_TOP_PROCESS: return "TOP_PROCESS";
1185             default: return Integer.toString(reason);
1186         }
1187     }
1188 
1189     /**
1190      * Update {@link #getRunnableAt()}, when needed.
1191      */
updateRunnableAt()1192     void updateRunnableAt() {
1193         if (!mRunnableAtInvalidated) return;
1194         mRunnableAtInvalidated = false;
1195 
1196         final SomeArgs next = peekNextBroadcast();
1197         if (next != null) {
1198             final BroadcastRecord r = (BroadcastRecord) next.arg1;
1199             final int index = next.argi1;
1200             final long runnableAt = r.enqueueTime;
1201 
1202             if (r.isBlocked(index)) {
1203                 mRunnableAt = Long.MAX_VALUE;
1204                 mRunnableAtReason = REASON_BLOCKED;
1205                 return;
1206             }
1207 
1208             if (mForcedDelayedDurationMs > 0) {
1209                 mRunnableAt = runnableAt + mForcedDelayedDurationMs;
1210                 mRunnableAtReason = REASON_FORCE_DELAYED;
1211             } else if (mCountForeground > mCountForegroundDeferred) {
1212                 mRunnableAt = runnableAt + constants.DELAY_URGENT_MILLIS;
1213                 mRunnableAtReason = REASON_CONTAINS_FOREGROUND;
1214             } else if (mCountInteractive > 0) {
1215                 mRunnableAt = runnableAt + constants.DELAY_URGENT_MILLIS;
1216                 mRunnableAtReason = REASON_CONTAINS_INTERACTIVE;
1217             } else if (mCountInstrumented > 0) {
1218                 mRunnableAt = runnableAt + constants.DELAY_URGENT_MILLIS;
1219                 mRunnableAtReason = REASON_CONTAINS_INSTRUMENTED;
1220             } else if (mProcessInstrumented) {
1221                 mRunnableAt = runnableAt + constants.DELAY_URGENT_MILLIS;
1222                 mRunnableAtReason = REASON_INSTRUMENTED;
1223             } else if (mUidForeground) {
1224                 mRunnableAt = runnableAt + constants.DELAY_FOREGROUND_PROC_MILLIS;
1225                 mRunnableAtReason = REASON_FOREGROUND;
1226             } else if (app != null && app.getSetProcState() == ActivityManager.PROCESS_STATE_TOP) {
1227                 // TODO (b/287676625): Use a callback to check when a process goes in and out of
1228                 // the TOP state.
1229                 mRunnableAt = runnableAt + constants.DELAY_FOREGROUND_PROC_MILLIS;
1230                 mRunnableAtReason = REASON_TOP_PROCESS;
1231             } else if (mProcessPersistent) {
1232                 mRunnableAt = runnableAt + constants.DELAY_PERSISTENT_PROC_MILLIS;
1233                 mRunnableAtReason = REASON_PERSISTENT;
1234             } else if (mCountOrdered > 0) {
1235                 mRunnableAt = runnableAt;
1236                 mRunnableAtReason = REASON_CONTAINS_ORDERED;
1237             } else if (mCountAlarm > 0) {
1238                 mRunnableAt = runnableAt;
1239                 mRunnableAtReason = REASON_CONTAINS_ALARM;
1240             } else if (mCountPrioritized > mCountPrioritizedDeferred) {
1241                 mRunnableAt = runnableAt;
1242                 mRunnableAtReason = REASON_CONTAINS_PRIORITIZED;
1243             } else if (mCountManifest > 0) {
1244                 mRunnableAt = runnableAt;
1245                 mRunnableAtReason = REASON_CONTAINS_MANIFEST;
1246             } else if (mProcessFreezable) {
1247                 if (r.deferUntilActive) {
1248                     // All enqueued broadcasts are deferrable, defer
1249                     if (mCountDeferred == mCountEnqueued) {
1250                         mRunnableAt = Long.MAX_VALUE;
1251                         mRunnableAtReason = REASON_CACHED_INFINITE_DEFER;
1252                     } else {
1253                         // At least one enqueued broadcast isn't deferrable, repick time and reason
1254                         // for this record. If a later record is not deferrable and is one of these
1255                         // special cases, one of the cases above would have already caught that.
1256                         if (r.isForeground()) {
1257                             mRunnableAt = runnableAt + constants.DELAY_URGENT_MILLIS;
1258                             mRunnableAtReason = REASON_CONTAINS_FOREGROUND;
1259                         } else if (r.prioritized) {
1260                             mRunnableAt = runnableAt;
1261                             mRunnableAtReason = REASON_CONTAINS_PRIORITIZED;
1262                         } else if (r.resultTo != null) {
1263                             mRunnableAt = runnableAt;
1264                             mRunnableAtReason = REASON_CONTAINS_RESULT_TO;
1265                         } else {
1266                             mRunnableAt = runnableAt + constants.DELAY_CACHED_MILLIS;
1267                             mRunnableAtReason = REASON_CACHED;
1268                         }
1269                     }
1270                 } else {
1271                     // This record isn't deferrable
1272                     mRunnableAt = runnableAt + constants.DELAY_CACHED_MILLIS;
1273                     mRunnableAtReason = REASON_CACHED;
1274                 }
1275             } else if (mCountResultTo > 0) {
1276                 // All resultTo broadcasts are infinitely deferrable, so if the app
1277                 // is already cached, they'll be deferred on the line above
1278                 mRunnableAt = runnableAt;
1279                 mRunnableAtReason = REASON_CONTAINS_RESULT_TO;
1280             } else if (UserHandle.isCore(uid)) {
1281                 mRunnableAt = runnableAt;
1282                 mRunnableAtReason = REASON_CORE_UID;
1283             } else {
1284                 mRunnableAt = runnableAt + constants.DELAY_NORMAL_MILLIS;
1285                 mRunnableAtReason = REASON_NORMAL;
1286             }
1287 
1288             // If we have too many broadcasts pending, bypass any delays that
1289             // might have been applied above to aid draining
1290             if (mPending.size() + mPendingUrgent.size()
1291                     + mPendingOffload.size() >= constants.MAX_PENDING_BROADCASTS) {
1292                 mRunnableAt = Math.min(mRunnableAt, runnableAt);
1293                 mRunnableAtReason = REASON_MAX_PENDING;
1294             }
1295 
1296             if (VERBOSE) {
1297                 Trace.instantForTrack(Trace.TRACE_TAG_ACTIVITY_MANAGER, "BroadcastQueue",
1298                         ((app != null) ? app.processName : "(null)")
1299                         + ":" + r.intent.toString() + ":"
1300                         + r.deferUntilActive
1301                         + ":" + mRunnableAt + " " + reasonToString(mRunnableAtReason)
1302                         + ":" + ((app != null) ? app.isCached() : "false"));
1303             }
1304         } else {
1305             mRunnableAt = Long.MAX_VALUE;
1306             mRunnableAtReason = REASON_EMPTY;
1307         }
1308     }
1309 
1310     /**
1311      * Update {@link BroadcastRecord#DELIVERY_DEFERRED} states of all our
1312      * pending broadcasts, when needed.
1313      */
updateDeferredStates(@onNull BroadcastConsumer applyConsumer, @NonNull BroadcastConsumer clearConsumer)1314     void updateDeferredStates(@NonNull BroadcastConsumer applyConsumer,
1315             @NonNull BroadcastConsumer clearConsumer) {
1316         // When all we have pending is deferred broadcasts, and we're cached,
1317         // then we want everything to be marked deferred
1318         final boolean wantDeferredStates = shouldBeDeferred();
1319 
1320         if (mLastDeferredStates != wantDeferredStates) {
1321             mLastDeferredStates = wantDeferredStates;
1322             if (wantDeferredStates) {
1323                 forEachMatchingBroadcast((r, i) -> {
1324                     return (r.getDeliveryState(i) == BroadcastRecord.DELIVERY_PENDING);
1325                 }, applyConsumer, false);
1326             } else {
1327                 forEachMatchingBroadcast((r, i) -> {
1328                     return (r.getDeliveryState(i) == BroadcastRecord.DELIVERY_DEFERRED);
1329                 }, clearConsumer, false);
1330             }
1331         }
1332     }
1333 
clearDeferredStates(@onNull BroadcastConsumer clearConsumer)1334     void clearDeferredStates(@NonNull BroadcastConsumer clearConsumer) {
1335         if (mLastDeferredStates) {
1336             mLastDeferredStates = false;
1337             forEachMatchingBroadcast((r, i) -> {
1338                 return (r.getDeliveryState(i) == BroadcastRecord.DELIVERY_DEFERRED);
1339             }, clearConsumer, false);
1340         }
1341     }
1342 
1343     @VisibleForTesting
shouldBeDeferred()1344     boolean shouldBeDeferred() {
1345         if (mRunnableAtInvalidated) updateRunnableAt();
1346         return mRunnableAtReason == REASON_CACHED
1347                 || mRunnableAtReason == REASON_CACHED_INFINITE_DEFER;
1348     }
1349 
1350     /**
1351      * Check overall health, confirming things are in a reasonable state and
1352      * that we're not wedged.
1353      */
assertHealthLocked()1354     public void assertHealthLocked() {
1355         // If we're not actively running, we should be sorted into the runnable
1356         // list, and if we're invalidated then someone likely forgot to invoke
1357         // updateRunnableList() to re-sort us into place
1358         if (!isActive()) {
1359             checkState(!mRunnableAtInvalidated, "mRunnableAtInvalidated");
1360         }
1361 
1362         assertHealthLocked(mPending);
1363         assertHealthLocked(mPendingUrgent);
1364         assertHealthLocked(mPendingOffload);
1365     }
1366 
assertHealthLocked(@onNull ArrayDeque<SomeArgs> queue)1367     private void assertHealthLocked(@NonNull ArrayDeque<SomeArgs> queue) {
1368         if (queue.isEmpty()) return;
1369 
1370         final Iterator<SomeArgs> it = queue.descendingIterator();
1371         while (it.hasNext()) {
1372             final SomeArgs args = it.next();
1373             final BroadcastRecord record = (BroadcastRecord) args.arg1;
1374             final int recordIndex = args.argi1;
1375 
1376             if (BroadcastRecord.isDeliveryStateTerminal(record.getDeliveryState(recordIndex))
1377                     || record.isDeferUntilActive()) {
1378                 continue;
1379             } else {
1380                 // If waiting more than 10 minutes, we're likely wedged
1381                 final long waitingTime = SystemClock.uptimeMillis() - record.enqueueTime;
1382                 checkState(waitingTime < (10 * DateUtils.MINUTE_IN_MILLIS), "waitingTime");
1383             }
1384         }
1385     }
1386 
1387     /**
1388      * Insert the given queue into a sorted linked list of "runnable" queues.
1389      *
1390      * @param head the current linked list head
1391      * @param item the queue to insert
1392      * @return a potentially updated linked list head
1393      */
1394     @VisibleForTesting
1395     static @Nullable BroadcastProcessQueue insertIntoRunnableList(
1396             @Nullable BroadcastProcessQueue head, @NonNull BroadcastProcessQueue item) {
1397         if (head == null) {
1398             return item;
1399         }
1400         final long itemRunnableAt = item.getRunnableAt();
1401         BroadcastProcessQueue test = head;
1402         BroadcastProcessQueue tail = null;
1403         while (test != null) {
1404             if (test.getRunnableAt() > itemRunnableAt) {
1405                 item.runnableAtNext = test;
1406                 item.runnableAtPrev = test.runnableAtPrev;
1407                 if (item.runnableAtNext != null) {
1408                     item.runnableAtNext.runnableAtPrev = item;
1409                 }
1410                 if (item.runnableAtPrev != null) {
1411                     item.runnableAtPrev.runnableAtNext = item;
1412                 }
1413                 return (test == head) ? item : head;
1414             }
1415             tail = test;
1416             test = test.runnableAtNext;
1417         }
1418         item.runnableAtPrev = tail;
1419         item.runnableAtPrev.runnableAtNext = item;
1420         return head;
1421     }
1422 
1423     /**
1424      * Remove the given queue from a sorted linked list of "runnable" queues.
1425      *
1426      * @param head the current linked list head
1427      * @param item the queue to remove
1428      * @return a potentially updated linked list head
1429      */
1430     @VisibleForTesting
removeFromRunnableList( @ullable BroadcastProcessQueue head, @NonNull BroadcastProcessQueue item)1431     static @Nullable BroadcastProcessQueue removeFromRunnableList(
1432             @Nullable BroadcastProcessQueue head, @NonNull BroadcastProcessQueue item) {
1433         if (head == item) {
1434             head = item.runnableAtNext;
1435         }
1436         if (item.runnableAtNext != null) {
1437             item.runnableAtNext.runnableAtPrev = item.runnableAtPrev;
1438         }
1439         if (item.runnableAtPrev != null) {
1440             item.runnableAtPrev.runnableAtNext = item.runnableAtNext;
1441         }
1442         item.runnableAtNext = null;
1443         item.runnableAtPrev = null;
1444         return head;
1445     }
1446 
1447     /**
1448      * Set the timeout flag to indicate that an ANR timer has been started.  A value of true means a
1449      * timer is running; a value of false means there is no timer running.
1450      */
setTimeoutScheduled(boolean timeoutScheduled)1451     void setTimeoutScheduled(boolean timeoutScheduled) {
1452         mTimeoutScheduled = timeoutScheduled;
1453     }
1454 
1455     /**
1456      * Get the timeout flag
1457      */
timeoutScheduled()1458     boolean timeoutScheduled() {
1459         return mTimeoutScheduled;
1460     }
1461 
1462     @Override
toString()1463     public String toString() {
1464         if (mCachedToString == null) {
1465             mCachedToString = "BroadcastProcessQueue{" + toShortString() + "}";
1466         }
1467         return mCachedToString;
1468     }
1469 
toShortString()1470     public String toShortString() {
1471         if (mCachedToShortString == null) {
1472             mCachedToShortString = Integer.toHexString(System.identityHashCode(this))
1473                     + " " + ((app != null) ? app.getPid() : "?") + ":" + processName + "/"
1474                     + UserHandle.formatUid(uid);
1475         }
1476         return mCachedToShortString;
1477     }
1478 
describeStateLocked()1479     public String describeStateLocked() {
1480         return describeStateLocked(SystemClock.uptimeMillis());
1481     }
1482 
describeStateLocked(@ptimeMillisLong long now)1483     public String describeStateLocked(@UptimeMillisLong long now) {
1484         final StringBuilder sb = new StringBuilder();
1485         if (isRunnable()) {
1486             sb.append("runnable at ");
1487             TimeUtils.formatDuration(getRunnableAt(), now, sb);
1488         } else {
1489             sb.append("not runnable");
1490         }
1491         sb.append(" because ");
1492         sb.append(reasonToString(mRunnableAtReason));
1493         return sb.toString();
1494     }
1495 
1496     @NeverCompile
dumpLocked(@ptimeMillisLong long now, @NonNull IndentingPrintWriter pw)1497     public void dumpLocked(@UptimeMillisLong long now, @NonNull IndentingPrintWriter pw) {
1498         if ((mActive == null) && isEmpty() && isOutgoingEmpty()) return;
1499 
1500         pw.print(toShortString());
1501         pw.print(" ");
1502         pw.print(describeStateLocked(now));
1503         pw.println();
1504 
1505         pw.increaseIndent();
1506         dumpProcessState(pw);
1507         dumpBroadcastCounts(pw);
1508 
1509         if (!mOutgoingBroadcasts.isEmpty()) {
1510             for (int i = 0; i < mOutgoingBroadcasts.size(); ++i) {
1511                 dumpOutgoingRecord(now, pw, mOutgoingBroadcasts.get(i));
1512             }
1513         }
1514 
1515         if (mActive != null) {
1516             dumpRecord("ACTIVE", now, pw, mActive, mActiveIndex);
1517         }
1518         for (SomeArgs args : mPendingUrgent) {
1519             final BroadcastRecord r = (BroadcastRecord) args.arg1;
1520             dumpRecord("URGENT", now, pw, r, args.argi1);
1521         }
1522         for (SomeArgs args : mPending) {
1523             final BroadcastRecord r = (BroadcastRecord) args.arg1;
1524             dumpRecord(null, now, pw, r, args.argi1);
1525         }
1526         for (SomeArgs args : mPendingOffload) {
1527             final BroadcastRecord r = (BroadcastRecord) args.arg1;
1528             dumpRecord("OFFLOAD", now, pw, r, args.argi1);
1529         }
1530         pw.decreaseIndent();
1531         pw.println();
1532     }
1533 
1534     @NeverCompile
dumpProcessState(@onNull IndentingPrintWriter pw)1535     private void dumpProcessState(@NonNull IndentingPrintWriter pw) {
1536         final StringBuilder sb = new StringBuilder();
1537         if (mUidForeground) {
1538             sb.append("FG");
1539         }
1540         if (mProcessFreezable) {
1541             if (sb.length() > 0) sb.append("|");
1542             sb.append("FRZ");
1543         }
1544         if (mProcessInstrumented) {
1545             if (sb.length() > 0) sb.append("|");
1546             sb.append("INSTR");
1547         }
1548         if (mProcessPersistent) {
1549             if (sb.length() > 0) sb.append("|");
1550             sb.append("PER");
1551         }
1552         if (sb.length() > 0) {
1553             pw.print("state:"); pw.println(sb);
1554         }
1555         if (runningOomAdjusted) {
1556             pw.print("runningOomAdjusted:"); pw.println(runningOomAdjusted);
1557         }
1558         if (mActiveReEnqueued) {
1559             pw.print("activeReEnqueued:"); pw.println(mActiveReEnqueued);
1560         }
1561     }
1562 
1563     @NeverCompile
dumpBroadcastCounts(@onNull IndentingPrintWriter pw)1564     private void dumpBroadcastCounts(@NonNull IndentingPrintWriter pw) {
1565         pw.print("e:"); pw.print(mCountEnqueued);
1566         pw.print(" d:"); pw.print(mCountDeferred);
1567         pw.print(" f:"); pw.print(mCountForeground);
1568         pw.print(" fd:"); pw.print(mCountForegroundDeferred);
1569         pw.print(" o:"); pw.print(mCountOrdered);
1570         pw.print(" a:"); pw.print(mCountAlarm);
1571         pw.print(" p:"); pw.print(mCountPrioritized);
1572         pw.print(" pd:"); pw.print(mCountPrioritizedDeferred);
1573         pw.print(" int:"); pw.print(mCountInteractive);
1574         pw.print(" rt:"); pw.print(mCountResultTo);
1575         pw.print(" ins:"); pw.print(mCountInstrumented);
1576         pw.print(" m:"); pw.print(mCountManifest);
1577 
1578         pw.print(" csi:"); pw.print(mActiveCountSinceIdle);
1579         pw.print(" adcsi:"); pw.print(mActiveAssumedDeliveryCountSinceIdle);
1580         pw.print(" ccu:"); pw.print(mActiveCountConsecutiveUrgent);
1581         pw.print(" ccn:"); pw.print(mActiveCountConsecutiveNormal);
1582         pw.println();
1583     }
1584 
1585     @NeverCompile
dumpOutgoingRecord(@ptimeMillisLong long now, @NonNull IndentingPrintWriter pw, @NonNull BroadcastRecord record)1586     private void dumpOutgoingRecord(@UptimeMillisLong long now,
1587             @NonNull IndentingPrintWriter pw, @NonNull BroadcastRecord record) {
1588         pw.print("OUTGOING ");
1589         TimeUtils.formatDuration(record.enqueueTime, now, pw);
1590         pw.print(' ');
1591         pw.println(record.toShortString());
1592     }
1593 
1594     @NeverCompile
dumpRecord(@ullable String flavor, @UptimeMillisLong long now, @NonNull IndentingPrintWriter pw, @NonNull BroadcastRecord record, int recordIndex)1595     private void dumpRecord(@Nullable String flavor, @UptimeMillisLong long now,
1596             @NonNull IndentingPrintWriter pw, @NonNull BroadcastRecord record, int recordIndex) {
1597         TimeUtils.formatDuration(record.enqueueTime, now, pw);
1598         pw.print(' ');
1599         pw.println(record.toShortString());
1600         pw.print("    ");
1601         final int deliveryState = record.delivery[recordIndex];
1602         pw.print(deliveryStateToString(deliveryState));
1603         if (deliveryState == BroadcastRecord.DELIVERY_SCHEDULED) {
1604             pw.print(" at ");
1605             TimeUtils.formatDuration(record.scheduledTime[recordIndex], now, pw);
1606         }
1607         if (flavor != null) {
1608             pw.print(' ');
1609             pw.print(flavor);
1610         }
1611         final Object receiver = record.receivers.get(recordIndex);
1612         if (receiver instanceof BroadcastFilter) {
1613             final BroadcastFilter filter = (BroadcastFilter) receiver;
1614             pw.print(" for registered ");
1615             pw.print(Integer.toHexString(System.identityHashCode(filter)));
1616         } else /* if (receiver instanceof ResolveInfo) */ {
1617             final ResolveInfo info = (ResolveInfo) receiver;
1618             pw.print(" for manifest ");
1619             pw.print(info.activityInfo.name);
1620         }
1621         pw.println();
1622         final int blockedUntilBeyondCount = record.blockedUntilBeyondCount[recordIndex];
1623         if (blockedUntilBeyondCount != -1) {
1624             pw.print("    blocked until ");
1625             pw.print(blockedUntilBeyondCount);
1626             pw.print(", currently at ");
1627             pw.print(record.beyondCount);
1628             pw.print(" of ");
1629             pw.println(record.receivers.size());
1630         }
1631     }
1632 }
1633