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