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