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