• 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 android.app.ActivityManagerInternal.OOM_ADJ_REASON_START_RECEIVER;
20 import static android.os.Process.ZYGOTE_POLICY_FLAG_EMPTY;
21 import static android.os.Process.ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE;
22 
23 import static com.android.internal.util.FrameworkStatsLog.BOOT_COMPLETED_BROADCAST_COMPLETION_LATENCY_REPORTED;
24 import static com.android.internal.util.FrameworkStatsLog.BOOT_COMPLETED_BROADCAST_COMPLETION_LATENCY_REPORTED__EVENT__BOOT_COMPLETED;
25 import static com.android.internal.util.FrameworkStatsLog.BOOT_COMPLETED_BROADCAST_COMPLETION_LATENCY_REPORTED__EVENT__LOCKED_BOOT_COMPLETED;
26 import static com.android.internal.util.FrameworkStatsLog.BROADCAST_DELIVERY_EVENT_REPORTED;
27 import static com.android.internal.util.FrameworkStatsLog.BROADCAST_DELIVERY_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_COLD;
28 import static com.android.internal.util.FrameworkStatsLog.BROADCAST_DELIVERY_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_UNKNOWN;
29 import static com.android.internal.util.FrameworkStatsLog.BROADCAST_DELIVERY_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_WARM;
30 import static com.android.internal.util.FrameworkStatsLog.BROADCAST_DELIVERY_EVENT_REPORTED__RECEIVER_TYPE__MANIFEST;
31 import static com.android.internal.util.FrameworkStatsLog.BROADCAST_DELIVERY_EVENT_REPORTED__RECEIVER_TYPE__RUNTIME;
32 import static com.android.internal.util.FrameworkStatsLog.SERVICE_REQUEST_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_NORMAL;
33 import static com.android.internal.util.FrameworkStatsLog.SERVICE_REQUEST_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_STOPPED;
34 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
35 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
36 import static com.android.server.am.ActivityManagerDebugConfig.LOG_WRITER_INFO;
37 import static com.android.server.am.BroadcastProcessQueue.insertIntoRunnableList;
38 import static com.android.server.am.BroadcastProcessQueue.reasonToString;
39 import static com.android.server.am.BroadcastProcessQueue.removeFromRunnableList;
40 import static com.android.server.am.BroadcastRecord.DELIVERY_DEFERRED;
41 import static com.android.server.am.BroadcastRecord.deliveryStateToString;
42 import static com.android.server.am.BroadcastRecord.getReceiverClassName;
43 import static com.android.server.am.BroadcastRecord.getReceiverPackageName;
44 import static com.android.server.am.BroadcastRecord.getReceiverProcessName;
45 import static com.android.server.am.BroadcastRecord.getReceiverUid;
46 import static com.android.server.am.BroadcastRecord.isDeliveryStateTerminal;
47 
48 import android.annotation.CheckResult;
49 import android.annotation.NonNull;
50 import android.annotation.Nullable;
51 import android.annotation.UptimeMillisLong;
52 import android.app.Activity;
53 import android.app.ActivityManager;
54 import android.app.ApplicationExitInfo;
55 import android.app.BroadcastOptions;
56 import android.app.IApplicationThread;
57 import android.app.UidObserver;
58 import android.app.usage.UsageEvents.Event;
59 import android.content.ComponentName;
60 import android.content.ContentResolver;
61 import android.content.Intent;
62 import android.content.pm.ActivityInfo;
63 import android.content.pm.ApplicationInfo;
64 import android.content.pm.PackageManager;
65 import android.content.pm.ResolveInfo;
66 import android.content.pm.UserInfo;
67 import android.os.Bundle;
68 import android.os.BundleMerger;
69 import android.os.Handler;
70 import android.os.Message;
71 import android.os.PowerExemptionManager;
72 import android.os.Process;
73 import android.os.RemoteException;
74 import android.os.SystemClock;
75 import android.os.UserHandle;
76 import android.text.format.DateUtils;
77 import android.util.ArrayMap;
78 import android.util.ArraySet;
79 import android.util.IndentingPrintWriter;
80 import android.util.MathUtils;
81 import android.util.Pair;
82 import android.util.Slog;
83 import android.util.SparseArray;
84 import android.util.SparseBooleanArray;
85 import android.util.TimeUtils;
86 import android.util.proto.ProtoOutputStream;
87 
88 import com.android.internal.annotations.GuardedBy;
89 import com.android.internal.annotations.VisibleForTesting;
90 import com.android.internal.os.SomeArgs;
91 import com.android.internal.os.TimeoutRecord;
92 import com.android.internal.util.FrameworkStatsLog;
93 import com.android.server.LocalServices;
94 import com.android.server.am.BroadcastProcessQueue.BroadcastConsumer;
95 import com.android.server.am.BroadcastProcessQueue.BroadcastPredicate;
96 import com.android.server.am.BroadcastProcessQueue.BroadcastRecordConsumer;
97 import com.android.server.am.BroadcastRecord.DeliveryState;
98 import com.android.server.pm.UserJourneyLogger;
99 import com.android.server.pm.UserManagerInternal;
100 import com.android.server.utils.AnrTimer;
101 
102 import dalvik.annotation.optimization.NeverCompile;
103 
104 import java.io.FileDescriptor;
105 import java.io.PrintWriter;
106 import java.text.SimpleDateFormat;
107 import java.util.ArrayList;
108 import java.util.Objects;
109 import java.util.Set;
110 import java.util.concurrent.CountDownLatch;
111 import java.util.concurrent.atomic.AtomicReference;
112 import java.util.function.BooleanSupplier;
113 import java.util.function.Consumer;
114 import java.util.function.Predicate;
115 
116 /**
117  * Alternative {@link BroadcastQueue} implementation which pivots broadcasts to
118  * be dispatched on a per-process basis.
119  * <p>
120  * Each process now has its own broadcast queue represented by a
121  * {@link BroadcastProcessQueue} instance. Each queue has a concept of being
122  * "runnable at" a particular time in the future, which supports arbitrarily
123  * pausing or delaying delivery on a per-process basis.
124  * <p>
125  * To keep things easy to reason about, there is a <em>very strong</em>
126  * preference to have broadcast interactions flow through a consistent set of
127  * methods in this specific order:
128  * <ol>
129  * <li>{@link #updateRunnableList} promotes a per-process queue to be runnable
130  * when it has relevant pending broadcasts
131  * <li>{@link #updateRunningList} promotes a runnable queue to be running and
132  * schedules delivery of the first broadcast
133  * <li>{@link #scheduleReceiverColdLocked} requests any needed cold-starts, and
134  * results are reported back via {@link #onApplicationAttachedLocked}
135  * <li>{@link #scheduleReceiverWarmLocked} requests dispatch of the currently
136  * active broadcast to a running app, and results are reported back via
137  * {@link #finishReceiverLocked}
138  * </ol>
139  */
140 class BroadcastQueueImpl extends BroadcastQueue {
BroadcastQueueImpl(ActivityManagerService service, Handler handler, BroadcastConstants fgConstants, BroadcastConstants bgConstants)141     BroadcastQueueImpl(ActivityManagerService service, Handler handler,
142             BroadcastConstants fgConstants, BroadcastConstants bgConstants) {
143         this(service, handler, fgConstants, bgConstants, new BroadcastSkipPolicy(service),
144                 new BroadcastHistory(fgConstants));
145     }
146 
BroadcastQueueImpl(ActivityManagerService service, Handler handler, BroadcastConstants fgConstants, BroadcastConstants bgConstants, BroadcastSkipPolicy skipPolicy, BroadcastHistory history)147     BroadcastQueueImpl(ActivityManagerService service, Handler handler,
148             BroadcastConstants fgConstants, BroadcastConstants bgConstants,
149             BroadcastSkipPolicy skipPolicy, BroadcastHistory history) {
150         super(service, handler, skipPolicy, history);
151 
152         // For the moment, read agnostic constants from foreground
153         mConstants = Objects.requireNonNull(fgConstants);
154         mFgConstants = Objects.requireNonNull(fgConstants);
155         mBgConstants = Objects.requireNonNull(bgConstants);
156 
157         mLocalHandler = new Handler(handler.getLooper(), mLocalCallback);
158 
159         // We configure runnable size only once at boot; it'd be too complex to
160         // try resizing dynamically at runtime
161         mRunning = new BroadcastProcessQueue[mConstants.getMaxRunningQueues()];
162 
163         mAnrTimer = new BroadcastAnrTimer(mLocalHandler);
164     }
165 
166     /**
167      * Map from UID to per-process broadcast queues. If a UID hosts more than
168      * one process, each additional process is stored as a linked list using
169      * {@link BroadcastProcessQueue#processNameNext}.
170      *
171      * @see #getProcessQueue
172      * @see #getOrCreateProcessQueue
173      */
174     @GuardedBy("mService")
175     private final SparseArray<BroadcastProcessQueue> mProcessQueues = new SparseArray<>();
176 
177     /**
178      * Head of linked list containing queues which are "runnable". They're
179      * sorted by {@link BroadcastProcessQueue#getRunnableAt()} so that we prefer
180      * dispatching of longer-waiting broadcasts first.
181      *
182      * @see BroadcastProcessQueue#insertIntoRunnableList
183      * @see BroadcastProcessQueue#removeFromRunnableList
184      */
185     private BroadcastProcessQueue mRunnableHead = null;
186 
187     /**
188      * Array of queues which are currently "running", which may have gaps that
189      * are {@code null}.
190      *
191      * @see #getRunningSize
192      * @see #getRunningIndexOf
193      */
194     @GuardedBy("mService")
195     private final BroadcastProcessQueue[] mRunning;
196 
197     /**
198      * Single queue which is "running" but is awaiting a cold start to be
199      * completed via {@link #onApplicationAttachedLocked}. To optimize for
200      * system health we only request one cold start at a time.
201      */
202     @GuardedBy("mService")
203     private @Nullable BroadcastProcessQueue mRunningColdStart;
204 
205     /**
206      * Indicates whether we have queued a message to check pending cold start validity.
207      */
208     @GuardedBy("mService")
209     private boolean mCheckPendingColdStartQueued;
210 
211     /**
212      * Collection of latches waiting for device to reach specific state. The
213      * first argument is a function to test for the desired state, and the
214      * second argument is the latch to release once that state is reached.
215      * <p>
216      * This is commonly used for callers that are blocked waiting for an
217      * {@link #isIdleLocked} or {@link #isBeyondBarrierLocked} to be reached,
218      * without requiring that they periodically poll for the state change.
219      * <p>
220      * Finally, the presence of any waiting latches will cause all
221      * future-runnable processes to be runnable immediately, to aid in reaching
222      * the desired state as quickly as possible.
223      */
224     @GuardedBy("mService")
225     private final ArrayList<Pair<BooleanSupplier, CountDownLatch>> mWaitingFor = new ArrayList<>();
226 
227     /**
228      * Container for holding the set of broadcasts that have been replaced by a newer broadcast
229      * sent with {@link Intent#FLAG_RECEIVER_REPLACE_PENDING}.
230      */
231     @GuardedBy("mService")
232     private final AtomicReference<ArraySet<BroadcastRecord>> mReplacedBroadcastsCache =
233             new AtomicReference<>();
234 
235     /**
236      * Container for holding the set of broadcast records that satisfied a certain criteria.
237      */
238     @GuardedBy("mService")
239     private final AtomicReference<ArrayMap<BroadcastRecord, Boolean>> mRecordsLookupCache =
240             new AtomicReference<>();
241 
242     /**
243      * Container for holding the set of broadcast records that matches an enqueueing record.
244      * @see BroadcastRecord#isMatchingRecord(BroadcastRecord)
245      */
246     @GuardedBy("mService")
247     private final AtomicReference<ArrayMap<BroadcastRecord, Boolean>> mMatchingRecordsCache =
248             new AtomicReference<>();
249 
250     /**
251      * Map from UID to its last known "foreground" state. A UID is considered to be in
252      * "foreground" state when it's procState is {@link ActivityManager#PROCESS_STATE_TOP}.
253      * <p>
254      * We manually maintain this data structure since the lifecycle of
255      * {@link ProcessRecord} and {@link BroadcastProcessQueue} can be
256      * mismatched.
257      */
258     @GuardedBy("mService")
259     private final SparseBooleanArray mUidForeground = new SparseBooleanArray();
260 
261     private final BroadcastConstants mConstants;
262     private final BroadcastConstants mFgConstants;
263     private final BroadcastConstants mBgConstants;
264 
265     /**
266      * Timestamp when last {@link #testAllProcessQueues} failure was observed;
267      * used for throttling log messages.
268      */
269     private @UptimeMillisLong long mLastTestFailureTime;
270 
271     /**
272      * The ANR timer service for broadcasts.
273      */
274     @GuardedBy("mService")
275     private final BroadcastAnrTimer mAnrTimer;
276 
277     private static final int MSG_UPDATE_RUNNING_LIST = 1;
278     private static final int MSG_DELIVERY_TIMEOUT = 2;
279     private static final int MSG_BG_ACTIVITY_START_TIMEOUT = 3;
280     private static final int MSG_CHECK_HEALTH = 4;
281     private static final int MSG_CHECK_PENDING_COLD_START_VALIDITY = 5;
282     private static final int MSG_PROCESS_FREEZABLE_CHANGED = 6;
283     private static final int MSG_UID_STATE_CHANGED = 7;
284 
285     // Required when Flags.anrTimerServiceEnabled is false.  This constant should be deleted if and
286     // when the flag is fused on.
287     private static final int MSG_DELIVERY_TIMEOUT_SOFT = 8;
288 
enqueueUpdateRunningList()289     private void enqueueUpdateRunningList() {
290         mLocalHandler.removeMessages(MSG_UPDATE_RUNNING_LIST);
291         mLocalHandler.sendEmptyMessage(MSG_UPDATE_RUNNING_LIST);
292     }
293 
294     private final Handler mLocalHandler;
295 
296     private final Handler.Callback mLocalCallback = (msg) -> {
297         switch (msg.what) {
298             case MSG_UPDATE_RUNNING_LIST: {
299                 updateRunningList();
300                 return true;
301             }
302             // Required when Flags.anrTimerServiceEnabled is false.  This case should be deleted if
303             // and when the flag is fused on.
304             case MSG_DELIVERY_TIMEOUT_SOFT: {
305                 synchronized (mService) {
306                     deliveryTimeoutSoftLocked((BroadcastProcessQueue) msg.obj, msg.arg1);
307                     return true;
308                 }
309             }
310             case MSG_DELIVERY_TIMEOUT: {
311                 deliveryTimeout((BroadcastProcessQueue) msg.obj);
312                 return true;
313             }
314             case MSG_BG_ACTIVITY_START_TIMEOUT: {
315                 synchronized (mService) {
316                     final SomeArgs args = (SomeArgs) msg.obj;
317                     final ProcessRecord app = (ProcessRecord) args.arg1;
318                     final BroadcastRecord r = (BroadcastRecord) args.arg2;
319                     args.recycle();
320                     app.removeBackgroundStartPrivileges(r);
321                 }
322                 return true;
323             }
324             case MSG_CHECK_HEALTH: {
325                 checkHealth();
326                 return true;
327             }
328             case MSG_CHECK_PENDING_COLD_START_VALIDITY: {
329                 synchronized (mService) {
330                     /* Clear this as we have just received the broadcast. */
331                     mCheckPendingColdStartQueued = false;
332                     checkPendingColdStartValidityLocked();
333                 }
334                 return true;
335             }
336             case MSG_PROCESS_FREEZABLE_CHANGED: {
337                 handleProcessFreezableChanged((ProcessRecord) msg.obj);
338                 return true;
339             }
340             case MSG_UID_STATE_CHANGED: {
341                 final int uid = (int) msg.obj;
342                 final int procState = msg.arg1;
343                 synchronized (mService) {
344                     if (procState == ActivityManager.PROCESS_STATE_TOP) {
345                         mUidForeground.put(uid, true);
346                     } else {
347                         mUidForeground.delete(uid);
348                     }
349                     refreshProcessQueuesLocked(uid);
350                 }
351                 return true;
352             }
353         }
354         return false;
355     };
356 
357     /**
358      * Return the total number of active queues contained inside
359      * {@link #mRunning}.
360      */
361     @GuardedBy("mService")
getRunningSize()362     private int getRunningSize() {
363         int size = 0;
364         for (int i = 0; i < mRunning.length; i++) {
365             if (mRunning[i] != null) size++;
366         }
367         return size;
368     }
369 
370     /**
371      * Return the number of active queues that are delivering "urgent" broadcasts
372      */
373     @GuardedBy("mService")
getRunningUrgentCount()374     private int getRunningUrgentCount() {
375         int count = 0;
376         for (int i = 0; i < mRunning.length; i++) {
377             if (mRunning[i] != null && mRunning[i].getActive().isUrgent()) {
378                 count++;
379             }
380         }
381         return count;
382     }
383 
384     /**
385      * Return the first index of the given value contained inside
386      * {@link #mRunning}, otherwise {@code -1}.
387      */
388     @GuardedBy("mService")
getRunningIndexOf(@ullable BroadcastProcessQueue test)389     private int getRunningIndexOf(@Nullable BroadcastProcessQueue test) {
390         for (int i = 0; i < mRunning.length; i++) {
391             if (mRunning[i] == test) return i;
392         }
393         return -1;
394     }
395 
396     /**
397      * Consider updating the list of "runnable" queues, specifically with
398      * relation to the given queue.
399      * <p>
400      * Typically called when {@link BroadcastProcessQueue#getRunnableAt()} might
401      * have changed, since that influences the order in which we'll promote a
402      * "runnable" queue to be "running."
403      */
404     @GuardedBy("mService")
updateRunnableList(@onNull BroadcastProcessQueue queue)405     private void updateRunnableList(@NonNull BroadcastProcessQueue queue) {
406         if (getRunningIndexOf(queue) >= 0) {
407             // Already running; they'll be reinserted into the runnable list
408             // once they finish running, so no need to update them now
409             return;
410         }
411 
412         // To place ourselves correctly in the runnable list, we may need to
413         // update internals that may have been invalidated; we wait until now at
414         // the last possible moment to avoid duplicated work
415         queue.updateDeferredStates(mBroadcastConsumerDeferApply, mBroadcastConsumerDeferClear);
416         queue.updateRunnableAt();
417 
418         final boolean wantQueue = queue.isRunnable();
419         final boolean inQueue = (queue == mRunnableHead) || (queue.runnableAtPrev != null)
420                 || (queue.runnableAtNext != null);
421         if (wantQueue) {
422             if (inQueue) {
423                 // We're in a good state, but our position within the linked
424                 // list might need to move based on a runnableAt change
425                 final boolean prevLower = (queue.runnableAtPrev != null)
426                         ? queue.runnableAtPrev.getRunnableAt() <= queue.getRunnableAt() : true;
427                 final boolean nextHigher = (queue.runnableAtNext != null)
428                         ? queue.runnableAtNext.getRunnableAt() >= queue.getRunnableAt() : true;
429                 if (!prevLower || !nextHigher) {
430                     mRunnableHead = removeFromRunnableList(mRunnableHead, queue);
431                     mRunnableHead = insertIntoRunnableList(mRunnableHead, queue);
432                 }
433             } else {
434                 mRunnableHead = insertIntoRunnableList(mRunnableHead, queue);
435             }
436         } else if (inQueue) {
437             mRunnableHead = removeFromRunnableList(mRunnableHead, queue);
438         }
439 
440         // If app isn't running, and there's nothing in the queue, clean up
441         if (queue.isEmpty() && queue.isOutgoingEmpty() && !queue.isActive()
442                 && !queue.isProcessWarm()) {
443             removeProcessQueue(queue.processName, queue.uid);
444         }
445     }
446 
updateRunningList()447     private void updateRunningList() {
448         synchronized (mService) {
449             updateRunningListLocked();
450         }
451     }
452 
453     /**
454      * Consider updating the list of "running" queues.
455      * <p>
456      * This method can promote "runnable" queues to become "running", subject to
457      * a maximum of {@link BroadcastConstants#MAX_RUNNING_PROCESS_QUEUES} warm
458      * processes and only one pending cold-start.
459      */
460     @GuardedBy("mService")
updateRunningListLocked()461     private void updateRunningListLocked() {
462         // Allocated size here implicitly includes the extra reservation for urgent
463         // dispatches beyond the MAX_RUNNING_QUEUES soft limit for normal
464         // parallelism.  If we're already dispatching some urgent broadcasts,
465         // count that against the extra first - its role is to permit progress of
466         // urgent broadcast traffic when the normal reservation is fully occupied
467         // with less-urgent dispatches, not to generally expand parallelism.
468         final int usedExtra = Math.min(getRunningUrgentCount(),
469                 mConstants.EXTRA_RUNNING_URGENT_PROCESS_QUEUES);
470         int avail = mRunning.length - getRunningSize() - usedExtra;
471         if (avail == 0) return;
472 
473         final int cookie = traceBegin("updateRunningList");
474         final long now = SystemClock.uptimeMillis();
475 
476         // If someone is waiting for a state, everything is runnable now
477         final boolean waitingFor = !mWaitingFor.isEmpty();
478 
479         // We're doing an update now, so remove any future update requests;
480         // we'll repost below if needed
481         mLocalHandler.removeMessages(MSG_UPDATE_RUNNING_LIST);
482 
483         boolean updateOomAdj = false;
484         BroadcastProcessQueue queue = mRunnableHead;
485         while (queue != null && avail > 0) {
486             BroadcastProcessQueue nextQueue = queue.runnableAtNext;
487             final long runnableAt = queue.getRunnableAt();
488 
489             // When broadcasts are skipped or failed during list traversal, we
490             // might encounter a queue that is no longer runnable; skip it
491             if (!queue.isRunnable()) {
492                 queue = nextQueue;
493                 continue;
494             }
495 
496             // If we've hit the soft limit for non-urgent dispatch parallelism,
497             // only consider delivering from queues whose ready broadcast is urgent
498             if (getRunningSize() >= mConstants.MAX_RUNNING_PROCESS_QUEUES) {
499                 if (!queue.isPendingUrgent()) {
500                     queue = nextQueue;
501                     continue;
502                 }
503             }
504 
505             // If queues beyond this point aren't ready to run yet, schedule
506             // another pass when they'll be runnable
507             if (runnableAt > now && !waitingFor) {
508                 mLocalHandler.sendEmptyMessageAtTime(MSG_UPDATE_RUNNING_LIST, runnableAt);
509                 break;
510             }
511 
512             // Clear the deferred state of broadcasts in this queue as we are just about to
513             // deliver broadcasts to this process.
514             queue.clearDeferredStates(mBroadcastConsumerDeferClear);
515 
516             // We might not have heard about a newly running process yet, so
517             // consider refreshing if we think we're cold
518             updateWarmProcess(queue);
519 
520             final boolean processWarm = queue.isProcessWarm();
521             if (processWarm) {
522                 mService.mOomAdjuster.unfreezeTemporarily(queue.app,
523                         CachedAppOptimizer.UNFREEZE_REASON_START_RECEIVER);
524                 // The process could be killed as part of unfreezing. So, check again if it
525                 // is still warm.
526                 if (!queue.isProcessWarm()) {
527                     queue = nextQueue;
528                     enqueueUpdateRunningList();
529                     continue;
530                 }
531             } else {
532                 // We only offer to run one cold-start at a time to preserve
533                 // system resources; below we either claim that single slot or
534                 // skip to look for another warm process
535                 if (mRunningColdStart == null) {
536                     mRunningColdStart = queue;
537                     mRunningColdStart.clearProcessStartInitiatedTimestampMillis();
538                 } else if (isPendingColdStartValid()) {
539                     // Move to considering next runnable queue
540                     queue = nextQueue;
541                     continue;
542                 } else {
543                     // Pending cold start is not valid, so clear it and move on.
544                     clearInvalidPendingColdStart();
545                     mRunningColdStart = queue;
546                     mRunningColdStart.clearProcessStartInitiatedTimestampMillis();
547                 }
548             }
549 
550             if (DEBUG_BROADCAST) {
551                 logv("Promoting " + queue + " from runnable to running; process is " + queue.app);
552             }
553             promoteToRunningLocked(queue);
554             boolean completed;
555             if (processWarm) {
556                 updateOomAdj |= queue.runningOomAdjusted;
557                 try {
558                     completed = scheduleReceiverWarmLocked(queue);
559                 } catch (BroadcastRetryException e) {
560                     finishOrReEnqueueActiveBroadcast(queue);
561                     completed = true;
562                 }
563             } else {
564                 completed = scheduleReceiverColdLocked(queue);
565             }
566             // If we are done with delivering the broadcasts to the process, we can demote it
567             // from the "running" list.
568             if (completed) {
569                 demoteFromRunningLocked(queue);
570             }
571             // TODO: If delivering broadcasts to a process is finished, we don't have to hold
572             // a slot for it.
573             avail--;
574 
575             // Move to considering next runnable queue
576             queue = nextQueue;
577         }
578 
579         // TODO: We need to update oomAdj early as this currently doesn't guarantee that the
580         // procState is updated correctly when the app is handling a broadcast.
581         if (updateOomAdj) {
582             mService.updateOomAdjPendingTargetsLocked(OOM_ADJ_REASON_START_RECEIVER);
583         }
584 
585         checkPendingColdStartValidityLocked();
586         checkAndRemoveWaitingFor();
587 
588         traceEnd(cookie);
589     }
590 
591     @GuardedBy("mService")
isPendingColdStartValid()592     private boolean isPendingColdStartValid() {
593         if (mRunningColdStart.hasProcessStartInitiationTimedout()) {
594             return false;
595         } else if (mRunningColdStart.app.getPid() > 0) {
596             // If the process has already started, check if it wasn't killed.
597             return !mRunningColdStart.app.isKilled();
598         } else {
599             // Otherwise, check if the process start is still pending.
600             return mRunningColdStart.app.isPendingStart();
601         }
602     }
603 
604     @GuardedBy("mService")
clearInvalidPendingColdStart()605     private void clearInvalidPendingColdStart() {
606         logw("Clearing invalid pending cold start: " + mRunningColdStart);
607         if (mRunningColdStart.wasActiveBroadcastReEnqueued()) {
608             finishReceiverActiveLocked(mRunningColdStart, BroadcastRecord.DELIVERY_FAILURE,
609                     "invalid start with re-enqueued broadcast");
610         } else {
611             mRunningColdStart.reEnqueueActiveBroadcast();
612         }
613         final BroadcastProcessQueue queue = mRunningColdStart;
614         clearRunningColdStart();
615         demoteFromRunningLocked(queue);
616         enqueueUpdateRunningList();
617     }
618 
619     @GuardedBy("mService")
checkPendingColdStartValidityLocked()620     private void checkPendingColdStartValidityLocked() {
621         // There are a few cases where a starting process gets killed but AMS doesn't report
622         // this event. So, once we start waiting for a pending cold start, periodically check
623         // if the pending start is still valid and if not, clear it so that the queue doesn't
624         // keep waiting for the process start forever.
625         // If there is no pending cold start, then nothing to do.
626         if (mRunningColdStart == null) {
627             return;
628         }
629         if (isPendingColdStartValid()) {
630             if (!mCheckPendingColdStartQueued) {
631                 mLocalHandler.sendEmptyMessageDelayed(MSG_CHECK_PENDING_COLD_START_VALIDITY,
632                         mConstants.PENDING_COLD_START_CHECK_INTERVAL_MILLIS);
633                 mCheckPendingColdStartQueued = true;
634             }
635         } else {
636             clearInvalidPendingColdStart();
637         }
638     }
639 
640     @GuardedBy("mService")
finishOrReEnqueueActiveBroadcast(@onNull BroadcastProcessQueue queue)641     private void finishOrReEnqueueActiveBroadcast(@NonNull BroadcastProcessQueue queue) {
642         checkState(queue.isActive(), "isActive");
643 
644         if (queue.wasActiveBroadcastReEnqueued()) {
645             // If the broadcast was already re-enqueued previously, finish it to avoid repeated
646             // delivery attempts
647             finishReceiverActiveLocked(queue, BroadcastRecord.DELIVERY_FAILURE,
648                     "re-enqueued broadcast delivery failed");
649         } else {
650             final BroadcastRecord record = queue.getActive();
651             final int index = queue.getActiveIndex();
652             setDeliveryState(queue, queue.app, record, index, record.receivers.get(index),
653                     BroadcastRecord.DELIVERY_PENDING, "reEnqueueActiveBroadcast");
654             queue.reEnqueueActiveBroadcast();
655         }
656     }
657 
658     @GuardedBy("mService")
659     @Override
onApplicationAttachedLocked(@onNull ProcessRecord app)660     public boolean onApplicationAttachedLocked(@NonNull ProcessRecord app)
661             throws BroadcastRetryException {
662         if (DEBUG_BROADCAST) {
663             logv("Process " + app + " is attached");
664         }
665         // Process records can be recycled, so always start by looking up the
666         // relevant per-process queue
667         final BroadcastProcessQueue queue = getProcessQueue(app);
668         if (queue != null) {
669             setQueueProcess(queue, app);
670             // Outgoing broadcasts should be cleared when the process dies but there have been
671             // issues due to AMS not always informing the BroadcastQueue of process deaths.
672             // So, clear them when a new process starts as well.
673             queue.clearOutgoingBroadcasts();
674         }
675 
676         boolean didSomething = false;
677         if ((mRunningColdStart != null) && (mRunningColdStart == queue)) {
678             // We've been waiting for this app to cold start, and it's ready
679             // now; dispatch its next broadcast and clear the slot
680             mRunningColdStart.clearProcessStartInitiatedTimestampMillis();
681             mRunningColdStart = null;
682 
683             // Now that we're running warm, we can finally request that OOM
684             // adjust we've been waiting for
685             notifyStartedRunning(queue);
686             mService.updateOomAdjPendingTargetsLocked(OOM_ADJ_REASON_START_RECEIVER);
687 
688             queue.traceProcessEnd();
689             queue.traceProcessRunningBegin();
690             try {
691                 if (scheduleReceiverWarmLocked(queue)) {
692                     demoteFromRunningLocked(queue);
693                 }
694             } catch (BroadcastRetryException e) {
695                 finishOrReEnqueueActiveBroadcast(queue);
696                 demoteFromRunningLocked(queue);
697                 throw e;
698             }
699 
700             // We might be willing to kick off another cold start
701             enqueueUpdateRunningList();
702             didSomething = true;
703         }
704         return didSomething;
705     }
706 
707     @GuardedBy("mService")
708     @Override
onApplicationTimeoutLocked(@onNull ProcessRecord app)709     public void onApplicationTimeoutLocked(@NonNull ProcessRecord app) {
710         onApplicationCleanupLocked(app);
711     }
712 
713     @GuardedBy("mService")
714     @Override
onApplicationProblemLocked(@onNull ProcessRecord app)715     public void onApplicationProblemLocked(@NonNull ProcessRecord app) {
716         onApplicationCleanupLocked(app);
717     }
718 
719     @GuardedBy("mService")
720     @Override
onApplicationCleanupLocked(@onNull ProcessRecord app)721     public void onApplicationCleanupLocked(@NonNull ProcessRecord app) {
722         if (DEBUG_BROADCAST) {
723             logv("Process " + app + " is cleaned up");
724         }
725 
726         // This cleanup callback could be for an old process and not for the one we are waiting
727         // on, so explicitly check if this for the same ProcessRecord that a queue has.
728         final BroadcastProcessQueue queue = getProcessQueue(app);
729         if ((mRunningColdStart != null) && (mRunningColdStart == queue)
730                 && mRunningColdStart.app == app) {
731             clearRunningColdStart();
732         }
733 
734         if (queue != null && queue.app == app) {
735             setQueueProcess(queue, null);
736 
737             // If queue was running a broadcast, fail it
738             if (queue.isActive()) {
739                 finishReceiverActiveLocked(queue, BroadcastRecord.DELIVERY_FAILURE,
740                         "onApplicationCleanupLocked");
741                 demoteFromRunningLocked(queue);
742             }
743 
744             queue.clearOutgoingBroadcasts();
745 
746             // Skip any pending registered receivers, since the old process
747             // would never be around to receive them
748             boolean didSomething = queue.forEachMatchingBroadcast((r, i) -> {
749                 return (r.receivers.get(i) instanceof BroadcastFilter);
750             }, mBroadcastConsumerSkip, true);
751             if (didSomething || queue.isEmpty()) {
752                 updateRunnableList(queue);
753                 enqueueUpdateRunningList();
754             }
755         }
756     }
757 
758     @GuardedBy("mService")
clearRunningColdStart()759     private void clearRunningColdStart() {
760         mRunningColdStart.traceProcessEnd();
761 
762         // We've been waiting for this app to cold start, and it had
763         // trouble; clear the slot and fail delivery below
764         mRunningColdStart.clearProcessStartInitiatedTimestampMillis();
765         mRunningColdStart = null;
766 
767         // We might be willing to kick off another cold start
768         enqueueUpdateRunningList();
769     }
770 
771     @GuardedBy("mService")
772     @Override
onProcessFreezableChangedLocked(@onNull ProcessRecord app)773     public void onProcessFreezableChangedLocked(@NonNull ProcessRecord app) {
774         mLocalHandler.removeMessages(MSG_PROCESS_FREEZABLE_CHANGED, app);
775         mLocalHandler.obtainMessage(MSG_PROCESS_FREEZABLE_CHANGED, app).sendToTarget();
776     }
777 
778     @GuardedBy("mService")
779     @Override
getPreferredSchedulingGroupLocked(@onNull ProcessRecord app)780     public int getPreferredSchedulingGroupLocked(@NonNull ProcessRecord app) {
781         final BroadcastProcessQueue queue = getProcessQueue(app);
782         if ((queue != null) && getRunningIndexOf(queue) >= 0) {
783             return queue.getPreferredSchedulingGroupLocked();
784         }
785         return ProcessList.SCHED_GROUP_UNDEFINED;
786     }
787 
788     @GuardedBy("mService")
789     @Override
enqueueBroadcastLocked(@onNull BroadcastRecord r)790     public void enqueueBroadcastLocked(@NonNull BroadcastRecord r) {
791         // TODO: Apply delivery group policies and FLAG_REPLACE_PENDING to collapse the
792         // outgoing broadcasts.
793         // TODO: Add traces/logs for the enqueueing outgoing broadcasts logic.
794         if (Flags.deferOutgoingBroadcasts() && isProcessFreezable(r.callerApp)) {
795             final BroadcastProcessQueue queue = getOrCreateProcessQueue(
796                     r.callerApp.processName, r.callerApp.uid);
797             if (queue.getOutgoingBroadcastCount() >= mConstants.MAX_FROZEN_OUTGOING_BROADCASTS) {
798                 r.callerApp.killLocked("Too many outgoing broadcasts in cached state",
799                         ApplicationExitInfo.REASON_OTHER,
800                         ApplicationExitInfo.SUBREASON_EXCESSIVE_OUTGOING_BROADCASTS_WHILE_CACHED,
801                         true /* noisy */);
802                 return;
803             }
804             queue.enqueueOutgoingBroadcast(r);
805             mHistory.onBroadcastFrozenLocked(r);
806             mService.mOomAdjuster.mCachedAppOptimizer.freezeAppAsyncImmediateLSP(r.callerApp);
807             return;
808         }
809         if (DEBUG_BROADCAST || r.debugLog()) {
810             logv("Enqueuing " + r + " for " + r.receivers.size() + " receivers");
811         }
812 
813         final int cookie = traceBegin("enqueueBroadcast");
814         r.applySingletonPolicy(mService);
815 
816         applyDeliveryGroupPolicy(r);
817 
818         r.enqueueTime = SystemClock.uptimeMillis();
819         r.enqueueRealTime = SystemClock.elapsedRealtime();
820         r.enqueueClockTime = System.currentTimeMillis();
821         mHistory.onBroadcastEnqueuedLocked(r);
822 
823         ArraySet<BroadcastRecord> replacedBroadcasts = mReplacedBroadcastsCache.getAndSet(null);
824         if (replacedBroadcasts == null) {
825             replacedBroadcasts = new ArraySet<>();
826         }
827         ArrayMap<BroadcastRecord, Boolean> matchingBroadcasts =
828                 mMatchingRecordsCache.getAndSet(null);
829         if (matchingBroadcasts == null) {
830             matchingBroadcasts = new ArrayMap<>();
831         }
832         r.setMatchingRecordsCache(matchingBroadcasts);
833         boolean enqueuedBroadcast = false;
834 
835         for (int i = 0; i < r.receivers.size(); i++) {
836             final Object receiver = r.receivers.get(i);
837             final BroadcastProcessQueue queue = getOrCreateProcessQueue(
838                     getReceiverProcessName(receiver), getReceiverUid(receiver));
839 
840             // If this receiver is going to be skipped, skip it now itself and don't even enqueue
841             // it.
842             final String skipReason = Flags.avoidNoteOpAtEnqueue()
843                     ? mSkipPolicy.shouldSkipAtEnqueueMessage(r, receiver)
844                     : mSkipPolicy.shouldSkipMessage(r, receiver);
845             if (skipReason != null) {
846                 setDeliveryState(null, null, r, i, receiver, BroadcastRecord.DELIVERY_SKIPPED,
847                         "skipped by policy at enqueue: " + skipReason);
848                 continue;
849             }
850 
851             enqueuedBroadcast = true;
852             final BroadcastRecord replacedBroadcast = queue.enqueueOrReplaceBroadcast(
853                     r, i, mBroadcastConsumerDeferApply);
854             if (replacedBroadcast != null) {
855                 replacedBroadcasts.add(replacedBroadcast);
856             }
857             updateRunnableList(queue);
858             enqueueUpdateRunningList();
859         }
860 
861         // Skip any broadcasts that have been replaced by newer broadcasts with
862         // FLAG_RECEIVER_REPLACE_PENDING.
863         // TODO: Optimize and reuse mBroadcastConsumerSkipAndCanceled for the case of
864         // cancelling all receivers for a broadcast.
865         skipAndCancelReplacedBroadcasts(replacedBroadcasts);
866         replacedBroadcasts.clear();
867         mReplacedBroadcastsCache.compareAndSet(null, replacedBroadcasts);
868         matchingBroadcasts.clear();
869         r.clearMatchingRecordsCache();
870         mMatchingRecordsCache.compareAndSet(null, matchingBroadcasts);
871 
872         // If nothing to dispatch, send any pending result immediately
873         if (r.receivers.isEmpty() || !enqueuedBroadcast) {
874             scheduleResultTo(r);
875             notifyFinishBroadcast(r);
876         }
877 
878         traceEnd(cookie);
879     }
880 
881     @GuardedBy("mService")
skipAndCancelReplacedBroadcasts(ArraySet<BroadcastRecord> replacedBroadcasts)882     private void skipAndCancelReplacedBroadcasts(ArraySet<BroadcastRecord> replacedBroadcasts) {
883         for (int i = 0; i < replacedBroadcasts.size(); ++i) {
884             final BroadcastRecord r = replacedBroadcasts.valueAt(i);
885             // Skip all the receivers in the replaced broadcast
886             for (int rcvrIdx = 0; rcvrIdx < r.receivers.size(); ++rcvrIdx) {
887                 if (!isDeliveryStateTerminal(r.getDeliveryState(rcvrIdx))) {
888                     mBroadcastConsumerSkipAndCanceled.accept(r, rcvrIdx);
889                 }
890             }
891         }
892     }
893 
894     @GuardedBy("mService")
applyDeliveryGroupPolicy(@onNull BroadcastRecord r)895     private void applyDeliveryGroupPolicy(@NonNull BroadcastRecord r) {
896         if (mService.shouldIgnoreDeliveryGroupPolicy(r.intent.getAction())) {
897             return;
898         }
899         final int policy = r.getDeliveryGroupPolicy();
900         final BroadcastConsumer broadcastConsumer;
901         switch (policy) {
902             case BroadcastOptions.DELIVERY_GROUP_POLICY_ALL:
903                 // Older broadcasts need to be left as is in this case, so nothing more to do.
904                 return;
905             case BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT:
906                 broadcastConsumer = mBroadcastConsumerSkipAndCanceled;
907                 break;
908             case BroadcastOptions.DELIVERY_GROUP_POLICY_MERGED:
909                 // TODO: Allow applying MERGED policy for broadcasts with more than one receiver.
910                 if (r.receivers.size() > 1) {
911                     return;
912                 }
913                 final BundleMerger extrasMerger = r.options.getDeliveryGroupExtrasMerger();
914                 if (extrasMerger == null) {
915                     // Extras merger is required to be able to merge the extras. So, if it's not
916                     // supplied, then ignore the delivery group policy.
917                     return;
918                 }
919                 broadcastConsumer = (record, recordIndex) -> {
920                     r.intent.mergeExtras(record.intent, extrasMerger);
921                     mBroadcastConsumerSkipAndCanceled.accept(record, recordIndex);
922                 };
923                 break;
924             default:
925                 logw("Unknown delivery group policy: " + policy);
926                 return;
927         }
928         final ArrayMap<BroadcastRecord, Boolean> recordsLookupCache = getRecordsLookupCache();
929         forEachMatchingBroadcast(QUEUE_PREDICATE_ANY, (testRecord, testIndex) -> {
930             // If the receiver is already in a terminal state, then ignore it.
931             if (isDeliveryStateTerminal(testRecord.getDeliveryState(testIndex))) {
932                 return false;
933             }
934             // We only allow caller to remove broadcasts they enqueued
935             if ((r.callingUid != testRecord.callingUid)
936                     || (r.userId != testRecord.userId)
937                     || !r.matchesDeliveryGroup(testRecord)) {
938                 return false;
939             }
940 
941             // For ordered broadcast, check if the receivers for the new broadcast is a superset
942             // of those for the previous one as skipping and removing only one of them could result
943             // in an inconsistent state.
944             if (testRecord.ordered) {
945                 return containsAllReceivers(r, testRecord, recordsLookupCache);
946             } else if (testRecord.prioritized || testRecord.resultTo != null) {
947                 return testRecord.getDeliveryState(testIndex) == DELIVERY_DEFERRED
948                         ? r.containsReceiver(testRecord.receivers.get(testIndex))
949                         : containsAllReceivers(r, testRecord, recordsLookupCache);
950             } else {
951                 return r.containsReceiver(testRecord.receivers.get(testIndex));
952             }
953         }, broadcastConsumer, true);
954         recordsLookupCache.clear();
955         mRecordsLookupCache.compareAndSet(null, recordsLookupCache);
956     }
957 
958     @GuardedBy("mService")
959     @NonNull
getRecordsLookupCache()960     private ArrayMap<BroadcastRecord, Boolean> getRecordsLookupCache() {
961         ArrayMap<BroadcastRecord, Boolean> recordsLookupCache =
962                 mRecordsLookupCache.getAndSet(null);
963         if (recordsLookupCache == null) {
964             recordsLookupCache = new ArrayMap<>();
965         }
966         return recordsLookupCache;
967     }
968 
969     @GuardedBy("mService")
containsAllReceivers(@onNull BroadcastRecord record, @NonNull BroadcastRecord testRecord, @NonNull ArrayMap<BroadcastRecord, Boolean> recordsLookupCache)970     private boolean containsAllReceivers(@NonNull BroadcastRecord record,
971             @NonNull BroadcastRecord testRecord,
972             @NonNull ArrayMap<BroadcastRecord, Boolean> recordsLookupCache) {
973         final int idx = recordsLookupCache.indexOfKey(testRecord);
974         if (idx > 0) {
975             return recordsLookupCache.valueAt(idx);
976         }
977         final boolean containsAll = record.containsAllReceivers(testRecord.receivers);
978         recordsLookupCache.put(testRecord, containsAll);
979         return containsAll;
980     }
981 
982     /**
983      * Schedule the currently active broadcast on the given queue when we know
984      * the process is cold. This kicks off a cold start and will eventually call
985      * through to {@link #scheduleReceiverWarmLocked} once it's ready.
986      *
987      * @return {@code true} if the broadcast delivery is finished and the process queue can
988      *         be demoted from the running list. Otherwise {@code false}.
989      */
990     @CheckResult
991     @GuardedBy("mService")
scheduleReceiverColdLocked(@onNull BroadcastProcessQueue queue)992     private boolean scheduleReceiverColdLocked(@NonNull BroadcastProcessQueue queue) {
993         checkState(queue.isActive(), "isActive");
994 
995         // Remember that active broadcast was scheduled via a cold start
996         queue.setActiveViaColdStart(true);
997 
998         final BroadcastRecord r = queue.getActive();
999         final int index = queue.getActiveIndex();
1000         final Object receiver = r.receivers.get(index);
1001 
1002         // Ignore registered receivers from a previous PID
1003         if (receiver instanceof BroadcastFilter) {
1004             mRunningColdStart = null;
1005             finishReceiverActiveLocked(queue, BroadcastRecord.DELIVERY_SKIPPED,
1006                     "BroadcastFilter for cold app");
1007             return true;
1008         }
1009 
1010         final String skipReason = shouldSkipReceiver(queue, r, index);
1011         if (skipReason != null) {
1012             mRunningColdStart = null;
1013             finishReceiverActiveLocked(queue, BroadcastRecord.DELIVERY_SKIPPED, skipReason);
1014             return true;
1015         }
1016 
1017         final ApplicationInfo info = ((ResolveInfo) receiver).activityInfo.applicationInfo;
1018         final ComponentName component = ((ResolveInfo) receiver).activityInfo.getComponentName();
1019 
1020         queue.setActiveWasStopped(info.isStopped());
1021         queue.setActiveFirstLaunch(info.isNotLaunched());
1022 
1023         final int intentFlags = r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND;
1024         final HostingRecord hostingRecord = new HostingRecord(HostingRecord.HOSTING_TYPE_BROADCAST,
1025                 component, r.intent.getAction(), r.getHostingRecordTriggerType());
1026         final boolean isActivityCapable = (r.options != null
1027                 && r.options.getTemporaryAppAllowlistDuration() > 0);
1028         final int zygotePolicyFlags = isActivityCapable ? ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE
1029                 : ZYGOTE_POLICY_FLAG_EMPTY;
1030         final boolean allowWhileBooting = (r.intent.getFlags()
1031                 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0;
1032 
1033         long startTimeNs = SystemClock.uptimeNanos();
1034         if (DEBUG_BROADCAST || r.debugLog()) {
1035             logv("Scheduling " + r + " to cold " + queue);
1036         }
1037         queue.app = mService.startProcessLocked(queue.processName, info, true, intentFlags,
1038                 hostingRecord, zygotePolicyFlags, allowWhileBooting, false);
1039         if (queue.app == null) {
1040             mRunningColdStart = null;
1041             finishReceiverActiveLocked(queue, BroadcastRecord.DELIVERY_FAILURE,
1042                     "startProcessLocked failed");
1043             return true;
1044         }
1045         queue.setProcessStartInitiatedTimestampMillis(SystemClock.uptimeMillis());
1046         // TODO: b/335420031 - cache receiver intent to avoid multiple calls to getReceiverIntent.
1047         mService.mProcessList.getAppStartInfoTracker().handleProcessBroadcastStart(
1048                 startTimeNs, queue.app, r.getReceiverIntent(receiver), r.alarm /* isAlarm */);
1049         return false;
1050     }
1051 
1052     /**
1053      * Schedule the currently active broadcast on the given queue when we know
1054      * the process is warm.
1055      * <p>
1056      * There is a <em>very strong</em> preference to consistently handle all
1057      * results by calling through to {@link #finishReceiverLocked}, both in the
1058      * case where a broadcast is handled by a remote app, and the case where the
1059      * broadcast was finished locally without the remote app being involved.
1060      *
1061      * @return {@code true} if the broadcast delivery is finished and the process queue can
1062      *         be demoted from the running list. Otherwise {@code false}.
1063      */
1064     @CheckResult
1065     @GuardedBy("mService")
scheduleReceiverWarmLocked(@onNull BroadcastProcessQueue queue)1066     private boolean scheduleReceiverWarmLocked(@NonNull BroadcastProcessQueue queue)
1067             throws BroadcastRetryException {
1068         checkState(queue.isActive(), "isActive");
1069 
1070         final int cookie = traceBegin("scheduleReceiverWarmLocked");
1071         while (queue.isActive()) {
1072             final BroadcastRecord r = queue.getActive();
1073             final int index = queue.getActiveIndex();
1074 
1075             if (r.terminalCount == 0) {
1076                 r.dispatchTime = SystemClock.uptimeMillis();
1077                 r.dispatchRealTime = SystemClock.elapsedRealtime();
1078                 r.dispatchClockTime = System.currentTimeMillis();
1079             }
1080 
1081             final String skipReason = shouldSkipReceiver(queue, r, index);
1082             if (skipReason == null) {
1083                 final boolean isBlockingDispatch = dispatchReceivers(queue, r, index);
1084                 if (isBlockingDispatch) {
1085                     traceEnd(cookie);
1086                     return false;
1087                 }
1088             } else {
1089                 finishReceiverActiveLocked(queue, BroadcastRecord.DELIVERY_SKIPPED, skipReason);
1090             }
1091 
1092             if (shouldRetire(queue)) {
1093                 break;
1094             }
1095 
1096             // We're on a roll; move onto the next broadcast for this process
1097             queue.makeActiveNextPending();
1098         }
1099         traceEnd(cookie);
1100         return true;
1101     }
1102 
1103     /**
1104      * Consults {@link BroadcastSkipPolicy} and the receiver process state to decide whether or
1105      * not the broadcast to a receiver can be skipped.
1106      */
1107     @GuardedBy("mService")
shouldSkipReceiver(@onNull BroadcastProcessQueue queue, @NonNull BroadcastRecord r, int index)1108     private String shouldSkipReceiver(@NonNull BroadcastProcessQueue queue,
1109             @NonNull BroadcastRecord r, int index) {
1110         final int oldDeliveryState = getDeliveryState(r, index);
1111         final ProcessRecord app = queue.app;
1112         final Object receiver = r.receivers.get(index);
1113 
1114         // If someone already finished this broadcast, finish immediately
1115         if (isDeliveryStateTerminal(oldDeliveryState)) {
1116             return "already terminal state";
1117         }
1118 
1119         // Consider additional cases where we'd want to finish immediately
1120         if (app != null && app.isInFullBackup()) {
1121             return "isInFullBackup";
1122         }
1123         final String skipReason = mSkipPolicy.shouldSkipMessage(r, receiver);
1124         if (skipReason != null) {
1125             return skipReason;
1126         }
1127         final Intent receiverIntent = r.getReceiverIntent(receiver);
1128         if (receiverIntent == null) {
1129             return "getReceiverIntent";
1130         }
1131 
1132         // Ignore registered receivers from a previous PID
1133         if ((receiver instanceof BroadcastFilter)
1134                 && ((BroadcastFilter) receiver).receiverList.pid != app.getPid()) {
1135             return "BroadcastFilter for mismatched PID";
1136         }
1137         // The receiver was not handled in this method.
1138         return null;
1139     }
1140 
1141     /**
1142      * A receiver is about to be dispatched.  Start ANR timers, if necessary.
1143      *
1144      * @return {@code true} if this a blocking delivery. That is, we are going to block on the
1145      *         finishReceiver() to be called before moving to the next broadcast. Otherwise,
1146      *         {@code false}.
1147      */
1148     @GuardedBy("mService")
1149     @CheckResult
dispatchReceivers(@onNull BroadcastProcessQueue queue, @NonNull BroadcastRecord r, int index)1150     private boolean dispatchReceivers(@NonNull BroadcastProcessQueue queue,
1151             @NonNull BroadcastRecord r, int index) throws BroadcastRetryException {
1152         final ProcessRecord app = queue.app;
1153         final Object receiver = r.receivers.get(index);
1154 
1155         // Skip ANR tracking early during boot, when requested, or when we
1156         // immediately assume delivery success
1157         final boolean assumeDelivered = r.isAssumedDelivered(index);
1158         if (mService.mProcessesReady && !r.timeoutExempt && !assumeDelivered) {
1159             queue.setTimeoutScheduled(true);
1160             final int softTimeoutMillis = (int) (r.isForeground() ? mFgConstants.TIMEOUT
1161                     : mBgConstants.TIMEOUT);
1162             startDeliveryTimeoutLocked(queue, softTimeoutMillis);
1163         } else {
1164             queue.setTimeoutScheduled(false);
1165         }
1166 
1167         if (r.mBackgroundStartPrivileges.allowsAny()) {
1168             app.addOrUpdateBackgroundStartPrivileges(r, r.mBackgroundStartPrivileges);
1169 
1170             final long timeout = r.isForeground() ? mFgConstants.ALLOW_BG_ACTIVITY_START_TIMEOUT
1171                     : mBgConstants.ALLOW_BG_ACTIVITY_START_TIMEOUT;
1172             final SomeArgs args = SomeArgs.obtain();
1173             args.arg1 = app;
1174             args.arg2 = r;
1175             mLocalHandler.sendMessageDelayed(
1176                     Message.obtain(mLocalHandler, MSG_BG_ACTIVITY_START_TIMEOUT, args), timeout);
1177         }
1178         if (r.options != null && r.options.getTemporaryAppAllowlistDuration() > 0) {
1179             if (r.options.getTemporaryAppAllowlistType()
1180                     == PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_APP_FREEZING_DELAYED) {
1181                 // Only delay freezer, don't add to any temp allowlist
1182                 // TODO: Add a unit test
1183                 mService.mOomAdjuster.mCachedAppOptimizer.unfreezeTemporarily(app,
1184                         CachedAppOptimizer.UNFREEZE_REASON_START_RECEIVER,
1185                         r.options.getTemporaryAppAllowlistDuration());
1186             } else {
1187                 mService.tempAllowlistUidLocked(queue.uid,
1188                         r.options.getTemporaryAppAllowlistDuration(),
1189                         r.options.getTemporaryAppAllowlistReasonCode(), r.toShortString(),
1190                         r.options.getTemporaryAppAllowlistType(), r.callingUid);
1191             }
1192         }
1193 
1194         if (DEBUG_BROADCAST || r.debugLog()) {
1195             logv("Scheduling " + r + " to warm " + app);
1196         }
1197         setDeliveryState(queue, app, r, index, receiver, BroadcastRecord.DELIVERY_SCHEDULED,
1198                 "scheduleReceiverWarmLocked");
1199 
1200         final Intent receiverIntent = r.getReceiverIntent(receiver);
1201         final IApplicationThread thread = app.getOnewayThread();
1202         if (thread != null) {
1203             try {
1204                 if (r.shareIdentity) {
1205                     mService.mPackageManagerInt.grantImplicitAccess(r.userId, r.intent,
1206                             UserHandle.getAppId(app.uid), r.callingUid, true);
1207                 }
1208                 queue.lastProcessState = app.mState.getCurProcState();
1209                 if (receiver instanceof BroadcastFilter) {
1210                     notifyScheduleRegisteredReceiver(app, r, (BroadcastFilter) receiver);
1211                     thread.scheduleRegisteredReceiver(
1212                             ((BroadcastFilter) receiver).receiverList.receiver,
1213                             receiverIntent, r.resultCode, r.resultData, r.resultExtras,
1214                             r.ordered, r.initialSticky, assumeDelivered, r.userId,
1215                             app.mState.getReportedProcState(),
1216                             r.shareIdentity ? r.callingUid : Process.INVALID_UID,
1217                             r.shareIdentity ? r.callerPackage : null);
1218                     // TODO: consider making registered receivers of unordered
1219                     // broadcasts report results to detect ANRs
1220                     if (assumeDelivered) {
1221                         finishReceiverActiveLocked(queue, BroadcastRecord.DELIVERY_DELIVERED,
1222                                 "assuming delivered");
1223                         return false;
1224                     }
1225                 } else {
1226                     notifyScheduleReceiver(app, r, (ResolveInfo) receiver);
1227                     thread.scheduleReceiver(receiverIntent, ((ResolveInfo) receiver).activityInfo,
1228                             null, r.resultCode, r.resultData, r.resultExtras, r.ordered,
1229                             assumeDelivered, r.userId,
1230                             app.mState.getReportedProcState(),
1231                             r.shareIdentity ? r.callingUid : Process.INVALID_UID,
1232                             r.shareIdentity ? r.callerPackage : null);
1233                 }
1234                 return true;
1235             } catch (RemoteException e) {
1236                 final String msg = "Failed to schedule " + r + " to " + receiver
1237                         + " via " + app + ": " + e;
1238                 logw(msg);
1239                 app.killLocked("Can't deliver broadcast", ApplicationExitInfo.REASON_OTHER,
1240                         ApplicationExitInfo.SUBREASON_UNDELIVERED_BROADCAST, true);
1241                 // If we were trying to deliver a manifest broadcast, throw the error as we need
1242                 // to try redelivering the broadcast to this receiver.
1243                 if (receiver instanceof ResolveInfo) {
1244                     cancelDeliveryTimeoutLocked(queue);
1245                     throw new BroadcastRetryException(e);
1246                 }
1247                 finishReceiverActiveLocked(queue, BroadcastRecord.DELIVERY_FAILURE,
1248                         "remote app");
1249                 return false;
1250             }
1251         } else {
1252             finishReceiverActiveLocked(queue, BroadcastRecord.DELIVERY_FAILURE,
1253                     "missing IApplicationThread");
1254             return false;
1255         }
1256     }
1257 
1258     /**
1259      * Schedule the final {@link BroadcastRecord#resultTo} delivery for an
1260      * ordered broadcast; assumes the sender is still a warm process.
1261      */
1262     @GuardedBy("mService")
scheduleResultTo(@onNull BroadcastRecord r)1263     private void scheduleResultTo(@NonNull BroadcastRecord r) {
1264         if (r.resultTo == null) return;
1265         final ProcessRecord app = r.resultToApp;
1266         final IApplicationThread thread = (app != null) ? app.getOnewayThread() : null;
1267         if (thread != null) {
1268             mService.mOomAdjuster.unfreezeTemporarily(
1269                     app, CachedAppOptimizer.UNFREEZE_REASON_FINISH_RECEIVER);
1270             if (r.shareIdentity && app.uid != r.callingUid) {
1271                 mService.mPackageManagerInt.grantImplicitAccess(r.userId, r.intent,
1272                         UserHandle.getAppId(app.uid), r.callingUid, true);
1273             }
1274             try {
1275                 final boolean assumeDelivered = true;
1276                 thread.scheduleRegisteredReceiver(
1277                         r.resultTo, r.intent,
1278                         r.resultCode, r.resultData, r.resultExtras, false, r.initialSticky,
1279                         assumeDelivered, r.userId,
1280                         app.mState.getReportedProcState(),
1281                         r.shareIdentity ? r.callingUid : Process.INVALID_UID,
1282                         r.shareIdentity ? r.callerPackage : null);
1283             } catch (RemoteException e) {
1284                 final String msg = "Failed to schedule result of " + r + " via " + app + ": " + e;
1285                 logw(msg);
1286                 app.killLocked("Can't deliver broadcast", ApplicationExitInfo.REASON_OTHER,
1287                         ApplicationExitInfo.SUBREASON_UNDELIVERED_BROADCAST, true);
1288             }
1289         }
1290         // Clear so both local and remote references can be GC'ed
1291         r.resultTo = null;
1292     }
1293 
1294     // Required when Flags.anrTimerServiceEnabled is false.  This function can be replaced with a
1295     // single call to {@code mAnrTimer.start()} if and when the flag is fused on.
1296     @GuardedBy("mService")
startDeliveryTimeoutLocked(@onNull BroadcastProcessQueue queue, int softTimeoutMillis)1297     private void startDeliveryTimeoutLocked(@NonNull BroadcastProcessQueue queue,
1298             int softTimeoutMillis) {
1299         if (mAnrTimer.serviceEnabled()) {
1300             mAnrTimer.start(queue, softTimeoutMillis);
1301         } else {
1302             queue.lastCpuDelayTime = queue.app.getCpuDelayTime();
1303             mLocalHandler.sendMessageDelayed(Message.obtain(mLocalHandler,
1304                     MSG_DELIVERY_TIMEOUT_SOFT, softTimeoutMillis, 0, queue), softTimeoutMillis);
1305         }
1306     }
1307 
1308     // Required when Flags.anrTimerServiceEnabled is false. This function can be replaced with a
1309     // single call to {@code mAnrTimer.cancel()} if and when the flag is fused on.
1310     @GuardedBy("mService")
cancelDeliveryTimeoutLocked(@onNull BroadcastProcessQueue queue)1311     private void cancelDeliveryTimeoutLocked(@NonNull BroadcastProcessQueue queue) {
1312         mAnrTimer.cancel(queue);
1313         if (!mAnrTimer.serviceEnabled()) {
1314             mLocalHandler.removeMessages(MSG_DELIVERY_TIMEOUT_SOFT, queue);
1315         }
1316     }
1317 
1318     // Required when Flags.anrTimerServiceEnabled is false.  This function can be deleted entirely
1319     // if and when the flag is fused on.
1320     @GuardedBy("mService")
deliveryTimeoutSoftLocked(@onNull BroadcastProcessQueue queue, int softTimeoutMillis)1321     private void deliveryTimeoutSoftLocked(@NonNull BroadcastProcessQueue queue,
1322             int softTimeoutMillis) {
1323         if (queue.app != null) {
1324             // Instead of immediately triggering an ANR, extend the timeout by
1325             // the amount of time the process was runnable-but-waiting; we're
1326             // only willing to do this once before triggering an hard ANR
1327             final long cpuDelayTime = queue.app.getCpuDelayTime() - queue.lastCpuDelayTime;
1328             final long hardTimeoutMillis = MathUtils.constrain(cpuDelayTime, 0, softTimeoutMillis);
1329             mAnrTimer.start(queue, hardTimeoutMillis);
1330         } else {
1331             deliveryTimeoutLocked(queue);
1332         }
1333     }
1334 
deliveryTimeout(@onNull BroadcastProcessQueue queue)1335     private void deliveryTimeout(@NonNull BroadcastProcessQueue queue) {
1336         final int cookie = traceBegin("deliveryTimeout");
1337         synchronized (mService) {
1338             deliveryTimeoutLocked(queue);
1339         }
1340         traceEnd(cookie);
1341     }
1342 
1343     @GuardedBy("mService")
deliveryTimeoutLocked(@onNull BroadcastProcessQueue queue)1344     private void deliveryTimeoutLocked(@NonNull BroadcastProcessQueue queue) {
1345         finishReceiverActiveLocked(queue, BroadcastRecord.DELIVERY_TIMEOUT,
1346                 "deliveryTimeoutLocked");
1347         demoteFromRunningLocked(queue);
1348     }
1349 
1350     private class BroadcastAnrTimer extends AnrTimer<BroadcastProcessQueue> {
BroadcastAnrTimer(@onNull Handler handler)1351         BroadcastAnrTimer(@NonNull Handler handler) {
1352             super(Objects.requireNonNull(handler),
1353                     MSG_DELIVERY_TIMEOUT, "BROADCAST_TIMEOUT",
1354                     new AnrTimer.Args().extend(true).freeze(true));
1355         }
1356 
1357         @Override
getPid(@onNull BroadcastProcessQueue queue)1358         public int getPid(@NonNull BroadcastProcessQueue queue) {
1359             return (queue.app != null) ? queue.app.getPid() : 0;
1360         }
1361 
1362         @Override
getUid(@onNull BroadcastProcessQueue queue)1363         public int getUid(@NonNull BroadcastProcessQueue queue) {
1364             return (queue.app != null) ? queue.app.uid : 0;
1365         }
1366     }
1367 
1368     @GuardedBy("mService")
1369     @Override
finishReceiverLocked(@onNull ProcessRecord app, int resultCode, @Nullable String resultData, @Nullable Bundle resultExtras, boolean resultAbort, boolean waitForServices)1370     public boolean finishReceiverLocked(@NonNull ProcessRecord app, int resultCode,
1371             @Nullable String resultData, @Nullable Bundle resultExtras, boolean resultAbort,
1372             boolean waitForServices) {
1373         final BroadcastProcessQueue queue = getProcessQueue(app);
1374         if ((queue == null) || !queue.isActive()) {
1375             logw("Ignoring finishReceiverLocked; no active broadcast for " + queue);
1376             return false;
1377         }
1378 
1379         final BroadcastRecord r = queue.getActive();
1380         final int index = queue.getActiveIndex();
1381         if (r.ordered) {
1382             r.resultCode = resultCode;
1383             r.resultData = resultData;
1384             r.resultExtras = resultExtras;
1385             if (!r.isNoAbort()) {
1386                 r.resultAbort = resultAbort;
1387             }
1388         }
1389 
1390         // To ensure that "beyond" high-water marks are updated in a monotonic
1391         // way, we finish this receiver before possibly skipping any remaining
1392         // aborted receivers
1393         finishReceiverActiveLocked(queue,
1394                 BroadcastRecord.DELIVERY_DELIVERED, "remote app");
1395 
1396         // When the caller aborted an ordered broadcast, we mark all
1397         // remaining receivers as skipped
1398         if (r.resultAbort) {
1399             for (int i = index + 1; i < r.receivers.size(); i++) {
1400                 setDeliveryState(null, null, r, i, r.receivers.get(i),
1401                         BroadcastRecord.DELIVERY_SKIPPED, "resultAbort");
1402             }
1403         }
1404 
1405         if (shouldRetire(queue)) {
1406             demoteFromRunningLocked(queue);
1407             return true;
1408         }
1409 
1410         // We're on a roll; move onto the next broadcast for this process
1411         queue.makeActiveNextPending();
1412         try {
1413             if (scheduleReceiverWarmLocked(queue)) {
1414                 demoteFromRunningLocked(queue);
1415                 return true;
1416             }
1417         } catch (BroadcastRetryException e) {
1418             finishOrReEnqueueActiveBroadcast(queue);
1419             demoteFromRunningLocked(queue);
1420             return true;
1421         }
1422 
1423         return false;
1424     }
1425 
1426     /**
1427      * Return true if there are no more broadcasts in the queue or if the queue is not runnable.
1428      */
1429     @GuardedBy("mService")
shouldRetire(@onNull BroadcastProcessQueue queue)1430     private boolean shouldRetire(@NonNull BroadcastProcessQueue queue) {
1431         // If we've made reasonable progress, periodically retire ourselves to
1432         // avoid starvation of other processes and stack overflow when a
1433         // broadcast is immediately finished without waiting
1434         final boolean shouldRetire;
1435         if (UserHandle.isCore(queue.uid)) {
1436             final int nonBlockingDeliveryCount = queue.getActiveAssumedDeliveryCountSinceIdle();
1437             final int blockingDeliveryCount = (queue.getActiveCountSinceIdle()
1438                     - queue.getActiveAssumedDeliveryCountSinceIdle());
1439             shouldRetire = (blockingDeliveryCount
1440                     >= mConstants.MAX_CORE_RUNNING_BLOCKING_BROADCASTS) || (nonBlockingDeliveryCount
1441                     >= mConstants.MAX_CORE_RUNNING_NON_BLOCKING_BROADCASTS);
1442         } else {
1443             shouldRetire =
1444                     (queue.getActiveCountSinceIdle() >= mConstants.MAX_RUNNING_ACTIVE_BROADCASTS);
1445         }
1446 
1447         return !queue.isRunnable() || !queue.isProcessWarm() || shouldRetire;
1448     }
1449 
1450     /**
1451      * Terminate all active broadcasts on the queue.
1452      */
1453     @GuardedBy("mService")
finishReceiverActiveLocked(@onNull BroadcastProcessQueue queue, @DeliveryState int deliveryState, @NonNull String reason)1454     private void finishReceiverActiveLocked(@NonNull BroadcastProcessQueue queue,
1455             @DeliveryState int deliveryState, @NonNull String reason) {
1456         if (!queue.isActive()) {
1457             logw("Ignoring finishReceiverActiveLocked; no active broadcast for " + queue);
1458             return;
1459         }
1460 
1461         final int cookie = traceBegin("finishReceiver");
1462         final ProcessRecord app = queue.app;
1463         final BroadcastRecord r = queue.getActive();
1464         final int index = queue.getActiveIndex();
1465         final Object receiver = r.receivers.get(index);
1466 
1467         setDeliveryState(queue, app, r, index, receiver, deliveryState, reason);
1468 
1469         if (deliveryState == BroadcastRecord.DELIVERY_TIMEOUT) {
1470             r.anrCount++;
1471             if (app != null && !app.isDebugging()) {
1472                 final AutoCloseable timer = mAnrTimer.accept(queue);
1473                 final String packageName = getReceiverPackageName(receiver);
1474                 final String className = getReceiverClassName(receiver);
1475                 TimeoutRecord tr = TimeoutRecord.forBroadcastReceiver(r.intent, packageName,
1476                         className).setExpiredTimer(timer);
1477                 mService.appNotResponding(queue.app, tr);
1478             } else {
1479                 mAnrTimer.discard(queue);
1480             }
1481         } else if (queue.timeoutScheduled()) {
1482             cancelDeliveryTimeoutLocked(queue);
1483         }
1484 
1485         // Given that a receiver just finished, check if the "waitingFor" conditions are met.
1486         checkAndRemoveWaitingFor();
1487 
1488         traceEnd(cookie);
1489     }
1490 
1491     /**
1492      * Promote a process to the "running" list.
1493      */
1494     @GuardedBy("mService")
promoteToRunningLocked(@onNull BroadcastProcessQueue queue)1495     private void promoteToRunningLocked(@NonNull BroadcastProcessQueue queue) {
1496         // Allocate this available permit and start running!
1497         final int queueIndex = getRunningIndexOf(null);
1498         mRunning[queueIndex] = queue;
1499 
1500         // Remove ourselves from linked list of runnable things
1501         mRunnableHead = removeFromRunnableList(mRunnableHead, queue);
1502 
1503         // Emit all trace events for this process into a consistent track
1504         queue.runningTraceTrackName = TAG + ".mRunning[" + queueIndex + "]";
1505         queue.runningOomAdjusted = queue.isPendingManifest()
1506                 || queue.isPendingOrdered()
1507                 || queue.isPendingResultTo();
1508 
1509         // If already warm, we can make OOM adjust request immediately;
1510         // otherwise we need to wait until process becomes warm
1511         final boolean processWarm = queue.isProcessWarm();
1512         if (processWarm) {
1513             notifyStartedRunning(queue);
1514         }
1515 
1516         // If we're already warm, schedule next pending broadcast now;
1517         // otherwise we'll wait for the cold start to circle back around
1518         queue.makeActiveNextPending();
1519         if (processWarm) {
1520             queue.traceProcessRunningBegin();
1521         } else {
1522             queue.traceProcessStartingBegin();
1523         }
1524     }
1525 
1526     /**
1527      * Demote a process from the "running" list.
1528      */
1529     @GuardedBy("mService")
demoteFromRunningLocked(@onNull BroadcastProcessQueue queue)1530     private void demoteFromRunningLocked(@NonNull BroadcastProcessQueue queue) {
1531         if (!queue.isActive()) {
1532             logw("Ignoring demoteFromRunning; no active broadcast for " + queue);
1533             return;
1534         }
1535 
1536         final int cookie = traceBegin("demoteFromRunning");
1537         // We've drained running broadcasts; maybe move back to runnable
1538         if (mRunningColdStart == queue) {
1539             // TODO: b/399020479 - Remove wtf log once we identify the case where mRunningColdStart
1540             // is not getting cleared.
1541             // If this queue is mRunningColdStart, then it should have been cleared before
1542             // it is demoted. Log a wtf if this isn't the case.
1543             Slog.wtf(TAG, "mRunningColdStart has not been cleared; mRunningColdStart.app: "
1544                     + mRunningColdStart.app + " , queue.app: " + queue.app,
1545                             new IllegalStateException());
1546         }
1547         queue.makeActiveIdle();
1548         queue.traceProcessEnd();
1549 
1550         final int queueIndex = getRunningIndexOf(queue);
1551         mRunning[queueIndex] = null;
1552         updateRunnableList(queue);
1553         enqueueUpdateRunningList();
1554 
1555         // Tell other OS components that app is not actively running, giving
1556         // a chance to update OOM adjustment
1557         notifyStoppedRunning(queue);
1558         traceEnd(cookie);
1559     }
1560 
1561     /**
1562      * Set the delivery state on the given broadcast, then apply any additional
1563      * bookkeeping related to ordered broadcasts.
1564      */
1565     @GuardedBy("mService")
setDeliveryState(@ullable BroadcastProcessQueue queue, @Nullable ProcessRecord app, @NonNull BroadcastRecord r, int index, @NonNull Object receiver, @DeliveryState int newDeliveryState, @NonNull String reason)1566     private void setDeliveryState(@Nullable BroadcastProcessQueue queue,
1567             @Nullable ProcessRecord app, @NonNull BroadcastRecord r, int index,
1568             @NonNull Object receiver, @DeliveryState int newDeliveryState,
1569             @NonNull String reason) {
1570         final int cookie = traceBegin("setDeliveryState");
1571 
1572         // Remember the old state and apply the new state
1573         final int oldDeliveryState = getDeliveryState(r, index);
1574         final boolean beyondCountChanged = r.setDeliveryState(index, newDeliveryState, reason);
1575 
1576         // Emit any relevant tracing results when we're changing the delivery
1577         // state as part of running from a queue
1578         if (queue != null) {
1579             if (newDeliveryState == BroadcastRecord.DELIVERY_SCHEDULED) {
1580                 queue.traceActiveBegin();
1581             } else if ((oldDeliveryState == BroadcastRecord.DELIVERY_SCHEDULED)
1582                     && isDeliveryStateTerminal(newDeliveryState)) {
1583                 queue.traceActiveEnd();
1584             }
1585         }
1586 
1587         // If we're moving into a terminal state, we might have internal
1588         // bookkeeping to update for ordered broadcasts
1589         if (!isDeliveryStateTerminal(oldDeliveryState)
1590                 && isDeliveryStateTerminal(newDeliveryState)) {
1591             if ((DEBUG_BROADCAST && newDeliveryState != BroadcastRecord.DELIVERY_DELIVERED)
1592                     || r.debugLog()) {
1593                 final String msg = "Delivery state of " + r + " to " + receiver
1594                         + " via " + app + " changed from "
1595                         + deliveryStateToString(oldDeliveryState) + " to "
1596                         + deliveryStateToString(newDeliveryState) + " because " + reason;
1597                 if (newDeliveryState == BroadcastRecord.DELIVERY_DELIVERED) {
1598                     logv(msg);
1599                 } else {
1600                     logw(msg);
1601                 }
1602             }
1603 
1604             notifyFinishReceiver(queue, app, r, index, receiver);
1605         }
1606 
1607         // When we've reached a new high-water mark, we might be in a position
1608         // to unblock other receivers or the final resultTo
1609         if (beyondCountChanged) {
1610             if (r.beyondCount == r.receivers.size()) {
1611                 scheduleResultTo(r);
1612             }
1613 
1614             // Our terminal state here might be enough for another process
1615             // blocked on us to now be runnable
1616             if (r.ordered || r.prioritized) {
1617                 for (int i = 0; i < r.receivers.size(); i++) {
1618                     if (!isDeliveryStateTerminal(getDeliveryState(r, i)) || (i == index)) {
1619                         final Object otherReceiver = r.receivers.get(i);
1620                         final BroadcastProcessQueue otherQueue = getProcessQueue(
1621                                 getReceiverProcessName(otherReceiver),
1622                                 getReceiverUid(otherReceiver));
1623                         if (otherQueue != null) {
1624                             otherQueue.invalidateRunnableAt();
1625                             updateRunnableList(otherQueue);
1626                         }
1627                     }
1628                 }
1629                 enqueueUpdateRunningList();
1630             }
1631         }
1632 
1633         traceEnd(cookie);
1634     }
1635 
1636     @GuardedBy("mService")
getDeliveryState(@onNull BroadcastRecord r, int index)1637     private @DeliveryState int getDeliveryState(@NonNull BroadcastRecord r, int index) {
1638         return r.getDeliveryState(index);
1639     }
1640 
1641     @GuardedBy("mService")
1642     @Override
cleanupDisabledPackageReceiversLocked(@ullable String packageName, @Nullable Set<String> filterByClasses, int userId)1643     public boolean cleanupDisabledPackageReceiversLocked(@Nullable String packageName,
1644             @Nullable Set<String> filterByClasses, int userId) {
1645         final Predicate<BroadcastProcessQueue> queuePredicate;
1646         final BroadcastPredicate broadcastPredicate;
1647         if (packageName != null) {
1648             // Caller provided a package and user ID, so we're focused on queues
1649             // belonging to a specific UID
1650             final int uid = mService.mPackageManagerInt.getPackageUid(
1651                     packageName, PackageManager.MATCH_UNINSTALLED_PACKAGES, userId);
1652             queuePredicate = (q) -> {
1653                 return q.uid == uid;
1654             };
1655 
1656             // If caller provided a set of classes, filter to skip only those;
1657             // otherwise we skip all broadcasts
1658             if (filterByClasses != null) {
1659                 broadcastPredicate = (r, i) -> {
1660                     final Object receiver = r.receivers.get(i);
1661                     if (receiver instanceof ResolveInfo) {
1662                         final ActivityInfo info = ((ResolveInfo) receiver).activityInfo;
1663                         return packageName.equals(info.packageName)
1664                                 && filterByClasses.contains(info.name);
1665                     } else {
1666                         return false;
1667                     }
1668                 };
1669             } else {
1670                 broadcastPredicate = (r, i) -> {
1671                     final Object receiver = r.receivers.get(i);
1672                     return packageName.equals(getReceiverPackageName(receiver));
1673                 };
1674             }
1675         } else {
1676             // Caller is cleaning up an entire user ID; skip all broadcasts
1677             queuePredicate = (q) -> {
1678                 return UserHandle.getUserId(q.uid) == userId;
1679             };
1680             broadcastPredicate = BROADCAST_PREDICATE_ANY;
1681 
1682             cleanupUserStateLocked(mUidForeground, userId);
1683         }
1684         return forEachMatchingBroadcast(queuePredicate, broadcastPredicate,
1685                 mBroadcastConsumerSkip, true);
1686     }
1687 
1688     @GuardedBy("mService")
cleanupUserStateLocked(@onNull SparseBooleanArray uidState, int userId)1689     private void cleanupUserStateLocked(@NonNull SparseBooleanArray uidState, int userId) {
1690         for (int i = uidState.size() - 1; i >= 0; --i) {
1691             final int uid = uidState.keyAt(i);
1692             if (UserHandle.getUserId(uid) == userId) {
1693                 uidState.removeAt(i);
1694             }
1695         }
1696     }
1697 
1698     private static final Predicate<BroadcastProcessQueue> QUEUE_PREDICATE_ANY =
1699             (q) -> true;
1700     private static final BroadcastPredicate BROADCAST_PREDICATE_ANY =
1701             (r, i) -> true;
1702 
1703     /**
1704      * Typical consumer that will skip the given broadcast, usually as a result
1705      * of it matching a predicate.
1706      */
1707     @GuardedBy("mService")
1708     private final BroadcastConsumer mBroadcastConsumerSkip = (r, i) -> {
1709         setDeliveryState(null, null, r, i, r.receivers.get(i), BroadcastRecord.DELIVERY_SKIPPED,
1710                 "mBroadcastConsumerSkip");
1711     };
1712 
1713     /**
1714      * Typical consumer that will both skip the given broadcast and mark it as
1715      * cancelled, usually as a result of it matching a predicate.
1716      */
1717     @GuardedBy("mService")
1718     private final BroadcastConsumer mBroadcastConsumerSkipAndCanceled = (r, i) -> {
1719         setDeliveryState(null, null, r, i, r.receivers.get(i), BroadcastRecord.DELIVERY_SKIPPED,
1720                 "mBroadcastConsumerSkipAndCanceled");
1721         r.resultCode = Activity.RESULT_CANCELED;
1722         r.resultData = null;
1723         r.resultExtras = null;
1724     };
1725 
1726     @VisibleForTesting
1727     @GuardedBy("mService")
1728     final BroadcastConsumer mBroadcastConsumerDeferApply = (r, i) -> {
1729         setDeliveryState(null, null, r, i, r.receivers.get(i), BroadcastRecord.DELIVERY_DEFERRED,
1730                 "mBroadcastConsumerDeferApply");
1731     };
1732 
1733     @VisibleForTesting
1734     @GuardedBy("mService")
1735     final BroadcastConsumer mBroadcastConsumerDeferClear = (r, i) -> {
1736         setDeliveryState(null, null, r, i, r.receivers.get(i), BroadcastRecord.DELIVERY_PENDING,
1737                 "mBroadcastConsumerDeferClear");
1738     };
1739 
1740     @GuardedBy("mService")
1741     final BroadcastRecordConsumer mBroadcastRecordConsumerEnqueue = this::enqueueBroadcastLocked;
1742 
1743     /**
1744      * Verify that all known {@link #mProcessQueues} are in the state tested by
1745      * the given {@link Predicate}.
1746      */
1747     @GuardedBy("mService")
testAllProcessQueues(@onNull Predicate<BroadcastProcessQueue> test, @NonNull String label, @NonNull PrintWriter pw)1748     private boolean testAllProcessQueues(@NonNull Predicate<BroadcastProcessQueue> test,
1749             @NonNull String label, @NonNull PrintWriter pw) {
1750         for (int i = 0; i < mProcessQueues.size(); i++) {
1751             BroadcastProcessQueue leaf = mProcessQueues.valueAt(i);
1752             while (leaf != null) {
1753                 if (!test.test(leaf)) {
1754                     final long now = SystemClock.uptimeMillis();
1755                     if (now > mLastTestFailureTime + DateUtils.SECOND_IN_MILLIS) {
1756                         mLastTestFailureTime = now;
1757                         pw.println("Test " + label + " failed due to " + leaf.toShortString() + " "
1758                                 + leaf.describeStateLocked());
1759                         pw.flush();
1760                     }
1761                     return false;
1762                 }
1763                 leaf = leaf.processNameNext;
1764             }
1765         }
1766         pw.println("Test " + label + " passed");
1767         pw.flush();
1768         return true;
1769     }
1770 
1771     @GuardedBy("mService")
forEachMatchingBroadcast( @onNull Predicate<BroadcastProcessQueue> queuePredicate, @NonNull BroadcastPredicate broadcastPredicate, @NonNull BroadcastConsumer broadcastConsumer, boolean andRemove)1772     private boolean forEachMatchingBroadcast(
1773             @NonNull Predicate<BroadcastProcessQueue> queuePredicate,
1774             @NonNull BroadcastPredicate broadcastPredicate,
1775             @NonNull BroadcastConsumer broadcastConsumer, boolean andRemove) {
1776         boolean didSomething = false;
1777         for (int i = mProcessQueues.size() - 1; i >= 0; i--) {
1778             BroadcastProcessQueue leaf = mProcessQueues.valueAt(i);
1779             while (leaf != null) {
1780                 if (queuePredicate.test(leaf)) {
1781                     if (leaf.forEachMatchingBroadcast(broadcastPredicate,
1782                             broadcastConsumer, andRemove)) {
1783                         updateRunnableList(leaf);
1784                         didSomething = true;
1785                     }
1786                 }
1787                 leaf = leaf.processNameNext;
1788             }
1789         }
1790         if (didSomething) {
1791             enqueueUpdateRunningList();
1792         }
1793         return didSomething;
1794     }
1795 
1796     @GuardedBy("mService")
forEachMatchingQueue( @onNull Predicate<BroadcastProcessQueue> queuePredicate, @NonNull Consumer<BroadcastProcessQueue> queueConsumer)1797     private boolean forEachMatchingQueue(
1798             @NonNull Predicate<BroadcastProcessQueue> queuePredicate,
1799             @NonNull Consumer<BroadcastProcessQueue> queueConsumer) {
1800         boolean didSomething = false;
1801         for (int i = mProcessQueues.size() - 1; i >= 0; i--) {
1802             BroadcastProcessQueue leaf = mProcessQueues.valueAt(i);
1803             while (leaf != null) {
1804                 if (queuePredicate.test(leaf)) {
1805                     queueConsumer.accept(leaf);
1806                     updateRunnableList(leaf);
1807                     didSomething = true;
1808                 }
1809                 leaf = leaf.processNameNext;
1810             }
1811         }
1812         if (didSomething) {
1813             enqueueUpdateRunningList();
1814         }
1815         return didSomething;
1816     }
1817 
1818     @GuardedBy("mService")
1819     @Override
start(@onNull ContentResolver resolver)1820     public void start(@NonNull ContentResolver resolver) {
1821         mFgConstants.startObserving(mHandler, resolver);
1822         mBgConstants.startObserving(mHandler, resolver);
1823 
1824         mService.registerUidObserver(new UidObserver() {
1825             @Override
1826             public void onUidStateChanged(int uid, int procState, long procStateSeq,
1827                     int capability) {
1828                 mLocalHandler.removeMessages(MSG_UID_STATE_CHANGED, uid);
1829                 mLocalHandler.obtainMessage(MSG_UID_STATE_CHANGED, procState, 0, uid)
1830                         .sendToTarget();
1831             }
1832         }, ActivityManager.UID_OBSERVER_PROCSTATE,
1833                 ActivityManager.PROCESS_STATE_TOP, "android");
1834 
1835         // Kick off periodic health checks
1836         mLocalHandler.sendEmptyMessage(MSG_CHECK_HEALTH);
1837     }
1838 
1839     @GuardedBy("mService")
1840     @Override
isIdleLocked()1841     public boolean isIdleLocked() {
1842         return isIdleLocked(LOG_WRITER_INFO);
1843     }
1844 
1845     @GuardedBy("mService")
isIdleLocked(@onNull PrintWriter pw)1846     public boolean isIdleLocked(@NonNull PrintWriter pw) {
1847         return testAllProcessQueues(q -> q.isIdle(), "idle", pw);
1848     }
1849 
1850     @GuardedBy("mService")
1851     @Override
isBeyondBarrierLocked(@ptimeMillisLong long barrierTime)1852     public boolean isBeyondBarrierLocked(@UptimeMillisLong long barrierTime) {
1853         return isBeyondBarrierLocked(barrierTime, LOG_WRITER_INFO);
1854     }
1855 
1856     @GuardedBy("mService")
isBeyondBarrierLocked(@ptimeMillisLong long barrierTime, @NonNull PrintWriter pw)1857     public boolean isBeyondBarrierLocked(@UptimeMillisLong long barrierTime,
1858             @NonNull PrintWriter pw) {
1859         return testAllProcessQueues(q -> q.isBeyondBarrierLocked(barrierTime), "barrier", pw);
1860     }
1861 
1862     @GuardedBy("mService")
1863     @Override
isDispatchedLocked(@onNull Intent intent)1864     public boolean isDispatchedLocked(@NonNull Intent intent) {
1865         return isDispatchedLocked(intent, LOG_WRITER_INFO);
1866     }
1867 
1868     @GuardedBy("mService")
isDispatchedLocked(@onNull Intent intent, @NonNull PrintWriter pw)1869     public boolean isDispatchedLocked(@NonNull Intent intent, @NonNull PrintWriter pw) {
1870         return testAllProcessQueues(q -> q.isDispatched(intent),
1871                 "dispatch of " + intent, pw);
1872     }
1873 
1874     @GuardedBy("mService")
1875     @Override
waitForIdle(@onNull PrintWriter pw)1876     public void waitForIdle(@NonNull PrintWriter pw) {
1877         waitFor(() -> isIdleLocked(pw));
1878     }
1879 
1880     @Override
waitForBarrier(@onNull PrintWriter pw)1881     public void waitForBarrier(@NonNull PrintWriter pw) {
1882         final long now = SystemClock.uptimeMillis();
1883         synchronized (mService) {
1884             forEachMatchingQueue(QUEUE_PREDICATE_ANY,
1885                     q -> q.addPrioritizeEarliestRequest());
1886         }
1887         try {
1888             waitFor(() -> isBeyondBarrierLocked(now, pw));
1889         } finally {
1890             synchronized (mService) {
1891                 forEachMatchingQueue(QUEUE_PREDICATE_ANY,
1892                         q -> q.removePrioritizeEarliestRequest());
1893             }
1894         }
1895     }
1896 
1897     @GuardedBy("mService")
1898     @Override
waitForDispatched(@onNull Intent intent, @NonNull PrintWriter pw)1899     public void waitForDispatched(@NonNull Intent intent, @NonNull PrintWriter pw) {
1900         waitFor(() -> isDispatchedLocked(intent, pw));
1901     }
1902 
waitFor(@onNull BooleanSupplier condition)1903     private void waitFor(@NonNull BooleanSupplier condition) {
1904         final CountDownLatch latch = new CountDownLatch(1);
1905         synchronized (mService) {
1906             mWaitingFor.add(Pair.create(condition, latch));
1907         }
1908         enqueueUpdateRunningList();
1909         try {
1910             latch.await();
1911         } catch (InterruptedException e) {
1912             throw new RuntimeException(e);
1913         }
1914     }
1915 
1916     @GuardedBy("mService")
checkAndRemoveWaitingFor()1917     private void checkAndRemoveWaitingFor() {
1918         if (!mWaitingFor.isEmpty()) {
1919             mWaitingFor.removeIf((pair) -> {
1920                 if (pair.first.getAsBoolean()) {
1921                     pair.second.countDown();
1922                     return true;
1923                 } else {
1924                     return false;
1925                 }
1926             });
1927         }
1928     }
1929 
1930     @Override
forceDelayBroadcastDelivery(@onNull String targetPackage, long delayedDurationMs)1931     public void forceDelayBroadcastDelivery(@NonNull String targetPackage,
1932             long delayedDurationMs) {
1933         synchronized (mService) {
1934             forEachMatchingQueue(
1935                     (q) -> targetPackage.equals(q.getPackageName()),
1936                     (q) -> q.forceDelayBroadcastDelivery(delayedDurationMs));
1937         }
1938     }
1939 
1940     @Override
describeStateLocked()1941     public String describeStateLocked() {
1942         return getRunningSize() + " running";
1943     }
1944 
checkHealth()1945     private void checkHealth() {
1946         synchronized (mService) {
1947             checkHealthLocked();
1948         }
1949     }
1950 
1951     @GuardedBy("mService")
checkHealthLocked()1952     private void checkHealthLocked() {
1953         try {
1954             assertHealthLocked();
1955 
1956             // If no health issues found above, check again in the future
1957             mLocalHandler.sendEmptyMessageDelayed(MSG_CHECK_HEALTH,
1958                     DateUtils.MINUTE_IN_MILLIS);
1959 
1960         } catch (Exception e) {
1961             // Throw up a message to indicate that something went wrong, and
1962             // dump current state for later inspection
1963             Slog.wtf(TAG, e);
1964             dumpToDropBoxLocked(e.toString());
1965         }
1966     }
1967 
1968     /**
1969      * Check overall health, confirming things are in a reasonable state and
1970      * that we're not wedged. If we determine we're in an unhealthy state, dump
1971      * current state once and stop future health checks to avoid spamming.
1972      */
1973     @VisibleForTesting
1974     @GuardedBy("mService")
assertHealthLocked()1975     void assertHealthLocked() {
1976         // Verify all runnable queues are sorted
1977         BroadcastProcessQueue prev = null;
1978         BroadcastProcessQueue next = mRunnableHead;
1979         while (next != null) {
1980             checkState(next.runnableAtPrev == prev, "runnableAtPrev");
1981             checkState(next.isRunnable(), "isRunnable " + next);
1982             if (prev != null) {
1983                 checkState(next.getRunnableAt() >= prev.getRunnableAt(),
1984                         "getRunnableAt " + next + " vs " + prev);
1985             }
1986             prev = next;
1987             next = next.runnableAtNext;
1988         }
1989 
1990         // Verify all running queues are active
1991         for (BroadcastProcessQueue queue : mRunning) {
1992             if (queue != null) {
1993                 checkState(queue.isActive(), "isActive " + queue);
1994             }
1995         }
1996 
1997         // Verify that pending cold start hasn't been orphaned
1998         if (mRunningColdStart != null) {
1999             checkState(getRunningIndexOf(mRunningColdStart) >= 0,
2000                     "isOrphaned " + mRunningColdStart);
2001 
2002             final BroadcastProcessQueue queue = getProcessQueue(mRunningColdStart.processName,
2003                     mRunningColdStart.uid);
2004             checkState(queue == mRunningColdStart, "Conflicting " + mRunningColdStart
2005                     + " with queue " + queue
2006                     + ";\n mRunningColdStart.app: " + mRunningColdStart.app.toDetailedString()
2007                     + ";\n queue.app: " + queue.app.toDetailedString());
2008 
2009             checkState(mRunningColdStart.app != null, "Empty cold start queue "
2010                     + mRunningColdStart);
2011 
2012             if (mRunningColdStart.isProcessStartInitiationTimeoutExpected()) {
2013                 final StringBuilder sb = new StringBuilder();
2014                 sb.append("Process start timeout expected for app ");
2015                 sb.append(mRunningColdStart.app);
2016                 sb.append(" in queue ");
2017                 sb.append(mRunningColdStart);
2018                 sb.append("; startUpTime: ");
2019                 final long startupTimeMs =
2020                         mRunningColdStart.getProcessStartInitiatedTimestampMillis();
2021                 sb.append(startupTimeMs == 0 ? "<none>"
2022                         : TimeUtils.formatDuration(startupTimeMs - SystemClock.uptimeMillis()));
2023                 sb.append(";\n app: ");
2024                 sb.append(mRunningColdStart.app.toDetailedString());
2025                 checkState(false, sb.toString());
2026             }
2027         }
2028 
2029         // Verify health of all known process queues
2030         for (int i = 0; i < mProcessQueues.size(); i++) {
2031             BroadcastProcessQueue leaf = mProcessQueues.valueAt(i);
2032             while (leaf != null) {
2033                 leaf.assertHealthLocked();
2034                 leaf = leaf.processNameNext;
2035             }
2036         }
2037     }
2038 
2039     @SuppressWarnings("CheckResult")
2040     @GuardedBy("mService")
updateWarmProcess(@onNull BroadcastProcessQueue queue)2041     private void updateWarmProcess(@NonNull BroadcastProcessQueue queue) {
2042         if (!queue.isProcessWarm()) {
2043             // This is a bit awkward; we're in the middle of traversing the
2044             // runnable queue, so we can't reorder that list if the runnable
2045             // time changes here. However, if this process was just found to be
2046             // warm via this operation, we're going to immediately promote it to
2047             // be running, and any side effect of this operation will then apply
2048             // after it's finished and is returned to the runnable list.
2049             final ProcessRecord app = mService.getProcessRecordLocked(queue.processName, queue.uid);
2050             queue.setProcessAndUidState(app, mUidForeground.get(queue.uid, false),
2051                     isProcessFreezable(app));
2052         }
2053     }
2054 
2055     /**
2056      * Update the {@link ProcessRecord} associated with the given
2057      * {@link BroadcastProcessQueue}. Also updates any runnable status that
2058      * might have changed as a side-effect.
2059      */
2060     @GuardedBy("mService")
setQueueProcess(@onNull BroadcastProcessQueue queue, @Nullable ProcessRecord app)2061     private void setQueueProcess(@NonNull BroadcastProcessQueue queue,
2062             @Nullable ProcessRecord app) {
2063         if (queue.setProcessAndUidState(app, mUidForeground.get(queue.uid, false),
2064                 isProcessFreezable(app))) {
2065             updateRunnableList(queue);
2066         }
2067     }
2068 
2069     @VisibleForTesting
2070     @GuardedBy("mService")
isProcessFreezable(@ullable ProcessRecord app)2071     boolean isProcessFreezable(@Nullable ProcessRecord app) {
2072         if (app == null) {
2073             return false;
2074         }
2075         synchronized (mService.mProcLock) {
2076             return app.mOptRecord.isPendingFreeze() || app.mOptRecord.isFrozen();
2077         }
2078     }
2079 
2080     /**
2081      * Refresh the process queues with the latest process state so that runnableAt
2082      * can be updated.
2083      */
2084     @GuardedBy("mService")
refreshProcessQueuesLocked(int uid)2085     private void refreshProcessQueuesLocked(int uid) {
2086         BroadcastProcessQueue leaf = mProcessQueues.get(uid);
2087         while (leaf != null) {
2088             // Update internal state by refreshing values previously
2089             // read from any known running process
2090             setQueueProcess(leaf, leaf.app);
2091             leaf = leaf.processNameNext;
2092         }
2093         enqueueUpdateRunningList();
2094     }
2095 
handleProcessFreezableChanged(@onNull ProcessRecord app)2096     private void handleProcessFreezableChanged(@NonNull ProcessRecord app) {
2097         synchronized (mService) {
2098             final BroadcastProcessQueue queue = getProcessQueue(app.processName, app.uid);
2099             if (queue == null || queue.app == null || queue.app.getPid() != app.getPid()) {
2100                 return;
2101             }
2102             if (!isProcessFreezable(app)) {
2103                 queue.enqueueOutgoingBroadcasts(mBroadcastRecordConsumerEnqueue);
2104             }
2105             refreshProcessQueueLocked(queue);
2106         }
2107     }
2108 
2109     /**
2110      * Refresh the process queue corresponding to {@code app} with the latest process state
2111      * so that runnableAt can be updated.
2112      */
2113     @GuardedBy("mService")
refreshProcessQueueLocked(@onNull BroadcastProcessQueue queue)2114     private void refreshProcessQueueLocked(@NonNull BroadcastProcessQueue queue) {
2115         setQueueProcess(queue, queue.app);
2116         enqueueUpdateRunningList();
2117     }
2118 
2119     /**
2120      * Inform other parts of OS that the given broadcast queue has started
2121      * running, typically for internal bookkeeping.
2122      */
2123     @GuardedBy("mService")
notifyStartedRunning(@onNull BroadcastProcessQueue queue)2124     private void notifyStartedRunning(@NonNull BroadcastProcessQueue queue) {
2125         if (queue.app != null) {
2126             queue.incrementCurAppReceivers();
2127 
2128             // Don't bump its LRU position if it's in the background restricted.
2129             if (mService.mInternal.getRestrictionLevel(
2130                     queue.uid) < ActivityManager.RESTRICTION_LEVEL_RESTRICTED_BUCKET) {
2131                 mService.updateLruProcessLocked(queue.app, false, null);
2132             }
2133 
2134             mService.mOomAdjuster.unfreezeTemporarily(queue.app,
2135                     CachedAppOptimizer.UNFREEZE_REASON_START_RECEIVER);
2136 
2137             if (queue.runningOomAdjusted) {
2138                 queue.app.mState.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_RECEIVER);
2139                 mService.enqueueOomAdjTargetLocked(queue.app);
2140             }
2141         }
2142     }
2143 
2144     /**
2145      * Inform other parts of OS that the given broadcast queue has stopped
2146      * running, typically for internal bookkeeping.
2147      */
2148     @GuardedBy("mService")
notifyStoppedRunning(@onNull BroadcastProcessQueue queue)2149     private void notifyStoppedRunning(@NonNull BroadcastProcessQueue queue) {
2150         if (queue.app != null) {
2151             queue.decrementCurAppReceivers();
2152 
2153             if (queue.runningOomAdjusted) {
2154                 mService.enqueueOomAdjTargetLocked(queue.app);
2155             }
2156         }
2157     }
2158 
2159     /**
2160      * Inform other parts of OS that the given broadcast was just scheduled for
2161      * a registered receiver, typically for internal bookkeeping.
2162      */
2163     @GuardedBy("mService")
notifyScheduleRegisteredReceiver(@onNull ProcessRecord app, @NonNull BroadcastRecord r, @NonNull BroadcastFilter receiver)2164     private void notifyScheduleRegisteredReceiver(@NonNull ProcessRecord app,
2165             @NonNull BroadcastRecord r, @NonNull BroadcastFilter receiver) {
2166         reportUsageStatsBroadcastDispatched(app, r);
2167     }
2168 
2169     /**
2170      * Inform other parts of OS that the given broadcast was just scheduled for
2171      * a manifest receiver, typically for internal bookkeeping.
2172      */
2173     @GuardedBy("mService")
notifyScheduleReceiver(@onNull ProcessRecord app, @NonNull BroadcastRecord r, @NonNull ResolveInfo receiver)2174     private void notifyScheduleReceiver(@NonNull ProcessRecord app,
2175             @NonNull BroadcastRecord r, @NonNull ResolveInfo receiver) {
2176         reportUsageStatsBroadcastDispatched(app, r);
2177 
2178         final String receiverPackageName = receiver.activityInfo.packageName;
2179         app.addPackage(receiverPackageName,
2180                 receiver.activityInfo.applicationInfo.longVersionCode, mService.mProcessStats);
2181 
2182         final boolean targetedBroadcast = r.intent.getComponent() != null;
2183         final boolean targetedSelf = Objects.equals(r.callerPackage, receiverPackageName);
2184         if (targetedBroadcast && !targetedSelf) {
2185             if (r.userId == UserHandle.USER_ALL) {
2186                 mService.mUsageStatsService.reportEventForAllUsers(
2187                         receiverPackageName, Event.APP_COMPONENT_USED);
2188             } else {
2189                 mService.mUsageStatsService.reportEvent(receiverPackageName,
2190                         r.userId, Event.APP_COMPONENT_USED);
2191             }
2192         }
2193 
2194         mService.notifyPackageUse(receiverPackageName,
2195                 PackageManager.NOTIFY_PACKAGE_USE_BROADCAST_RECEIVER);
2196 
2197         mService.mPackageManagerInt.notifyComponentUsed(
2198                 receiverPackageName, r.userId, r.callerPackage, r.toString());
2199     }
2200 
2201     @GuardedBy("mService")
reportUsageStatsBroadcastDispatched(@onNull ProcessRecord app, @NonNull BroadcastRecord r)2202     private void reportUsageStatsBroadcastDispatched(@NonNull ProcessRecord app,
2203             @NonNull BroadcastRecord r) {
2204         final long idForResponseEvent = (r.options != null)
2205                 ? r.options.getIdForResponseEvent() : 0L;
2206         if (idForResponseEvent <= 0) return;
2207 
2208         final String targetPackage;
2209         if (r.intent.getPackage() != null) {
2210             targetPackage = r.intent.getPackage();
2211         } else if (r.intent.getComponent() != null) {
2212             targetPackage = r.intent.getComponent().getPackageName();
2213         } else {
2214             targetPackage = null;
2215         }
2216         if (targetPackage == null) return;
2217 
2218         mService.mUsageStatsService.reportBroadcastDispatched(r.callingUid, targetPackage,
2219                 UserHandle.of(r.userId), idForResponseEvent, SystemClock.elapsedRealtime(),
2220                 mService.getUidStateLocked(app.uid));
2221     }
2222 
2223     /**
2224      * Inform other parts of OS that the given broadcast was just finished,
2225      * typically for internal bookkeeping.
2226      */
2227     @GuardedBy("mService")
notifyFinishReceiver(@ullable BroadcastProcessQueue queue, @Nullable ProcessRecord app, @NonNull BroadcastRecord r, int index, @NonNull Object receiver)2228     private void notifyFinishReceiver(@Nullable BroadcastProcessQueue queue,
2229             @Nullable ProcessRecord app, @NonNull BroadcastRecord r, int index,
2230             @NonNull Object receiver) {
2231         if (r.wasDeliveryAttempted(index)) {
2232             logBroadcastDeliveryEventReported(queue, app, r, index, receiver);
2233         }
2234 
2235         if (!r.isAssumedDelivered(index) && r.wasDelivered(index)) {
2236             r.updateBroadcastProcessedEventRecord(receiver,
2237                     r.terminalTime[index] - r.scheduledTime[index]);
2238         }
2239 
2240         final boolean recordFinished = (r.terminalCount == r.receivers.size());
2241         if (recordFinished) {
2242             notifyFinishBroadcast(r);
2243         }
2244     }
2245 
2246     @GuardedBy("mService")
logBroadcastDeliveryEventReported(@ullable BroadcastProcessQueue queue, @Nullable ProcessRecord app, @NonNull BroadcastRecord r, int index, @NonNull Object receiver)2247     private void logBroadcastDeliveryEventReported(@Nullable BroadcastProcessQueue queue,
2248             @Nullable ProcessRecord app, @NonNull BroadcastRecord r, int index,
2249             @NonNull Object receiver) {
2250         // Report statistics for each individual receiver
2251         final int uid = getReceiverUid(receiver);
2252         final int senderUid = (r.callingUid == -1) ? Process.SYSTEM_UID : r.callingUid;
2253         final String actionName = r.intent.getAction();
2254         final int receiverType = (receiver instanceof BroadcastFilter)
2255                 ? BROADCAST_DELIVERY_EVENT_REPORTED__RECEIVER_TYPE__RUNTIME
2256                 : BROADCAST_DELIVERY_EVENT_REPORTED__RECEIVER_TYPE__MANIFEST;
2257         final int type;
2258         final int receiverProcessState;
2259         if (queue == null) {
2260             type = BROADCAST_DELIVERY_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_UNKNOWN;
2261             receiverProcessState = ActivityManager.PROCESS_STATE_UNKNOWN;
2262         } else if (queue.getActiveViaColdStart()) {
2263             type = BROADCAST_DELIVERY_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_COLD;
2264             receiverProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT;
2265         } else {
2266             type = BROADCAST_DELIVERY_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_WARM;
2267             receiverProcessState = queue.lastProcessState;
2268         }
2269         // With the new per-process queues, there's no delay between being
2270         // "dispatched" and "scheduled", so we report no "receive delay"
2271         final long dispatchDelay = r.scheduledTime[index] - r.enqueueTime;
2272         final long receiveDelay = 0;
2273         final long finishDelay = r.terminalTime[index] - r.scheduledTime[index];
2274         if (DEBUG_PROCESSES) {
2275             Slog.d(TAG, "Logging broadcast for "
2276                     + (app != null ? app.info.packageName : "<null>")
2277                     + ", stopped=" + queue.getActiveWasStopped()
2278                     + ", firstLaunch=" + queue.getActiveFirstLaunch());
2279         }
2280         if (queue != null) {
2281             final int packageState = queue.getActiveWasStopped()
2282                     ? SERVICE_REQUEST_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_STOPPED
2283                     : SERVICE_REQUEST_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_NORMAL;
2284             FrameworkStatsLog.write(BROADCAST_DELIVERY_EVENT_REPORTED, uid, senderUid, actionName,
2285                     receiverType, type, dispatchDelay, receiveDelay, finishDelay, packageState,
2286                     app != null ? app.info.packageName : null, r.callerPackage,
2287                     r.calculateTypeForLogging(), r.getDeliveryGroupPolicy(), r.intent.getFlags(),
2288                     BroadcastRecord.getReceiverPriority(receiver), r.callerProcState,
2289                     receiverProcessState, queue.getActiveFirstLaunch(),
2290                     0L /* TODO: stoppedDuration */);
2291             // Reset the states after logging
2292             queue.setActiveFirstLaunch(false);
2293             queue.setActiveWasStopped(false);
2294         }
2295     }
2296 
2297     @GuardedBy("mService")
notifyFinishBroadcast(@onNull BroadcastRecord r)2298     private void notifyFinishBroadcast(@NonNull BroadcastRecord r) {
2299         mService.notifyBroadcastFinishedLocked(r);
2300         r.finishTime = SystemClock.uptimeMillis();
2301         r.nextReceiver = r.receivers.size();
2302         mHistory.onBroadcastFinishedLocked(r);
2303 
2304         logBootCompletedBroadcastCompletionLatencyIfPossible(r);
2305         r.logBroadcastProcessedEventRecord();
2306 
2307         if (r.intent.getComponent() == null && r.intent.getPackage() == null
2308                 && (r.intent.getFlags() & Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
2309             int manifestCount = 0;
2310             int manifestSkipCount = 0;
2311             for (int i = 0; i < r.receivers.size(); i++) {
2312                 if (r.receivers.get(i) instanceof ResolveInfo) {
2313                     manifestCount++;
2314                     if (r.delivery[i] == BroadcastRecord.DELIVERY_SKIPPED) {
2315                         manifestSkipCount++;
2316                     }
2317                 }
2318             }
2319 
2320             final long dispatchTime = SystemClock.uptimeMillis() - r.enqueueTime;
2321             mService.addBroadcastStatLocked(r.intent.getAction(), r.callerPackage,
2322                     manifestCount, manifestSkipCount, dispatchTime);
2323         }
2324     }
2325 
2326     @VisibleForTesting
2327     @GuardedBy("mService")
getOrCreateProcessQueue(@onNull ProcessRecord app)2328     @NonNull BroadcastProcessQueue getOrCreateProcessQueue(@NonNull ProcessRecord app) {
2329         return getOrCreateProcessQueue(app.processName, app.info.uid);
2330     }
2331 
2332     @VisibleForTesting
2333     @GuardedBy("mService")
getOrCreateProcessQueue(@onNull String processName, int uid)2334     @NonNull BroadcastProcessQueue getOrCreateProcessQueue(@NonNull String processName,
2335             int uid) {
2336         BroadcastProcessQueue leaf = mProcessQueues.get(uid);
2337         while (leaf != null) {
2338             if (Objects.equals(leaf.processName, processName)) {
2339                 return leaf;
2340             } else if (leaf.processNameNext == null) {
2341                 break;
2342             }
2343             leaf = leaf.processNameNext;
2344         }
2345 
2346         BroadcastProcessQueue created = new BroadcastProcessQueue(mConstants, processName, uid);
2347         setQueueProcess(created, mService.getProcessRecordLocked(processName, uid));
2348 
2349         if (leaf == null) {
2350             mProcessQueues.put(uid, created);
2351         } else {
2352             leaf.processNameNext = created;
2353         }
2354         return created;
2355     }
2356 
2357     @VisibleForTesting
2358     @GuardedBy("mService")
getProcessQueue(@onNull ProcessRecord app)2359     @Nullable BroadcastProcessQueue getProcessQueue(@NonNull ProcessRecord app) {
2360         return getProcessQueue(app.processName, app.info.uid);
2361     }
2362 
2363     @VisibleForTesting
2364     @GuardedBy("mService")
getProcessQueue(@onNull String processName, int uid)2365     @Nullable BroadcastProcessQueue getProcessQueue(@NonNull String processName, int uid) {
2366         BroadcastProcessQueue leaf = mProcessQueues.get(uid);
2367         while (leaf != null) {
2368             if (Objects.equals(leaf.processName, processName)) {
2369                 return leaf;
2370             }
2371             leaf = leaf.processNameNext;
2372         }
2373         return null;
2374     }
2375 
2376     @VisibleForTesting
2377     @GuardedBy("mService")
removeProcessQueue(@onNull String processName, int uid)2378     @Nullable BroadcastProcessQueue removeProcessQueue(@NonNull String processName,
2379             int uid) {
2380         BroadcastProcessQueue prev = null;
2381         BroadcastProcessQueue leaf = mProcessQueues.get(uid);
2382         while (leaf != null) {
2383             if (Objects.equals(leaf.processName, processName)) {
2384                 if (prev != null) {
2385                     prev.processNameNext = leaf.processNameNext;
2386                 } else {
2387                     if (leaf.processNameNext != null) {
2388                         mProcessQueues.put(uid, leaf.processNameNext);
2389                     } else {
2390                         mProcessQueues.remove(uid);
2391                     }
2392                 }
2393                 return leaf;
2394             }
2395             prev = leaf;
2396             leaf = leaf.processNameNext;
2397         }
2398         return null;
2399     }
2400 
2401     @GuardedBy("mService")
logBootCompletedBroadcastCompletionLatencyIfPossible(BroadcastRecord r)2402     private void logBootCompletedBroadcastCompletionLatencyIfPossible(BroadcastRecord r) {
2403         // Only log after last receiver.
2404         // In case of split BOOT_COMPLETED broadcast, make sure only call this method on the
2405         // last BroadcastRecord of the split broadcast which has non-null resultTo.
2406         final int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
2407         if (r.nextReceiver < numReceivers) {
2408             return;
2409         }
2410         final String action = r.intent.getAction();
2411         int event = 0;
2412         if (Intent.ACTION_LOCKED_BOOT_COMPLETED.equals(action)) {
2413             event = BOOT_COMPLETED_BROADCAST_COMPLETION_LATENCY_REPORTED__EVENT__LOCKED_BOOT_COMPLETED;
2414         } else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
2415             event = BOOT_COMPLETED_BROADCAST_COMPLETION_LATENCY_REPORTED__EVENT__BOOT_COMPLETED;
2416         }
2417         if (event != 0) {
2418             final int dispatchLatency = (int) (r.dispatchTime - r.enqueueTime);
2419             final int completeLatency = (int) (SystemClock.uptimeMillis() - r.enqueueTime);
2420             final int dispatchRealLatency = (int) (r.dispatchRealTime - r.enqueueRealTime);
2421             final int completeRealLatency = (int)
2422                     (SystemClock.elapsedRealtime() - r.enqueueRealTime);
2423             int userType =
2424                     FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__USER_TYPE__TYPE_UNKNOWN;
2425             // This method is called very infrequently, no performance issue we call
2426             // LocalServices.getService() here.
2427             final UserManagerInternal umInternal = LocalServices.getService(
2428                     UserManagerInternal.class);
2429             final UserInfo userInfo =
2430                     (umInternal != null) ? umInternal.getUserInfo(r.userId) : null;
2431             if (userInfo != null) {
2432                 userType = UserJourneyLogger.getUserTypeForStatsd(userInfo.userType);
2433             }
2434             Slog.i(TAG, "BOOT_COMPLETED_BROADCAST_COMPLETION_LATENCY_REPORTED action:"
2435                     + action
2436                     + " dispatchLatency:" + dispatchLatency
2437                     + " completeLatency:" + completeLatency
2438                     + " dispatchRealLatency:" + dispatchRealLatency
2439                     + " completeRealLatency:" + completeRealLatency
2440                     + " receiversSize:" + numReceivers
2441                     + " userId:" + r.userId
2442                     + " userType:" + (userInfo != null ? userInfo.userType : null));
2443             FrameworkStatsLog.write(
2444                     BOOT_COMPLETED_BROADCAST_COMPLETION_LATENCY_REPORTED,
2445                     event,
2446                     dispatchLatency,
2447                     completeLatency,
2448                     dispatchRealLatency,
2449                     completeRealLatency,
2450                     r.userId,
2451                     userType);
2452         }
2453     }
2454 
2455     @Override
2456     @NeverCompile
2457     @GuardedBy("mService")
dumpDebug(@onNull ProtoOutputStream proto, long fieldId)2458     public void dumpDebug(@NonNull ProtoOutputStream proto, long fieldId) {
2459         long token = proto.start(fieldId);
2460         mHistory.dumpDebug(proto);
2461         proto.end(token);
2462     }
2463 
2464     @Override
2465     @NeverCompile
2466     @GuardedBy("mService")
dumpLocked(@onNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args, int opti, boolean dumpConstants, boolean dumpHistory, boolean dumpAll, @Nullable String dumpPackage, @Nullable String dumpIntentAction, boolean needSep)2467     public boolean dumpLocked(@NonNull FileDescriptor fd, @NonNull PrintWriter pw,
2468             @NonNull String[] args, int opti, boolean dumpConstants, boolean dumpHistory,
2469             boolean dumpAll, @Nullable String dumpPackage, @Nullable String dumpIntentAction,
2470             boolean needSep) {
2471         final long now = SystemClock.uptimeMillis();
2472         final IndentingPrintWriter ipw = new IndentingPrintWriter(pw);
2473         ipw.increaseIndent();
2474         ipw.println();
2475 
2476         if (dumpIntentAction == null) {
2477             dumpProcessQueues(ipw, now);
2478             dumpBroadcastsWithIgnoredPolicies(ipw);
2479             dumpForegroundUids(ipw);
2480 
2481             if (dumpConstants) {
2482                 mFgConstants.dump(ipw);
2483                 mBgConstants.dump(ipw);
2484             }
2485         }
2486 
2487         if (dumpHistory) {
2488             final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
2489             needSep = mHistory.dumpLocked(ipw, dumpPackage, dumpIntentAction,
2490                     sdf, dumpAll);
2491         }
2492         return needSep;
2493     }
2494 
dumpProcessQueues(@onNull IndentingPrintWriter ipw, @UptimeMillisLong long now)2495     private void dumpProcessQueues(@NonNull IndentingPrintWriter ipw, @UptimeMillisLong long now) {
2496         ipw.println("�� Per-process queues:");
2497         ipw.increaseIndent();
2498         for (int i = 0; i < mProcessQueues.size(); i++) {
2499             BroadcastProcessQueue leaf = mProcessQueues.valueAt(i);
2500             while (leaf != null) {
2501                 leaf.dumpLocked(now, ipw);
2502                 leaf = leaf.processNameNext;
2503             }
2504         }
2505         ipw.decreaseIndent();
2506         ipw.println();
2507 
2508         ipw.println("�� Runnable:");
2509         ipw.increaseIndent();
2510         if (mRunnableHead == null) {
2511             ipw.println("(none)");
2512         } else {
2513             BroadcastProcessQueue queue = mRunnableHead;
2514             while (queue != null) {
2515                 TimeUtils.formatDuration(queue.getRunnableAt(), now, ipw);
2516                 ipw.print(' ');
2517                 ipw.print(reasonToString(queue.getRunnableAtReason()));
2518                 ipw.print(' ');
2519                 ipw.print(queue.toShortString());
2520                 ipw.println();
2521                 queue = queue.runnableAtNext;
2522             }
2523         }
2524         ipw.decreaseIndent();
2525         ipw.println();
2526 
2527         ipw.println("�� Running:");
2528         ipw.increaseIndent();
2529         for (BroadcastProcessQueue queue : mRunning) {
2530             if ((queue != null) && (queue == mRunningColdStart)) {
2531                 ipw.print("�� ");
2532             } else {
2533                 ipw.print("\u3000 ");
2534             }
2535             if (queue != null) {
2536                 ipw.println(queue.toShortString());
2537             } else {
2538                 ipw.println("(none)");
2539             }
2540         }
2541         ipw.decreaseIndent();
2542         ipw.println();
2543     }
2544 
dumpBroadcastsWithIgnoredPolicies(@onNull IndentingPrintWriter ipw)2545     private void dumpBroadcastsWithIgnoredPolicies(@NonNull IndentingPrintWriter ipw) {
2546         ipw.println("Broadcasts with ignored delivery group policies:");
2547         ipw.increaseIndent();
2548         mService.dumpDeliveryGroupPolicyIgnoredActions(ipw);
2549         ipw.decreaseIndent();
2550         ipw.println();
2551     }
2552 
dumpForegroundUids(@onNull IndentingPrintWriter ipw)2553     private void dumpForegroundUids(@NonNull IndentingPrintWriter ipw) {
2554         ipw.println("Foreground UIDs:");
2555         ipw.increaseIndent();
2556         ipw.println(mUidForeground);
2557         ipw.decreaseIndent();
2558         ipw.println();
2559     }
2560 }
2561