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