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