1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.am; 18 19 import static android.app.ActivityManager.PROCESS_STATE_UNKNOWN; 20 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_FINISH_RECEIVER; 21 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_START_RECEIVER; 22 import static android.os.UserHandle.USER_SYSTEM; 23 24 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; 25 import static com.android.server.am.ActivityManagerDebugConfig.LOG_WRITER_INFO; 26 import static com.android.server.am.BroadcastProcessQueue.reasonToString; 27 import static com.android.server.am.BroadcastRecord.deliveryStateToString; 28 import static com.android.server.am.BroadcastRecord.isReceiverEquals; 29 30 import static com.google.common.truth.Truth.assertThat; 31 32 import static org.junit.Assert.assertEquals; 33 import static org.junit.Assert.assertFalse; 34 import static org.junit.Assert.assertNotEquals; 35 import static org.junit.Assert.assertNotNull; 36 import static org.junit.Assert.assertNull; 37 import static org.junit.Assert.assertTrue; 38 import static org.junit.Assert.fail; 39 import static org.mockito.ArgumentMatchers.any; 40 import static org.mockito.ArgumentMatchers.anyBoolean; 41 import static org.mockito.ArgumentMatchers.anyInt; 42 import static org.mockito.ArgumentMatchers.anyLong; 43 import static org.mockito.ArgumentMatchers.argThat; 44 import static org.mockito.ArgumentMatchers.eq; 45 import static org.mockito.ArgumentMatchers.same; 46 import static org.mockito.Mockito.atLeastOnce; 47 import static org.mockito.Mockito.doAnswer; 48 import static org.mockito.Mockito.doNothing; 49 import static org.mockito.Mockito.inOrder; 50 import static org.mockito.Mockito.mock; 51 import static org.mockito.Mockito.never; 52 import static org.mockito.Mockito.spy; 53 import static org.mockito.Mockito.times; 54 import static org.mockito.Mockito.verify; 55 56 import android.annotation.NonNull; 57 import android.annotation.Nullable; 58 import android.app.Activity; 59 import android.app.ActivityManager; 60 import android.app.AppOpsManager; 61 import android.app.ApplicationExitInfo; 62 import android.app.BackgroundStartPrivileges; 63 import android.app.BroadcastOptions; 64 import android.app.IApplicationThread; 65 import android.app.UidObserver; 66 import android.app.usage.UsageEvents.Event; 67 import android.content.ComponentName; 68 import android.content.IIntentReceiver; 69 import android.content.Intent; 70 import android.content.pm.ApplicationInfo; 71 import android.content.pm.PackageManager; 72 import android.content.pm.ResolveInfo; 73 import android.os.Binder; 74 import android.os.Bundle; 75 import android.os.DeadObjectException; 76 import android.os.IBinder; 77 import android.os.PowerExemptionManager; 78 import android.os.SystemClock; 79 import android.os.UserHandle; 80 import android.platform.test.annotations.DisableFlags; 81 import android.platform.test.annotations.EnableFlags; 82 import android.platform.test.annotations.RequiresFlagsEnabled; 83 import android.util.ArrayMap; 84 import android.util.Log; 85 import android.util.Pair; 86 import android.util.proto.ProtoOutputStream; 87 88 import androidx.test.filters.MediumTest; 89 import androidx.test.platform.app.InstrumentationRegistry; 90 91 import org.junit.After; 92 import org.junit.Before; 93 import org.junit.Test; 94 import org.mockito.ArgumentMatcher; 95 import org.mockito.InOrder; 96 import org.mockito.verification.VerificationMode; 97 98 import java.io.FileDescriptor; 99 import java.io.PrintWriter; 100 import java.io.Writer; 101 import java.util.ArrayList; 102 import java.util.Arrays; 103 import java.util.HashMap; 104 import java.util.List; 105 import java.util.Map; 106 import java.util.Objects; 107 import java.util.Set; 108 import java.util.concurrent.CountDownLatch; 109 import java.util.concurrent.atomic.AtomicReference; 110 import java.util.function.UnaryOperator; 111 112 /** 113 * Common tests for {@link BroadcastQueue} implementations. 114 */ 115 @MediumTest 116 @SuppressWarnings("GuardedBy") 117 public class BroadcastQueueTest extends BaseBroadcastQueueTest { 118 private static final String TAG = "BroadcastQueueTest"; 119 120 private BroadcastQueue mQueue; 121 private UidObserver mUidObserver; 122 123 /** 124 * Desired behavior of the next 125 * {@link ActivityManagerService#startProcessLocked} call. 126 */ 127 private AtomicReference<ProcessStartBehavior> mNextProcessStartBehavior = new AtomicReference<>( 128 ProcessStartBehavior.SUCCESS); 129 130 /** 131 * Map of processes to behaviors indicating how the new processes should behave as needed 132 * by the tests. 133 */ 134 private ArrayMap<String, ProcessBehavior> mNewProcessBehaviors = new ArrayMap<>(); 135 136 /** 137 * Map of processes to behaviors indicating how the new process starts should result in. 138 */ 139 private ArrayMap<String, ProcessStartBehavior> mNewProcessStartBehaviors = new ArrayMap<>(); 140 141 /** 142 * Collection of all active processes during current test run. 143 */ 144 private List<ProcessRecord> mActiveProcesses = new ArrayList<>(); 145 146 /** 147 * Collection of scheduled broadcasts, in the order they were dispatched. 148 */ 149 private List<Pair<Integer, String>> mScheduledBroadcasts = new ArrayList<>(); 150 151 @Before setUp()152 public void setUp() throws Exception { 153 super.setUp(); 154 155 doAnswer((invocation) -> { 156 Log.v(TAG, "Intercepting startProcessLocked() for " 157 + Arrays.toString(invocation.getArguments())); 158 final String processName = invocation.getArgument(0); 159 final ProcessStartBehavior behavior = mNewProcessStartBehaviors.getOrDefault( 160 processName, mNextProcessStartBehavior.getAndSet(ProcessStartBehavior.SUCCESS)); 161 if (behavior == ProcessStartBehavior.FAIL_NULL) { 162 return null; 163 } 164 final ApplicationInfo ai = invocation.getArgument(1); 165 final ProcessBehavior processBehavior = mNewProcessBehaviors.getOrDefault( 166 processName, ProcessBehavior.NORMAL); 167 final ProcessRecord res = makeActiveProcessRecord(ai, processName, 168 processBehavior, UnaryOperator.identity()); 169 final ProcessRecord deliverRes; 170 switch (behavior) { 171 case SUCCESS_PREDECESSOR: 172 case FAIL_TIMEOUT_PREDECESSOR: 173 // Create a different process that will be linked to the 174 // returned process via a predecessor/successor relationship 175 mActiveProcesses.remove(res); 176 res.setKilled(true); 177 deliverRes = makeActiveProcessRecord(ai, processName, 178 ProcessBehavior.NORMAL, UnaryOperator.identity()); 179 deliverRes.mPredecessor = res; 180 res.mSuccessor = deliverRes; 181 break; 182 default: 183 deliverRes = res; 184 break; 185 } 186 res.setPendingStart(true); 187 mHandlerThread.getThreadHandler().post(() -> { 188 res.setPendingStart(false); 189 synchronized (mAms) { 190 switch (behavior) { 191 case SUCCESS: 192 case SUCCESS_PREDECESSOR: 193 try { 194 mQueue.onApplicationAttachedLocked(deliverRes); 195 } catch (BroadcastDeliveryFailedException e) { 196 Log.v(TAG, "Error while invoking onApplicationAttachedLocked", e); 197 } 198 break; 199 case FAIL_TIMEOUT: 200 case FAIL_TIMEOUT_PREDECESSOR: 201 mActiveProcesses.remove(deliverRes); 202 mQueue.onApplicationTimeoutLocked(deliverRes); 203 break; 204 case KILLED_WITHOUT_NOTIFY: 205 mActiveProcesses.remove(res); 206 res.setKilled(true); 207 break; 208 case MISSING_RESPONSE: 209 res.setPendingStart(true); 210 break; 211 default: 212 throw new UnsupportedOperationException(); 213 } 214 } 215 }); 216 return res; 217 }).when(mAms).startProcessLocked(any(), any(), anyBoolean(), anyInt(), 218 any(), anyInt(), anyBoolean(), anyBoolean()); 219 220 doAnswer((invocation) -> { 221 final String processName = invocation.getArgument(0); 222 final int uid = invocation.getArgument(1); 223 for (ProcessRecord r : mActiveProcesses) { 224 if (Objects.equals(r.processName, processName) && r.uid == uid) { 225 return r; 226 } 227 } 228 return null; 229 }).when(mAms).getProcessRecordLocked(any(), anyInt()); 230 doNothing().when(mAms).appNotResponding(any(), any()); 231 232 doAnswer((invocation) -> { 233 mUidObserver = invocation.getArgument(0); 234 return null; 235 }).when(mAms).registerUidObserver(any(), anyInt(), 236 eq(ActivityManager.PROCESS_STATE_TOP), any()); 237 238 mQueue = new BroadcastQueueImpl(mAms, mHandlerThread.getThreadHandler(), 239 mConstants, mConstants, mSkipPolicy, mEmptyHistory); 240 mAms.setBroadcastQueueForTest(mQueue); 241 mQueue.start(mContext.getContentResolver()); 242 243 // Set the constants after invoking BroadcastQueue.start() to ensure they don't 244 // get overridden by the defaults. 245 mConstants.TIMEOUT = 200; 246 mConstants.ALLOW_BG_ACTIVITY_START_TIMEOUT = 0; 247 mConstants.PENDING_COLD_START_CHECK_INTERVAL_MILLIS = 500; 248 mConstants.MAX_FROZEN_OUTGOING_BROADCASTS = 10; 249 mConstants.PENDING_COLD_START_ABANDON_TIMEOUT_MILLIS = 2000; 250 } 251 252 @After tearDown()253 public void tearDown() throws Exception { 254 super.tearDown(); 255 256 // Verify that all processes have finished handling broadcasts 257 for (ProcessRecord app : mActiveProcesses) { 258 assertEquals(app.toShortString(), 0, 259 app.mReceivers.numberOfCurReceivers()); 260 assertEquals(app.toShortString(), ProcessList.SCHED_GROUP_UNDEFINED, 261 mQueue.getPreferredSchedulingGroupLocked(app)); 262 } 263 mNewProcessBehaviors.clear(); 264 mNewProcessStartBehaviors.clear(); 265 } 266 267 @Override getTag()268 public String getTag() { 269 return TAG; 270 } 271 272 private enum ProcessStartBehavior { 273 /** Process starts successfully */ 274 SUCCESS, 275 /** Process starts successfully via predecessor */ 276 SUCCESS_PREDECESSOR, 277 /** Process fails by reporting timeout */ 278 FAIL_TIMEOUT, 279 /** Process fails by reporting timeout via predecessor */ 280 FAIL_TIMEOUT_PREDECESSOR, 281 /** Process fails by immediately returning null */ 282 FAIL_NULL, 283 /** Process is killed without reporting to BroadcastQueue */ 284 KILLED_WITHOUT_NOTIFY, 285 /** Process start fails without no response */ 286 MISSING_RESPONSE, 287 } 288 289 private enum ProcessBehavior { 290 /** Process broadcasts normally */ 291 NORMAL, 292 /** Wedge and never confirm broadcast receipt */ 293 WEDGE, 294 /** Process broadcast by requesting abort */ 295 ABORT, 296 /** Appear to behave completely dead */ 297 DEAD, 298 } 299 makeActiveProcessRecord(String packageName)300 private ProcessRecord makeActiveProcessRecord(String packageName) throws Exception { 301 return makeActiveProcessRecord(packageName, packageName, ProcessBehavior.NORMAL, 302 UserHandle.USER_SYSTEM); 303 } 304 makeActiveProcessRecord(String packageName, String processName)305 private ProcessRecord makeActiveProcessRecord(String packageName, String processName) 306 throws Exception { 307 return makeActiveProcessRecord(packageName, processName, ProcessBehavior.NORMAL, 308 UserHandle.USER_SYSTEM); 309 } 310 makeActiveProcessRecord(String packageName, ProcessBehavior behavior)311 private ProcessRecord makeActiveProcessRecord(String packageName, 312 ProcessBehavior behavior) throws Exception { 313 return makeActiveProcessRecord(packageName, packageName, behavior, UserHandle.USER_SYSTEM); 314 } 315 makeActiveProcessRecord(String packageName, String processName, ProcessBehavior behavior, int userId)316 private ProcessRecord makeActiveProcessRecord(String packageName, String processName, 317 ProcessBehavior behavior, int userId) throws Exception { 318 final ApplicationInfo ai = makeApplicationInfo(packageName, processName, userId); 319 return makeActiveProcessRecord(ai, ai.processName, behavior, 320 UnaryOperator.identity()); 321 } 322 makeActiveProcessRecord(ApplicationInfo ai, String processName, ProcessBehavior behavior, UnaryOperator<Bundle> extrasOperator)323 private ProcessRecord makeActiveProcessRecord(ApplicationInfo ai, String processName, 324 ProcessBehavior behavior, UnaryOperator<Bundle> extrasOperator) throws Exception { 325 final boolean wedge = (behavior == ProcessBehavior.WEDGE); 326 final boolean abort = (behavior == ProcessBehavior.ABORT); 327 final boolean dead = (behavior == ProcessBehavior.DEAD); 328 329 final ProcessRecord r = spy(new ProcessRecord(mAms, ai, processName, ai.uid)); 330 r.mState = spy(r.mState); 331 r.setPid(mNextPid.getAndIncrement()); 332 ProcessRecord.updateProcessRecordNodes(r); 333 mActiveProcesses.add(r); 334 335 final ApplicationThreadDeferred thread; 336 if (dead) { 337 thread = mock(ApplicationThreadDeferred.class, (invocation) -> { 338 throw new DeadObjectException(); 339 }); 340 } else { 341 thread = mock(ApplicationThreadDeferred.class); 342 } 343 final IBinder threadBinder = new Binder(); 344 doReturn(threadBinder).when(thread).asBinder(); 345 r.makeActive(thread, mAms.mProcessStats); 346 347 final IIntentReceiver receiver = mock(IIntentReceiver.class); 348 final IBinder receiverBinder = new Binder(); 349 doReturn(receiverBinder).when(receiver).asBinder(); 350 final ReceiverList receiverList = new ReceiverList(mAms, r, r.getPid(), r.info.uid, 351 UserHandle.getUserId(r.info.uid), receiver); 352 mRegisteredReceivers.put(r.getPid(), receiverList); 353 354 doReturn(42L).when(r).getCpuDelayTime(); 355 356 doAnswer((invocation) -> { 357 Log.v(TAG, "Intercepting killLocked() for " 358 + Arrays.toString(invocation.getArguments())); 359 mActiveProcesses.remove(r); 360 mRegisteredReceivers.remove(r.getPid()); 361 return invocation.callRealMethod(); 362 }).when(r).killLocked(any(), any(), anyInt(), anyInt(), anyBoolean(), anyBoolean()); 363 364 // If we're entirely dead, rely on default behaviors above 365 if (dead) return r; 366 367 doAnswer((invocation) -> { 368 Log.v(TAG, "Intercepting scheduleReceiver() for " 369 + Arrays.toString(invocation.getArguments()) + " package " + ai.packageName); 370 assertHealth(); 371 final Intent intent = invocation.getArgument(0); 372 final Bundle extras = invocation.getArgument(5); 373 mScheduledBroadcasts.add(makeScheduledBroadcast(r, intent)); 374 if (!wedge) { 375 assertTrue(r.mReceivers.numberOfCurReceivers() > 0); 376 assertNotEquals(ProcessList.SCHED_GROUP_UNDEFINED, 377 mQueue.getPreferredSchedulingGroupLocked(r)); 378 mHandlerThread.getThreadHandler().post(() -> { 379 synchronized (mAms) { 380 mQueue.finishReceiverLocked(r, Activity.RESULT_OK, null, 381 extrasOperator.apply(extras), abort, false); 382 } 383 }); 384 } 385 return null; 386 }).when(thread).scheduleReceiver(any(), any(), any(), anyInt(), any(), any(), anyBoolean(), 387 anyBoolean(), anyInt(), anyInt(), anyInt(), any()); 388 389 doAnswer((invocation) -> { 390 Log.v(TAG, "Intercepting scheduleRegisteredReceiver() for " 391 + Arrays.toString(invocation.getArguments()) + " package " + ai.packageName); 392 assertHealth(); 393 final Intent intent = invocation.getArgument(1); 394 final Bundle extras = invocation.getArgument(4); 395 final boolean ordered = invocation.getArgument(5); 396 mScheduledBroadcasts.add(makeScheduledBroadcast(r, intent)); 397 if (!wedge && ordered) { 398 assertTrue(r.mReceivers.numberOfCurReceivers() > 0); 399 assertNotEquals(ProcessList.SCHED_GROUP_UNDEFINED, 400 mQueue.getPreferredSchedulingGroupLocked(r)); 401 mHandlerThread.getThreadHandler().post(() -> { 402 synchronized (mAms) { 403 mQueue.finishReceiverLocked(r, Activity.RESULT_OK, 404 null, extrasOperator.apply(extras), abort, false); 405 } 406 }); 407 } 408 return null; 409 }).when(thread).scheduleRegisteredReceiver(any(), any(), anyInt(), any(), any(), 410 anyBoolean(), anyBoolean(), anyBoolean(), anyInt(), anyInt(), anyInt(), any()); 411 412 return r; 413 } 414 makeScheduledBroadcast(ProcessRecord app, Intent intent)415 private Pair<Integer, String> makeScheduledBroadcast(ProcessRecord app, Intent intent) { 416 return Pair.create(app.getPid(), intent.getAction()); 417 } 418 makeBroadcastRecord(Intent intent, ProcessRecord callerApp, List<Object> receivers)419 private BroadcastRecord makeBroadcastRecord(Intent intent, ProcessRecord callerApp, 420 List<Object> receivers) { 421 return makeBroadcastRecord(intent, callerApp, BroadcastOptions.makeBasic(), 422 receivers, false, null, null, UserHandle.USER_SYSTEM); 423 } 424 makeBroadcastRecord(Intent intent, ProcessRecord callerApp, int userId, List<Object> receivers)425 private BroadcastRecord makeBroadcastRecord(Intent intent, ProcessRecord callerApp, 426 int userId, List<Object> receivers) { 427 return makeBroadcastRecord(intent, callerApp, BroadcastOptions.makeBasic(), 428 receivers, false, null, null, userId); 429 } 430 makeBroadcastRecord(Intent intent, ProcessRecord callerApp, BroadcastOptions options, List<Object> receivers)431 private BroadcastRecord makeBroadcastRecord(Intent intent, ProcessRecord callerApp, 432 BroadcastOptions options, List<Object> receivers) { 433 return makeBroadcastRecord(intent, callerApp, options, 434 receivers, false, null, null, UserHandle.USER_SYSTEM); 435 } 436 makeBroadcastRecord(Intent intent, ProcessRecord callerApp, List<Object> receivers, IIntentReceiver resultTo)437 private BroadcastRecord makeBroadcastRecord(Intent intent, ProcessRecord callerApp, 438 List<Object> receivers, IIntentReceiver resultTo) { 439 return makeBroadcastRecord(intent, callerApp, BroadcastOptions.makeBasic(), 440 receivers, false, resultTo, null, UserHandle.USER_SYSTEM); 441 } 442 makeOrderedBroadcastRecord(Intent intent, ProcessRecord callerApp, List<Object> receivers, IIntentReceiver resultTo, Bundle resultExtras)443 private BroadcastRecord makeOrderedBroadcastRecord(Intent intent, ProcessRecord callerApp, 444 List<Object> receivers, IIntentReceiver resultTo, Bundle resultExtras) { 445 return makeBroadcastRecord(intent, callerApp, BroadcastOptions.makeBasic(), 446 receivers, true, resultTo, resultExtras, UserHandle.USER_SYSTEM); 447 } 448 makeBroadcastRecord(Intent intent, ProcessRecord callerApp, BroadcastOptions options, List<Object> receivers, boolean ordered, IIntentReceiver resultTo, Bundle resultExtras, int userId)449 private BroadcastRecord makeBroadcastRecord(Intent intent, ProcessRecord callerApp, 450 BroadcastOptions options, List<Object> receivers, boolean ordered, 451 IIntentReceiver resultTo, Bundle resultExtras, int userId) { 452 return new BroadcastRecord(mQueue, intent, callerApp, callerApp.info.packageName, null, 453 callerApp.getPid(), callerApp.info.uid, false, null, null, null, null, 454 AppOpsManager.OP_NONE, options, receivers, callerApp, resultTo, 455 Activity.RESULT_OK, null, resultExtras, ordered, false, false, userId, 456 BackgroundStartPrivileges.NONE, false, null, PROCESS_STATE_UNKNOWN, 457 mPlatformCompat); 458 } 459 assertHealth()460 private void assertHealth() { 461 // If this fails, it'll throw a clear reason message 462 ((BroadcastQueueImpl) mQueue).assertHealthLocked(); 463 } 464 asMap(Bundle bundle)465 private static Map<String, Object> asMap(Bundle bundle) { 466 final Map<String, Object> map = new HashMap<>(); 467 if (bundle != null) { 468 for (String key : bundle.keySet()) { 469 map.put(key, bundle.get(key)); 470 } 471 } 472 return map; 473 } 474 componentEquals(String packageName, String className)475 private ArgumentMatcher<Intent> componentEquals(String packageName, String className) { 476 return (test) -> { 477 final ComponentName cn = test.getComponent(); 478 return (cn != null) 479 && Objects.equals(cn.getPackageName(), packageName) 480 && Objects.equals(cn.getClassName(), className); 481 }; 482 } 483 filterAndExtrasEquals(Intent intent)484 private ArgumentMatcher<Intent> filterAndExtrasEquals(Intent intent) { 485 return (test) -> { 486 return intent.filterEquals(test) 487 && Objects.equals(asMap(intent.getExtras()), asMap(test.getExtras())); 488 }; 489 } 490 491 private ArgumentMatcher<Intent> filterEquals(Intent intent) { 492 return (test) -> { 493 return intent.filterEquals(test); 494 }; 495 } 496 497 private ArgumentMatcher<Intent> filterEqualsIgnoringComponent(Intent intent) { 498 final Intent intentClean = new Intent(intent); 499 intentClean.setComponent(null); 500 return (test) -> { 501 final Intent testClean = new Intent(test); 502 testClean.setComponent(null); 503 return intentClean.filterEquals(testClean); 504 }; 505 } 506 507 private ArgumentMatcher<Bundle> bundleEquals(Bundle bundle) { 508 return (test) -> { 509 // TODO: check values in addition to keys 510 return Objects.equals(test.keySet(), bundle.keySet()); 511 }; 512 } 513 514 private @NonNull Bundle clone(@Nullable Bundle b) { 515 return (b != null) ? new Bundle(b) : new Bundle(); 516 } 517 518 private void enqueueBroadcast(BroadcastRecord r) { 519 synchronized (mAms) { 520 mQueue.enqueueBroadcastLocked(r); 521 } 522 } 523 524 /** 525 * Un-pause our handler to process pending events, wait for our queue to go 526 * idle, and then re-pause the handler. 527 */ 528 private void waitForIdle() throws Exception { 529 mLooper.release(); 530 mQueue.waitForIdle(LOG_WRITER_INFO); 531 final CountDownLatch latch = new CountDownLatch(1); 532 mHandlerThread.getThreadHandler().post(latch::countDown); 533 latch.await(); 534 mLooper = Objects.requireNonNull(InstrumentationRegistry.getInstrumentation() 535 .acquireLooperManager(mHandlerThread.getLooper())); 536 } 537 538 private void verifyScheduleReceiver(ProcessRecord app, Intent intent) throws Exception { 539 verifyScheduleReceiver(times(1), app, intent, UserHandle.USER_SYSTEM); 540 } 541 542 private void verifyScheduleReceiver(VerificationMode mode, ProcessRecord app, Intent intent) 543 throws Exception { 544 verifyScheduleReceiver(mode, app, intent, UserHandle.USER_SYSTEM); 545 } 546 547 private void verifyScheduleReceiver(VerificationMode mode, ProcessRecord app, Intent intent, 548 ComponentName component) throws Exception { 549 final Intent targetedIntent = new Intent(intent); 550 targetedIntent.setComponent(component); 551 verify(app.getThread(), mode).scheduleReceiver( 552 argThat(filterEquals(targetedIntent)), any(), any(), 553 anyInt(), any(), any(), eq(false), anyBoolean(), eq(UserHandle.USER_SYSTEM), 554 anyInt(), anyInt(), any()); 555 } 556 557 private void verifyScheduleReceiver(VerificationMode mode, ProcessRecord app, 558 Intent intent, int userId) throws Exception { 559 verify(app.getThread(), mode).scheduleReceiver( 560 argThat(filterEqualsIgnoringComponent(intent)), any(), any(), 561 anyInt(), any(), any(), anyBoolean(), anyBoolean(), eq(userId), 562 anyInt(), anyInt(), any()); 563 } 564 565 private void verifyScheduleReceiver(VerificationMode mode, ProcessRecord app, 566 int userId) throws Exception { 567 verify(app.getThread(), mode).scheduleReceiver( 568 any(), any(), any(), 569 anyInt(), any(), any(), anyBoolean(), anyBoolean(), eq(userId), 570 anyInt(), anyInt(), any()); 571 } 572 573 private void verifyScheduleRegisteredReceiver(ProcessRecord app, Intent intent) 574 throws Exception { 575 verifyScheduleRegisteredReceiver(times(1), app, intent, UserHandle.USER_SYSTEM); 576 } 577 578 private void verifyScheduleRegisteredReceiver(VerificationMode mode, ProcessRecord app, 579 Intent intent) throws Exception { 580 verifyScheduleRegisteredReceiver(mode, app, intent, UserHandle.USER_SYSTEM); 581 } 582 583 private void verifyScheduleRegisteredReceiver(VerificationMode mode, ProcessRecord app, 584 Intent intent, int userId) throws Exception { 585 verify(app.getThread(), mode).scheduleRegisteredReceiver( 586 any(), argThat(filterEqualsIgnoringComponent(intent)), 587 anyInt(), any(), any(), anyBoolean(), anyBoolean(), anyBoolean(), 588 eq(userId), anyInt(), anyInt(), any()); 589 } 590 591 private void verifyScheduleRegisteredReceiver(VerificationMode mode, ProcessRecord app, 592 int userId) throws Exception { 593 verify(app.getThread(), mode).scheduleRegisteredReceiver( 594 any(), any(), 595 anyInt(), any(), any(), anyBoolean(), anyBoolean(), anyBoolean(), 596 eq(userId), anyInt(), anyInt(), any()); 597 } 598 599 /** 600 * Baseline verification of common debugging infrastructure, mostly to make 601 * sure it doesn't crash. 602 */ 603 @Test 604 public void testDebugging() throws Exception { 605 // To maximize test coverage, dump current state; we're not worried 606 // about the actual output, just that we don't crash 607 mQueue.dumpDebug(new ProtoOutputStream(), 608 ActivityManagerServiceDumpBroadcastsProto.BROADCAST_QUEUE); 609 mQueue.dumpLocked(FileDescriptor.err, new PrintWriter(Writer.nullWriter()), 610 null, 0, true, true, true, null, null, false); 611 mQueue.dumpToDropBoxLocked(TAG); 612 613 BroadcastQueue.logv(TAG); 614 BroadcastQueue.logw(TAG); 615 616 assertNotNull(mQueue.toString()); 617 assertNotNull(mQueue.describeStateLocked()); 618 619 for (int i = Byte.MIN_VALUE; i < Byte.MAX_VALUE; i++) { 620 assertNotNull(deliveryStateToString(i)); 621 assertNotNull(reasonToString(i)); 622 } 623 } 624 625 /** 626 * Verify dispatch of simple broadcast to single manifest receiver in 627 * already-running warm app. 628 */ 629 @Test 630 public void testSimple_Manifest_Warm() throws Exception { 631 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 632 final ProcessRecord receiverApp = makeActiveProcessRecord(PACKAGE_GREEN); 633 634 final Intent intent = new Intent(Intent.ACTION_TIMEZONE_CHANGED); 635 enqueueBroadcast(makeBroadcastRecord(intent, callerApp, 636 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN)))); 637 638 waitForIdle(); 639 verifyScheduleReceiver(receiverApp, intent); 640 } 641 642 /** 643 * Verify dispatch of multiple broadcasts to multiple manifest receivers in 644 * already-running warm apps. 645 */ 646 @Test 647 public void testSimple_Manifest_Warm_Multiple() throws Exception { 648 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 649 650 final ProcessRecord receiverGreenApp = makeActiveProcessRecord(PACKAGE_GREEN); 651 final ProcessRecord receiverBlueApp = makeActiveProcessRecord(PACKAGE_BLUE); 652 653 final Intent timezone = new Intent(Intent.ACTION_TIMEZONE_CHANGED); 654 enqueueBroadcast(makeBroadcastRecord(timezone, callerApp, 655 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN), 656 makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE)))); 657 658 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 659 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, 660 List.of(makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE)))); 661 662 waitForIdle(); 663 verifyScheduleReceiver(receiverGreenApp, timezone); 664 verifyScheduleReceiver(receiverBlueApp, timezone); 665 verifyScheduleReceiver(receiverBlueApp, airplane); 666 } 667 668 /** 669 * Verify dispatch of multiple broadcast to multiple manifest receivers in 670 * apps that require cold starts. 671 */ 672 @Test 673 public void testSimple_Manifest_ColdThenWarm() throws Exception { 674 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 675 676 // We purposefully dispatch into green twice; the first time cold and 677 // the second time it should already be running 678 679 final Intent timezone = new Intent(Intent.ACTION_TIMEZONE_CHANGED); 680 enqueueBroadcast(makeBroadcastRecord(timezone, callerApp, 681 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN), 682 makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE)))); 683 684 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 685 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, 686 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN)))); 687 688 waitForIdle(); 689 final ProcessRecord receiverGreenApp = mAms.getProcessRecordLocked(PACKAGE_GREEN, 690 getUidForPackage(PACKAGE_GREEN)); 691 final ProcessRecord receiverBlueApp = mAms.getProcessRecordLocked(PACKAGE_BLUE, 692 getUidForPackage(PACKAGE_BLUE)); 693 verifyScheduleReceiver(receiverGreenApp, timezone); 694 verifyScheduleReceiver(receiverGreenApp, airplane); 695 verifyScheduleReceiver(receiverBlueApp, timezone); 696 } 697 698 /** 699 * Verify dispatch of simple broadcast to single registered receiver in 700 * already-running warm app. 701 */ 702 @Test 703 public void testSimple_Registered() throws Exception { 704 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 705 final ProcessRecord receiverApp = makeActiveProcessRecord(PACKAGE_GREEN); 706 707 final Intent intent = new Intent(Intent.ACTION_TIMEZONE_CHANGED); 708 enqueueBroadcast(makeBroadcastRecord(intent, callerApp, 709 List.of(makeRegisteredReceiver(receiverApp)))); 710 711 waitForIdle(); 712 verifyScheduleRegisteredReceiver(receiverApp, intent); 713 } 714 715 /** 716 * Verify dispatch of multiple broadcasts to multiple registered receivers 717 * in already-running warm apps. 718 */ 719 @Test 720 public void testSimple_Registered_Multiple() throws Exception { 721 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 722 723 final ProcessRecord receiverGreenApp = makeActiveProcessRecord(PACKAGE_GREEN); 724 final ProcessRecord receiverBlueApp = makeActiveProcessRecord(PACKAGE_BLUE); 725 726 final Intent timezone = new Intent(Intent.ACTION_TIMEZONE_CHANGED); 727 enqueueBroadcast(makeBroadcastRecord(timezone, callerApp, 728 List.of(makeRegisteredReceiver(receiverGreenApp), 729 makeRegisteredReceiver(receiverBlueApp)))); 730 731 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 732 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, 733 List.of(makeRegisteredReceiver(receiverBlueApp)))); 734 735 waitForIdle(); 736 verifyScheduleRegisteredReceiver(receiverGreenApp, timezone); 737 verifyScheduleRegisteredReceiver(receiverBlueApp, timezone); 738 verifyScheduleRegisteredReceiver(receiverBlueApp, airplane); 739 } 740 741 /** 742 * Verify dispatch of multiple broadcasts mixed to both manifest and 743 * registered receivers, to both warm and cold apps. 744 */ 745 @Test 746 public void testComplex() throws Exception { 747 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 748 749 final ProcessRecord receiverGreenApp = makeActiveProcessRecord(PACKAGE_GREEN); 750 final ProcessRecord receiverYellowApp = makeActiveProcessRecord(PACKAGE_YELLOW); 751 752 final Intent timezone = new Intent(Intent.ACTION_TIMEZONE_CHANGED); 753 enqueueBroadcast(makeBroadcastRecord(timezone, callerApp, 754 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN), 755 makeRegisteredReceiver(receiverGreenApp), 756 makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE), 757 makeRegisteredReceiver(receiverYellowApp)))); 758 759 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 760 airplane.setComponent(new ComponentName(PACKAGE_YELLOW, CLASS_YELLOW)); 761 final BroadcastOptions options = BroadcastOptions.makeBasic(); 762 options.recordResponseEventWhileInBackground(42L); 763 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, options, 764 List.of(makeManifestReceiver(PACKAGE_YELLOW, CLASS_YELLOW)))); 765 766 waitForIdle(); 767 final ProcessRecord receiverBlueApp = mAms.getProcessRecordLocked(PACKAGE_BLUE, 768 getUidForPackage(PACKAGE_BLUE)); 769 verifyScheduleReceiver(receiverGreenApp, timezone); 770 verifyScheduleRegisteredReceiver(receiverGreenApp, timezone); 771 verifyScheduleReceiver(receiverBlueApp, timezone); 772 verifyScheduleRegisteredReceiver(receiverYellowApp, timezone); 773 verifyScheduleReceiver(receiverYellowApp, airplane); 774 775 for (ProcessRecord receiverApp : new ProcessRecord[] { 776 receiverGreenApp, receiverBlueApp, receiverYellowApp 777 }) { 778 // Confirm expected OOM adjustments; we were invoked once to upgrade 779 // and once to downgrade 780 verify(receiverApp.mState, times(1).description(String.valueOf(receiverApp))) 781 .setReportedProcState(ActivityManager.PROCESS_STATE_RECEIVER); 782 verify(mAms, times(2)).enqueueOomAdjTargetLocked(eq(receiverApp)); 783 784 // Confirm that app was thawed 785 verify(mAms.mOomAdjuster, atLeastOnce()).unfreezeTemporarily( 786 eq(receiverApp), eq(OOM_ADJ_REASON_START_RECEIVER)); 787 788 // Confirm that we added package to process 789 verify(receiverApp, atLeastOnce()).addPackage(eq(receiverApp.info.packageName), 790 anyLong(), any()); 791 792 // Confirm that we've reported package as being used 793 verify(mAms, atLeastOnce()).notifyPackageUse(eq(receiverApp.info.packageName), 794 eq(PackageManager.NOTIFY_PACKAGE_USE_BROADCAST_RECEIVER)); 795 796 // Confirm that we unstopped manifest receivers 797 verify(mAms.mPackageManagerInt, atLeastOnce()).notifyComponentUsed( 798 eq(receiverApp.info.packageName), eq(UserHandle.USER_SYSTEM), 799 eq(callerApp.info.packageName), any()); 800 } 801 802 // Confirm that we've reported expected usage events 803 verify(mAms.mUsageStatsService).reportBroadcastDispatched(eq(callerApp.uid), 804 eq(PACKAGE_YELLOW), eq(UserHandle.SYSTEM), eq(42L), anyLong(), anyInt()); 805 verify(mAms.mUsageStatsService).reportEvent(eq(PACKAGE_YELLOW), eq(UserHandle.USER_SYSTEM), 806 eq(Event.APP_COMPONENT_USED)); 807 } 808 809 /** 810 * Verify that we detect and ANR a wedged process when delivering to a 811 * manifest receiver. 812 */ 813 @Test 814 public void testWedged_Manifest() throws Exception { 815 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 816 final ProcessRecord receiverApp = makeActiveProcessRecord(PACKAGE_GREEN, 817 ProcessBehavior.WEDGE); 818 819 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 820 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, 821 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN)))); 822 823 waitForIdle(); 824 verify(mAms).appNotResponding(eq(receiverApp), any()); 825 } 826 827 /** 828 * Verify that we detect and ANR a wedged process when delivering an ordered 829 * broadcast, and that we deliver final result. 830 */ 831 @Test 832 public void testWedged_Registered_Ordered() throws Exception { 833 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 834 final ProcessRecord receiverApp = makeActiveProcessRecord(PACKAGE_GREEN, 835 ProcessBehavior.WEDGE); 836 837 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 838 final IIntentReceiver resultTo = mock(IIntentReceiver.class); 839 enqueueBroadcast(makeOrderedBroadcastRecord(airplane, callerApp, 840 List.of(makeRegisteredReceiver(receiverApp)), resultTo, null)); 841 842 waitForIdle(); 843 verify(mAms).appNotResponding(eq(receiverApp), any()); 844 verifyScheduleRegisteredReceiver(callerApp, airplane); 845 } 846 847 /** 848 * Verify that we detect and ANR a wedged process when delivering an 849 * unordered broadcast with a {@code resultTo}. 850 */ 851 @Test 852 public void testWedged_Registered_ResultTo() throws Exception { 853 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 854 final ProcessRecord receiverApp = makeActiveProcessRecord(PACKAGE_GREEN, 855 ProcessBehavior.WEDGE); 856 857 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 858 final IIntentReceiver resultTo = mock(IIntentReceiver.class); 859 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, 860 List.of(makeRegisteredReceiver(receiverApp)), resultTo)); 861 862 waitForIdle(); 863 verify(mAms).appNotResponding(eq(receiverApp), any()); 864 verifyScheduleRegisteredReceiver(callerApp, airplane); 865 } 866 867 /** 868 * Verify that we handle registered receivers in a process that always 869 * responds with {@link DeadObjectException}, recovering to restart the 870 * process and deliver their next broadcast. 871 */ 872 @Test 873 public void testDead_Registered() throws Exception { 874 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 875 final ProcessRecord receiverApp = makeActiveProcessRecord(PACKAGE_GREEN, 876 ProcessBehavior.DEAD); 877 878 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 879 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, 880 List.of(makeRegisteredReceiver(receiverApp)))); 881 final Intent timezone = new Intent(Intent.ACTION_TIMEZONE_CHANGED); 882 enqueueBroadcast(makeBroadcastRecord(timezone, callerApp, 883 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN)))); 884 waitForIdle(); 885 886 // First broadcast should have already been dead 887 verifyScheduleRegisteredReceiver(receiverApp, airplane); 888 // The old receiverApp should be killed gently 889 assertTrue(receiverApp.isKilled()); 890 891 // Second broadcast in new process should work fine 892 final ProcessRecord restartedReceiverApp = mAms.getProcessRecordLocked(PACKAGE_GREEN, 893 getUidForPackage(PACKAGE_GREEN)); 894 assertNotEquals(receiverApp, restartedReceiverApp); 895 verifyScheduleReceiver(restartedReceiverApp, timezone); 896 } 897 898 /** 899 * Verify that we handle manifest receivers in a process that always 900 * responds with {@link DeadObjectException}, recovering to restart the 901 * process and deliver their next broadcast. 902 */ 903 @Test 904 public void testDead_Manifest() throws Exception { 905 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 906 final ProcessRecord receiverApp = makeActiveProcessRecord(PACKAGE_GREEN, 907 ProcessBehavior.DEAD); 908 909 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 910 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, 911 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN)))); 912 final Intent timezone = new Intent(Intent.ACTION_TIMEZONE_CHANGED); 913 enqueueBroadcast(makeBroadcastRecord(timezone, callerApp, 914 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN)))); 915 waitForIdle(); 916 917 // First broadcast should have already been dead 918 verifyScheduleReceiver(receiverApp, airplane); 919 // The old receiverApp should be killed gently 920 assertTrue(receiverApp.isKilled()); 921 922 // Second broadcast in new process should work fine 923 final ProcessRecord restartedReceiverApp = mAms.getProcessRecordLocked(PACKAGE_GREEN, 924 getUidForPackage(PACKAGE_GREEN)); 925 assertNotEquals(receiverApp, restartedReceiverApp); 926 verifyScheduleReceiver(restartedReceiverApp, airplane); 927 verifyScheduleReceiver(restartedReceiverApp, timezone); 928 } 929 930 /** 931 * Verify that we handle manifest receivers in a process that always 932 * responds with {@link DeadObjectException} even after restarting. 933 */ 934 @Test 935 @RequiresFlagsEnabled(Flags.FLAG_AVOID_REPEATED_BCAST_RE_ENQUEUES) 936 public void testRepeatedDead_Manifest() throws Exception { 937 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 938 mNewProcessBehaviors.put(PACKAGE_GREEN, ProcessBehavior.DEAD); 939 940 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 941 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, List.of( 942 withPriority(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN), 10), 943 withPriority(makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE), 0)))); 944 final Intent timezone = new Intent(Intent.ACTION_TIMEZONE_CHANGED); 945 enqueueBroadcast(makeBroadcastRecord(timezone, callerApp, 946 List.of(makeManifestReceiver(PACKAGE_YELLOW, CLASS_YELLOW)))); 947 waitForIdle(); 948 949 final ProcessRecord receiverGreenApp = mAms.getProcessRecordLocked(PACKAGE_GREEN, 950 getUidForPackage(PACKAGE_GREEN)); 951 // Broadcast queue always kills the target process when broadcast delivery fails. 952 assertNull(receiverGreenApp); 953 final ProcessRecord receiverBlueApp = mAms.getProcessRecordLocked(PACKAGE_BLUE, 954 getUidForPackage(PACKAGE_BLUE)); 955 verifyScheduleReceiver(receiverBlueApp, airplane); 956 final ProcessRecord receiverYellowApp = mAms.getProcessRecordLocked(PACKAGE_YELLOW, 957 getUidForPackage(PACKAGE_YELLOW)); 958 verifyScheduleReceiver(receiverYellowApp, timezone); 959 } 960 961 /** 962 * Verify that we handle the system failing to start a process. 963 */ 964 @Test 965 public void testFailStartProcess() throws Exception { 966 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 967 968 // Send broadcast while process starts are failing 969 mNextProcessStartBehavior.set(ProcessStartBehavior.FAIL_NULL); 970 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 971 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, 972 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN)))); 973 974 // Confirm that queue goes idle, with no processes 975 waitForIdle(); 976 assertEquals(1, mActiveProcesses.size()); 977 978 // Send more broadcasts with working process starts 979 final Intent timezone = new Intent(Intent.ACTION_TIMEZONE_CHANGED); 980 enqueueBroadcast(makeBroadcastRecord(timezone, callerApp, 981 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN), 982 makeManifestReceiver(PACKAGE_YELLOW, CLASS_YELLOW)))); 983 984 // Confirm that we only saw second broadcast 985 waitForIdle(); 986 assertEquals(3, mActiveProcesses.size()); 987 final ProcessRecord receiverGreenApp = mAms.getProcessRecordLocked(PACKAGE_GREEN, 988 getUidForPackage(PACKAGE_GREEN)); 989 final ProcessRecord receiverYellowApp = mAms.getProcessRecordLocked(PACKAGE_YELLOW, 990 getUidForPackage(PACKAGE_YELLOW)); 991 verifyScheduleReceiver(never(), receiverGreenApp, airplane); 992 verifyScheduleReceiver(times(1), receiverGreenApp, timezone); 993 verifyScheduleReceiver(times(1), receiverYellowApp, timezone); 994 } 995 996 /** 997 * Verify that we cleanup a disabled component, skipping a pending dispatch 998 * of broadcast to that component. 999 */ 1000 @Test 1001 public void testCleanup() throws Exception { 1002 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 1003 final ProcessRecord receiverApp = makeActiveProcessRecord(PACKAGE_GREEN); 1004 1005 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 1006 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, new ArrayList<>( 1007 List.of(makeRegisteredReceiver(receiverApp), 1008 makeManifestReceiver(PACKAGE_GREEN, CLASS_RED), 1009 makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN), 1010 makeManifestReceiver(PACKAGE_GREEN, CLASS_BLUE))))); 1011 1012 synchronized (mAms) { 1013 mQueue.cleanupDisabledPackageReceiversLocked(PACKAGE_GREEN, Set.of(CLASS_GREEN), 1014 UserHandle.USER_SYSTEM); 1015 1016 // Also try clearing out other unrelated things that should leave 1017 // the final receiver intact 1018 mQueue.cleanupDisabledPackageReceiversLocked(PACKAGE_RED, null, 1019 UserHandle.USER_SYSTEM); 1020 mQueue.cleanupDisabledPackageReceiversLocked(null, null, USER_GUEST); 1021 1022 // To maximize test coverage, dump current state; we're not worried 1023 // about the actual output, just that we don't crash 1024 mQueue.dumpDebug(new ProtoOutputStream(), 1025 ActivityManagerServiceDumpBroadcastsProto.BROADCAST_QUEUE); 1026 mQueue.dumpLocked(FileDescriptor.err, new PrintWriter(Writer.nullWriter()), 1027 null, 0, true, true, true, null, null, false); 1028 } 1029 1030 waitForIdle(); 1031 verifyScheduleRegisteredReceiver(receiverApp, airplane); 1032 verifyScheduleReceiver(times(1), receiverApp, airplane, 1033 new ComponentName(PACKAGE_GREEN, CLASS_RED)); 1034 verifyScheduleReceiver(never(), receiverApp, airplane, 1035 new ComponentName(PACKAGE_GREEN, CLASS_GREEN)); 1036 verifyScheduleReceiver(times(1), receiverApp, airplane, 1037 new ComponentName(PACKAGE_GREEN, CLASS_BLUE)); 1038 } 1039 1040 @Test 1041 public void testCleanup_userRemoved() throws Exception { 1042 final ProcessRecord callerApp = makeActiveProcessRecord( 1043 PACKAGE_RED, PACKAGE_RED, ProcessBehavior.NORMAL, 1044 USER_GUEST); 1045 1046 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 1047 final Intent timeZone = new Intent(Intent.ACTION_TIMEZONE_CHANGED); 1048 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, USER_GUEST, new ArrayList<>( 1049 List.of(makeRegisteredReceiver(callerApp), 1050 makeManifestReceiver(PACKAGE_GREEN, CLASS_RED, USER_GUEST), 1051 makeManifestReceiver(PACKAGE_BLUE, CLASS_GREEN, USER_GUEST), 1052 makeManifestReceiver(PACKAGE_YELLOW, CLASS_BLUE, USER_GUEST))))); 1053 enqueueBroadcast(makeBroadcastRecord(timeZone, callerApp, USER_GUEST, new ArrayList<>( 1054 List.of(makeRegisteredReceiver(callerApp), 1055 makeManifestReceiver(PACKAGE_GREEN, CLASS_RED, USER_GUEST), 1056 makeManifestReceiver(PACKAGE_BLUE, CLASS_GREEN, USER_GUEST), 1057 makeManifestReceiver(PACKAGE_YELLOW, CLASS_BLUE, USER_GUEST))))); 1058 1059 synchronized (mAms) { 1060 mQueue.cleanupDisabledPackageReceiversLocked(null, null, USER_GUEST); 1061 } 1062 1063 waitForIdle(); 1064 verifyScheduleReceiver(never(), callerApp, USER_GUEST); 1065 verifyScheduleRegisteredReceiver(never(), callerApp, USER_GUEST); 1066 for (String pkg : new String[] { 1067 PACKAGE_GREEN, PACKAGE_BLUE, PACKAGE_YELLOW 1068 }) { 1069 assertNull(mAms.getProcessRecordLocked(pkg, getUidForPackage(pkg, USER_GUEST))); 1070 } 1071 } 1072 1073 /** 1074 * Verify that killing a running process skips registered receivers. 1075 */ 1076 @Test 1077 public void testKill() throws Exception { 1078 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 1079 final ProcessRecord oldApp = makeActiveProcessRecord(PACKAGE_GREEN); 1080 1081 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 1082 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, new ArrayList<>( 1083 List.of(makeRegisteredReceiver(oldApp), 1084 makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN))))); 1085 synchronized (mAms) { 1086 oldApp.killLocked(TAG, 42, false); 1087 mQueue.onApplicationCleanupLocked(oldApp); 1088 } 1089 waitForIdle(); 1090 1091 // Confirm that we cold-started after the kill 1092 final ProcessRecord newApp = mAms.getProcessRecordLocked(PACKAGE_GREEN, 1093 getUidForPackage(PACKAGE_GREEN)); 1094 assertNotEquals(oldApp, newApp); 1095 1096 // Confirm that we saw no registered receiver traffic 1097 final IApplicationThread oldThread = oldApp.getThread(); 1098 verify(oldThread, never()).scheduleRegisteredReceiver(any(), any(), anyInt(), any(), any(), 1099 anyBoolean(), anyBoolean(), anyBoolean(), anyInt(), anyInt(), anyInt(), any()); 1100 final IApplicationThread newThread = newApp.getThread(); 1101 verify(newThread, never()).scheduleRegisteredReceiver(any(), any(), anyInt(), any(), any(), 1102 anyBoolean(), anyBoolean(), anyBoolean(), anyInt(), anyInt(), anyInt(), any()); 1103 1104 // Confirm that we saw final manifest broadcast 1105 verifyScheduleReceiver(times(1), newApp, airplane, 1106 new ComponentName(PACKAGE_GREEN, CLASS_GREEN)); 1107 } 1108 1109 /** 1110 * Verify that when BroadcastQueue doesn't get notified when a process gets killed, it 1111 * doesn't get stuck. 1112 */ 1113 @Test 1114 public void testKillWithoutNotify() throws Exception { 1115 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 1116 final ProcessRecord receiverBlueApp = makeActiveProcessRecord(PACKAGE_BLUE); 1117 1118 mNextProcessStartBehavior.set(ProcessStartBehavior.KILLED_WITHOUT_NOTIFY); 1119 1120 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 1121 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, List.of( 1122 withPriority(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN), 10), 1123 withPriority(makeRegisteredReceiver(receiverBlueApp), 5), 1124 withPriority(makeManifestReceiver(PACKAGE_YELLOW, CLASS_YELLOW), 0)))); 1125 1126 final Intent timezone = new Intent(Intent.ACTION_TIMEZONE_CHANGED); 1127 enqueueBroadcast(makeBroadcastRecord(timezone, callerApp, 1128 List.of(makeManifestReceiver(PACKAGE_ORANGE, CLASS_ORANGE)))); 1129 1130 waitForIdle(); 1131 final ProcessRecord receiverGreenApp = mAms.getProcessRecordLocked(PACKAGE_GREEN, 1132 getUidForPackage(PACKAGE_GREEN)); 1133 final ProcessRecord receiverYellowApp = mAms.getProcessRecordLocked(PACKAGE_YELLOW, 1134 getUidForPackage(PACKAGE_YELLOW)); 1135 final ProcessRecord receiverOrangeApp = mAms.getProcessRecordLocked(PACKAGE_ORANGE, 1136 getUidForPackage(PACKAGE_ORANGE)); 1137 1138 verifyScheduleReceiver(times(1), receiverGreenApp, airplane); 1139 verifyScheduleRegisteredReceiver(times(1), receiverBlueApp, airplane); 1140 verifyScheduleReceiver(times(1), receiverYellowApp, airplane); 1141 verifyScheduleReceiver(times(1), receiverOrangeApp, timezone); 1142 } 1143 1144 /** 1145 * Verify that when BroadcastQueue doesn't get notified when a process gets killed repeatedly, 1146 * it doesn't get stuck. 1147 */ 1148 @Test 1149 @RequiresFlagsEnabled(Flags.FLAG_AVOID_REPEATED_BCAST_RE_ENQUEUES) 1150 public void testRepeatedKillWithoutNotify() throws Exception { 1151 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 1152 final ProcessRecord receiverBlueApp = makeActiveProcessRecord(PACKAGE_BLUE); 1153 1154 mNewProcessStartBehaviors.put(PACKAGE_GREEN, ProcessStartBehavior.KILLED_WITHOUT_NOTIFY); 1155 1156 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 1157 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, List.of( 1158 withPriority(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN), 10), 1159 withPriority(makeRegisteredReceiver(receiverBlueApp), 5), 1160 withPriority(makeManifestReceiver(PACKAGE_YELLOW, CLASS_YELLOW), 0)))); 1161 1162 final Intent timezone = new Intent(Intent.ACTION_TIMEZONE_CHANGED); 1163 enqueueBroadcast(makeBroadcastRecord(timezone, callerApp, 1164 List.of(makeManifestReceiver(PACKAGE_ORANGE, CLASS_ORANGE)))); 1165 1166 waitForIdle(); 1167 final ProcessRecord receiverGreenApp = mAms.getProcessRecordLocked(PACKAGE_GREEN, 1168 getUidForPackage(PACKAGE_GREEN)); 1169 final ProcessRecord receiverYellowApp = mAms.getProcessRecordLocked(PACKAGE_YELLOW, 1170 getUidForPackage(PACKAGE_YELLOW)); 1171 final ProcessRecord receiverOrangeApp = mAms.getProcessRecordLocked(PACKAGE_ORANGE, 1172 getUidForPackage(PACKAGE_ORANGE)); 1173 1174 // Broadcast queue always kills the target process when broadcast delivery fails. 1175 assertNull(receiverGreenApp); 1176 verifyScheduleRegisteredReceiver(times(1), receiverBlueApp, airplane); 1177 verifyScheduleReceiver(times(1), receiverYellowApp, airplane); 1178 verifyScheduleReceiver(times(1), receiverOrangeApp, timezone); 1179 } 1180 1181 @Test 1182 public void testProcessStartWithMissingResponse() throws Exception { 1183 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 1184 final ProcessRecord receiverBlueApp = makeActiveProcessRecord(PACKAGE_BLUE); 1185 1186 mNewProcessStartBehaviors.put(PACKAGE_GREEN, ProcessStartBehavior.MISSING_RESPONSE); 1187 1188 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 1189 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, List.of( 1190 withPriority(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN), 10), 1191 withPriority(makeRegisteredReceiver(receiverBlueApp), 5), 1192 withPriority(makeManifestReceiver(PACKAGE_YELLOW, CLASS_YELLOW), 0)))); 1193 1194 final Intent timezone = new Intent(Intent.ACTION_TIMEZONE_CHANGED); 1195 enqueueBroadcast(makeBroadcastRecord(timezone, callerApp, 1196 List.of(makeManifestReceiver(PACKAGE_ORANGE, CLASS_ORANGE)))); 1197 1198 waitForIdle(); 1199 final ProcessRecord receiverGreenApp = mAms.getProcessRecordLocked(PACKAGE_GREEN, 1200 getUidForPackage(PACKAGE_GREEN)); 1201 final ProcessRecord receiverYellowApp = mAms.getProcessRecordLocked(PACKAGE_YELLOW, 1202 getUidForPackage(PACKAGE_YELLOW)); 1203 final ProcessRecord receiverOrangeApp = mAms.getProcessRecordLocked(PACKAGE_ORANGE, 1204 getUidForPackage(PACKAGE_ORANGE)); 1205 1206 verifyScheduleReceiver(times(1), receiverGreenApp, airplane); 1207 verifyScheduleRegisteredReceiver(times(1), receiverBlueApp, airplane); 1208 verifyScheduleReceiver(times(1), receiverYellowApp, airplane); 1209 verifyScheduleReceiver(times(1), receiverOrangeApp, timezone); 1210 } 1211 1212 /** 1213 * Verify that a broadcast sent to a frozen app, which gets killed as part of unfreezing 1214 * process due to pending sync binder transactions, is delivered as expected. 1215 */ 1216 @Test 1217 public void testDeliveryToFrozenApp_killedWhileUnfreeze() throws Exception { 1218 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 1219 final ProcessRecord receiverBlueApp = makeActiveProcessRecord(PACKAGE_BLUE); 1220 1221 // Mark the app as killed while unfreezing it, which can happen either when we directly 1222 // try to unfreeze it or when it is done as part of OomAdjust computation. 1223 doAnswer(invocation -> { 1224 final ProcessRecord app = invocation.getArgument(0); 1225 if (app == receiverBlueApp) { 1226 app.setKilled(true); 1227 mActiveProcesses.remove(app); 1228 } 1229 return null; 1230 }).when(mAms.mOomAdjuster).unfreezeTemporarily(eq(receiverBlueApp), anyInt()); 1231 doAnswer(invocation -> { 1232 final ProcessRecord app = invocation.getArgument(0); 1233 if (app == receiverBlueApp) { 1234 app.setKilled(true); 1235 mActiveProcesses.remove(app); 1236 } 1237 return null; 1238 }).when(mAms).enqueueOomAdjTargetLocked(eq(receiverBlueApp)); 1239 1240 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 1241 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, List.of( 1242 makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE)))); 1243 1244 waitForIdle(); 1245 final ProcessRecord restartedReceiverBlueApp = mAms.getProcessRecordLocked(PACKAGE_BLUE, 1246 getUidForPackage(PACKAGE_BLUE)); 1247 assertNotEquals(receiverBlueApp, restartedReceiverBlueApp); 1248 verifyScheduleReceiver(never(), receiverBlueApp, airplane); 1249 // Verify that the new process receives the broadcast. 1250 verifyScheduleReceiver(times(1), restartedReceiverBlueApp, airplane); 1251 } 1252 1253 @Test 1254 public void testCold_Success() throws Exception { 1255 doCold(ProcessStartBehavior.SUCCESS); 1256 } 1257 1258 @Test 1259 public void testCold_Success_Predecessor() throws Exception { 1260 doCold(ProcessStartBehavior.SUCCESS_PREDECESSOR); 1261 } 1262 1263 @Test 1264 public void testCold_Fail_Null() throws Exception { 1265 doCold(ProcessStartBehavior.FAIL_NULL); 1266 } 1267 1268 @Test 1269 public void testCold_Fail_Timeout() throws Exception { 1270 doCold(ProcessStartBehavior.FAIL_TIMEOUT); 1271 } 1272 1273 @Test 1274 public void testCold_Fail_Timeout_Predecessor() throws Exception { 1275 doCold(ProcessStartBehavior.FAIL_TIMEOUT_PREDECESSOR); 1276 } 1277 1278 private void doCold(ProcessStartBehavior behavior) throws Exception { 1279 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 1280 1281 mNextProcessStartBehavior.set(behavior); 1282 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 1283 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, 1284 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN)))); 1285 waitForIdle(); 1286 1287 // Regardless of success/failure of above, we should always be able to 1288 // recover and begin sending future broadcasts 1289 final Intent timezone = new Intent(Intent.ACTION_TIMEZONE_CHANGED); 1290 enqueueBroadcast(makeBroadcastRecord(timezone, callerApp, 1291 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN)))); 1292 waitForIdle(); 1293 1294 final ProcessRecord receiverApp = mAms.getProcessRecordLocked(PACKAGE_GREEN, 1295 getUidForPackage(PACKAGE_GREEN)); 1296 verifyScheduleReceiver(receiverApp, timezone); 1297 } 1298 1299 /** 1300 * Verify that we skip broadcasts to an app being backed up. 1301 */ 1302 @Test 1303 public void testBackup() throws Exception { 1304 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 1305 final ProcessRecord receiverApp = makeActiveProcessRecord(PACKAGE_GREEN); 1306 receiverApp.setInFullBackup(true); 1307 1308 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 1309 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, 1310 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN)))); 1311 1312 waitForIdle(); 1313 verifyScheduleReceiver(never(), receiverApp, airplane, 1314 new ComponentName(PACKAGE_GREEN, CLASS_GREEN)); 1315 } 1316 1317 /** 1318 * Verify that an ordered broadcast collects results from everyone along the 1319 * chain, and is delivered to final destination. 1320 */ 1321 @Test 1322 public void testOrdered() throws Exception { 1323 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 1324 1325 // Purposefully warm-start the middle apps to make sure we dispatch to 1326 // both cold and warm apps in expected order 1327 makeActiveProcessRecord(makeApplicationInfo(PACKAGE_BLUE), PACKAGE_BLUE, 1328 ProcessBehavior.NORMAL, (extras) -> { 1329 extras = clone(extras); 1330 extras.putBoolean(PACKAGE_BLUE, true); 1331 return extras; 1332 }); 1333 makeActiveProcessRecord(makeApplicationInfo(PACKAGE_YELLOW), PACKAGE_YELLOW, 1334 ProcessBehavior.NORMAL, (extras) -> { 1335 extras = clone(extras); 1336 extras.putBoolean(PACKAGE_YELLOW, true); 1337 return extras; 1338 }); 1339 1340 final IIntentReceiver orderedResultTo = mock(IIntentReceiver.class); 1341 final Bundle orderedExtras = new Bundle(); 1342 orderedExtras.putBoolean(PACKAGE_RED, true); 1343 1344 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 1345 enqueueBroadcast(makeOrderedBroadcastRecord(airplane, callerApp, 1346 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN), 1347 makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE), 1348 makeManifestReceiver(PACKAGE_YELLOW, CLASS_YELLOW)), 1349 orderedResultTo, orderedExtras)); 1350 1351 waitForIdle(); 1352 final IApplicationThread greenThread = mAms.getProcessRecordLocked(PACKAGE_GREEN, 1353 getUidForPackage(PACKAGE_GREEN)).getThread(); 1354 final IApplicationThread blueThread = mAms.getProcessRecordLocked(PACKAGE_BLUE, 1355 getUidForPackage(PACKAGE_BLUE)).getThread(); 1356 final IApplicationThread yellowThread = mAms.getProcessRecordLocked(PACKAGE_YELLOW, 1357 getUidForPackage(PACKAGE_YELLOW)).getThread(); 1358 final IApplicationThread redThread = mAms.getProcessRecordLocked(PACKAGE_RED, 1359 getUidForPackage(PACKAGE_RED)).getThread(); 1360 1361 // Verify that we called everyone in specific order, and that each of 1362 // them observed the expected extras at that stage 1363 final InOrder inOrder = inOrder(greenThread, blueThread, yellowThread, redThread); 1364 final Bundle expectedExtras = new Bundle(); 1365 expectedExtras.putBoolean(PACKAGE_RED, true); 1366 inOrder.verify(greenThread).scheduleReceiver( 1367 argThat(filterEqualsIgnoringComponent(airplane)), any(), any(), 1368 eq(Activity.RESULT_OK), any(), argThat(bundleEquals(expectedExtras)), 1369 eq(true), eq(false), eq(UserHandle.USER_SYSTEM), anyInt(), anyInt(), any()); 1370 inOrder.verify(blueThread).scheduleReceiver( 1371 argThat(filterEqualsIgnoringComponent(airplane)), any(), any(), 1372 eq(Activity.RESULT_OK), any(), argThat(bundleEquals(expectedExtras)), 1373 eq(true), eq(false), eq(UserHandle.USER_SYSTEM), anyInt(), anyInt(), any()); 1374 expectedExtras.putBoolean(PACKAGE_BLUE, true); 1375 inOrder.verify(yellowThread).scheduleReceiver( 1376 argThat(filterEqualsIgnoringComponent(airplane)), any(), any(), 1377 eq(Activity.RESULT_OK), any(), argThat(bundleEquals(expectedExtras)), 1378 eq(true), eq(false), eq(UserHandle.USER_SYSTEM), anyInt(), anyInt(), any()); 1379 expectedExtras.putBoolean(PACKAGE_YELLOW, true); 1380 inOrder.verify(redThread).scheduleRegisteredReceiver( 1381 any(), argThat(filterEquals(airplane)), 1382 eq(Activity.RESULT_OK), any(), argThat(bundleEquals(expectedExtras)), 1383 eq(false), anyBoolean(), eq(true), eq(UserHandle.USER_SYSTEM), anyInt(), 1384 anyInt(), any()); 1385 1386 // Finally, verify that we thawed the final receiver 1387 verify(mAms.mOomAdjuster).unfreezeTemporarily(eq(callerApp), 1388 eq(OOM_ADJ_REASON_FINISH_RECEIVER)); 1389 } 1390 1391 /** 1392 * Verify that an ordered broadcast can be aborted partially through 1393 * dispatch, and is then delivered to final destination. 1394 */ 1395 @Test 1396 public void testOrdered_Aborting() throws Exception { 1397 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 1398 doOrdered_Aborting(airplane); 1399 } 1400 1401 /** 1402 * Verify that an ordered broadcast marked with 1403 * {@link Intent#FLAG_RECEIVER_NO_ABORT} cannot be aborted partially through 1404 * dispatch, and is delivered to everyone in order. 1405 */ 1406 @Test 1407 public void testOrdered_Aborting_NoAbort() throws Exception { 1408 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 1409 airplane.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 1410 doOrdered_Aborting(airplane); 1411 } 1412 1413 public void doOrdered_Aborting(@NonNull Intent intent) throws Exception { 1414 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 1415 1416 // Create a process that aborts any ordered broadcasts 1417 makeActiveProcessRecord(makeApplicationInfo(PACKAGE_GREEN), PACKAGE_GREEN, 1418 ProcessBehavior.ABORT, (extras) -> { 1419 extras = clone(extras); 1420 extras.putBoolean(PACKAGE_GREEN, true); 1421 return extras; 1422 }); 1423 makeActiveProcessRecord(PACKAGE_BLUE); 1424 1425 final IIntentReceiver orderedResultTo = mock(IIntentReceiver.class); 1426 1427 enqueueBroadcast(makeOrderedBroadcastRecord(intent, callerApp, 1428 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN), 1429 makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE)), 1430 orderedResultTo, null)); 1431 1432 waitForIdle(); 1433 final IApplicationThread greenThread = mAms.getProcessRecordLocked(PACKAGE_GREEN, 1434 getUidForPackage(PACKAGE_GREEN)).getThread(); 1435 final IApplicationThread blueThread = mAms.getProcessRecordLocked(PACKAGE_BLUE, 1436 getUidForPackage(PACKAGE_BLUE)).getThread(); 1437 final IApplicationThread redThread = mAms.getProcessRecordLocked(PACKAGE_RED, 1438 getUidForPackage(PACKAGE_RED)).getThread(); 1439 1440 final Bundle expectedExtras = new Bundle(); 1441 expectedExtras.putBoolean(PACKAGE_GREEN, true); 1442 1443 // Verify that we always invoke the first receiver, but then we might 1444 // have invoked or skipped the second receiver depending on the intent 1445 // flag policy; we always deliver to final receiver regardless of abort 1446 final InOrder inOrder = inOrder(greenThread, blueThread, redThread); 1447 inOrder.verify(greenThread).scheduleReceiver( 1448 argThat(filterEqualsIgnoringComponent(intent)), any(), any(), 1449 eq(Activity.RESULT_OK), any(), any(), eq(true), eq(false), 1450 eq(UserHandle.USER_SYSTEM), anyInt(), anyInt(), any()); 1451 if ((intent.getFlags() & Intent.FLAG_RECEIVER_NO_ABORT) != 0) { 1452 inOrder.verify(blueThread).scheduleReceiver( 1453 argThat(filterEqualsIgnoringComponent(intent)), any(), any(), 1454 eq(Activity.RESULT_OK), any(), any(), eq(true), eq(false), 1455 eq(UserHandle.USER_SYSTEM), anyInt(), anyInt(), any()); 1456 } else { 1457 inOrder.verify(blueThread, never()).scheduleReceiver( 1458 any(), any(), any(), anyInt(), any(), any(), 1459 anyBoolean(), anyBoolean(), anyInt(), anyInt(), anyInt(), any()); 1460 } 1461 inOrder.verify(redThread).scheduleRegisteredReceiver( 1462 any(), argThat(filterEquals(intent)), 1463 eq(Activity.RESULT_OK), any(), argThat(bundleEquals(expectedExtras)), 1464 eq(false), anyBoolean(), eq(true), eq(UserHandle.USER_SYSTEM), 1465 anyInt(), anyInt(), any()); 1466 } 1467 1468 /** 1469 * Verify that we immediately dispatch final result for empty lists. 1470 */ 1471 @Test 1472 public void testOrdered_Empty() throws Exception { 1473 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 1474 final IApplicationThread callerThread = callerApp.getThread(); 1475 1476 final IIntentReceiver orderedResultTo = mock(IIntentReceiver.class); 1477 final Bundle orderedExtras = new Bundle(); 1478 orderedExtras.putBoolean(PACKAGE_RED, true); 1479 1480 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 1481 enqueueBroadcast(makeOrderedBroadcastRecord(airplane, callerApp, null, 1482 orderedResultTo, orderedExtras)); 1483 1484 waitForIdle(); 1485 verify(callerThread).scheduleRegisteredReceiver( 1486 any(), argThat(filterEquals(airplane)), 1487 eq(Activity.RESULT_OK), any(), argThat(bundleEquals(orderedExtras)), 1488 eq(false), anyBoolean(), eq(true), eq(UserHandle.USER_SYSTEM), 1489 anyInt(), anyInt(), any()); 1490 } 1491 1492 /** 1493 * Verify that we deliver results for unordered broadcasts. 1494 */ 1495 @Test 1496 public void testUnordered_ResultTo() throws Exception { 1497 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 1498 final IApplicationThread callerThread = callerApp.getThread(); 1499 1500 final IIntentReceiver resultTo = mock(IIntentReceiver.class); 1501 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 1502 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, 1503 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN), 1504 makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE)), resultTo)); 1505 1506 waitForIdle(); 1507 verify(callerThread).scheduleRegisteredReceiver( 1508 any(), argThat(filterEquals(airplane)), 1509 eq(Activity.RESULT_OK), any(), any(), 1510 eq(false), anyBoolean(), eq(true), eq(UserHandle.USER_SYSTEM), 1511 anyInt(), anyInt(), any()); 1512 } 1513 1514 /** 1515 * Verify that we're not surprised by a process attempting to finishing a 1516 * broadcast when none is in progress. 1517 */ 1518 @Test 1519 public void testUnexpected() throws Exception { 1520 final ProcessRecord app = makeActiveProcessRecord(PACKAGE_RED); 1521 mQueue.finishReceiverLocked(app, Activity.RESULT_OK, null, null, false, false); 1522 } 1523 1524 @Test 1525 public void testBackgroundActivityStarts() throws Exception { 1526 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 1527 final ProcessRecord receiverApp = makeActiveProcessRecord(PACKAGE_GREEN); 1528 1529 final BackgroundStartPrivileges backgroundStartPrivileges = 1530 BackgroundStartPrivileges.allowBackgroundActivityStarts(new Binder()); 1531 final Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 1532 final BroadcastRecord r = new BroadcastRecord(mQueue, intent, callerApp, 1533 callerApp.info.packageName, null, callerApp.getPid(), callerApp.info.uid, false, 1534 null, null, null, null, AppOpsManager.OP_NONE, BroadcastOptions.makeBasic(), 1535 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN)), null, null, 1536 Activity.RESULT_OK, null, null, false, false, false, UserHandle.USER_SYSTEM, 1537 backgroundStartPrivileges, false, null, PROCESS_STATE_UNKNOWN, mPlatformCompat); 1538 enqueueBroadcast(r); 1539 1540 waitForIdle(); 1541 verify(receiverApp).addOrUpdateBackgroundStartPrivileges(eq(r), 1542 eq(backgroundStartPrivileges)); 1543 verify(receiverApp).removeBackgroundStartPrivileges(eq(r)); 1544 } 1545 1546 @Test 1547 public void testOptions_TemporaryAppAllowlist() throws Exception { 1548 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 1549 final ProcessRecord receiverApp = makeActiveProcessRecord(PACKAGE_GREEN); 1550 1551 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 1552 final BroadcastOptions options = BroadcastOptions.makeBasic(); 1553 options.setTemporaryAppAllowlist(1_000, 1554 PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED, 1555 PowerExemptionManager.REASON_VPN, TAG); 1556 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, options, 1557 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN)))); 1558 1559 waitForIdle(); 1560 verify(mAms).tempAllowlistUidLocked(eq(receiverApp.uid), eq(1_000L), 1561 eq(options.getTemporaryAppAllowlistReasonCode()), any(), 1562 eq(options.getTemporaryAppAllowlistType()), eq(callerApp.uid)); 1563 } 1564 1565 /** 1566 * Verify that sending broadcasts to the {@code system} process are handled 1567 * as a singleton process. 1568 */ 1569 @Test 1570 public void testSystemSingleton() throws Exception { 1571 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_PHONE); 1572 final ProcessRecord systemApp = makeActiveProcessRecord(PACKAGE_ANDROID, PROCESS_SYSTEM, 1573 ProcessBehavior.NORMAL, USER_SYSTEM); 1574 1575 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 1576 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, USER_SYSTEM, 1577 List.of(makeManifestReceiver(PACKAGE_ANDROID, PROCESS_SYSTEM, 1578 CLASS_GREEN, USER_SYSTEM)))); 1579 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, USER_GUEST, 1580 List.of(makeManifestReceiver(PACKAGE_ANDROID, PROCESS_SYSTEM, 1581 CLASS_GREEN, USER_GUEST)))); 1582 waitForIdle(); 1583 1584 // Confirm we dispatched both users to same singleton instance 1585 verifyScheduleReceiver(times(1), systemApp, airplane, USER_SYSTEM); 1586 verifyScheduleReceiver(times(1), systemApp, airplane, USER_GUEST); 1587 } 1588 1589 /** 1590 * Verify that when dispatching we respect tranches of priority. 1591 */ 1592 @DisableFlags(Flags.FLAG_LIMIT_PRIORITY_SCOPE) 1593 @SuppressWarnings("DistinctVarargsChecker") 1594 @Test 1595 public void testPriority_flagDisabled() throws Exception { 1596 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 1597 final ProcessRecord receiverBlueApp = makeActiveProcessRecord(PACKAGE_BLUE); 1598 final ProcessRecord receiverGreenApp = makeActiveProcessRecord(PACKAGE_GREEN); 1599 final ProcessRecord receiverYellowApp = makeActiveProcessRecord(PACKAGE_YELLOW); 1600 1601 // Enqueue a normal broadcast that will go to several processes, and 1602 // then enqueue a foreground broadcast that risks reordering 1603 final Intent timezone = new Intent(Intent.ACTION_TIMEZONE_CHANGED); 1604 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 1605 airplane.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 1606 enqueueBroadcast(makeBroadcastRecord(timezone, callerApp, 1607 List.of(makeRegisteredReceiver(receiverBlueApp, 10), 1608 makeRegisteredReceiver(receiverGreenApp, 10), 1609 makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE), 1610 makeManifestReceiver(PACKAGE_YELLOW, CLASS_YELLOW), 1611 makeRegisteredReceiver(receiverYellowApp, -10)))); 1612 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, 1613 List.of(makeRegisteredReceiver(receiverBlueApp)))); 1614 waitForIdle(); 1615 1616 // Ignore the final foreground broadcast 1617 mScheduledBroadcasts.remove(makeScheduledBroadcast(receiverBlueApp, airplane)); 1618 assertEquals(5, mScheduledBroadcasts.size()); 1619 1620 // We're only concerned about enforcing ordering between tranches; 1621 // within a tranche we're okay with reordering 1622 assertEquals( 1623 Set.of(makeScheduledBroadcast(receiverBlueApp, timezone), 1624 makeScheduledBroadcast(receiverGreenApp, timezone)), 1625 Set.of(mScheduledBroadcasts.remove(0), 1626 mScheduledBroadcasts.remove(0))); 1627 assertEquals( 1628 Set.of(makeScheduledBroadcast(receiverBlueApp, timezone), 1629 makeScheduledBroadcast(receiverYellowApp, timezone)), 1630 Set.of(mScheduledBroadcasts.remove(0), 1631 mScheduledBroadcasts.remove(0))); 1632 assertEquals( 1633 Set.of(makeScheduledBroadcast(receiverYellowApp, timezone)), 1634 Set.of(mScheduledBroadcasts.remove(0))); 1635 } 1636 1637 /** 1638 * Verify that when dispatching we respect tranches of priority. 1639 */ 1640 @SuppressWarnings("DistinctVarargsChecker") 1641 @Test 1642 public void testOrdered_withPriorities() throws Exception { 1643 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 1644 final ProcessRecord receiverBlueApp = makeActiveProcessRecord(PACKAGE_BLUE); 1645 final ProcessRecord receiverGreenApp = makeActiveProcessRecord(PACKAGE_GREEN); 1646 final ProcessRecord receiverYellowApp = makeActiveProcessRecord(PACKAGE_YELLOW); 1647 1648 // Enqueue a normal broadcast that will go to several processes, and 1649 // then enqueue a foreground broadcast that risks reordering 1650 final Intent timezone = new Intent(Intent.ACTION_TIMEZONE_CHANGED); 1651 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 1652 airplane.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 1653 final IIntentReceiver orderedResultTo = mock(IIntentReceiver.class); 1654 enqueueBroadcast(makeOrderedBroadcastRecord(timezone, callerApp, 1655 List.of(makeRegisteredReceiver(receiverBlueApp, 10), 1656 makeRegisteredReceiver(receiverGreenApp, 10), 1657 makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE), 1658 makeManifestReceiver(PACKAGE_YELLOW, CLASS_YELLOW), 1659 makeRegisteredReceiver(receiverYellowApp, -10)), 1660 orderedResultTo, null)); 1661 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, 1662 List.of(makeRegisteredReceiver(receiverBlueApp)))); 1663 waitForIdle(); 1664 1665 // Ignore the final foreground broadcast 1666 mScheduledBroadcasts.remove(makeScheduledBroadcast(receiverBlueApp, airplane)); 1667 assertEquals(6, mScheduledBroadcasts.size()); 1668 1669 // We're only concerned about enforcing ordering between tranches; 1670 // within a tranche we're okay with reordering 1671 assertEquals( 1672 Set.of(makeScheduledBroadcast(receiverBlueApp, timezone), 1673 makeScheduledBroadcast(receiverGreenApp, timezone)), 1674 Set.of(mScheduledBroadcasts.remove(0), 1675 mScheduledBroadcasts.remove(0))); 1676 assertEquals( 1677 Set.of(makeScheduledBroadcast(receiverBlueApp, timezone), 1678 makeScheduledBroadcast(receiverYellowApp, timezone)), 1679 Set.of(mScheduledBroadcasts.remove(0), 1680 mScheduledBroadcasts.remove(0))); 1681 assertEquals( 1682 Set.of(makeScheduledBroadcast(receiverYellowApp, timezone)), 1683 Set.of(mScheduledBroadcasts.remove(0))); 1684 } 1685 1686 /** 1687 * Verify that when dispatching we respect tranches of priority. 1688 */ 1689 @EnableFlags(Flags.FLAG_LIMIT_PRIORITY_SCOPE) 1690 @SuppressWarnings("DistinctVarargsChecker") 1691 @Test 1692 public void testPriority_changeIdDisabled() throws Exception { 1693 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 1694 final ProcessRecord receiverBlueApp = makeActiveProcessRecord(PACKAGE_BLUE); 1695 final ProcessRecord receiverGreenApp = makeActiveProcessRecord(PACKAGE_GREEN); 1696 final ProcessRecord receiverYellowApp = makeActiveProcessRecord(PACKAGE_YELLOW); 1697 1698 doReturn(false).when(mPlatformCompat).isChangeEnabledInternalNoLogging( 1699 eq(BroadcastRecord.LIMIT_PRIORITY_SCOPE), 1700 argThat(appInfoEquals(receiverBlueApp.uid))); 1701 1702 // Enqueue a normal broadcast that will go to several processes, and 1703 // then enqueue a foreground broadcast that risks reordering 1704 final Intent timezone = new Intent(Intent.ACTION_TIMEZONE_CHANGED); 1705 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 1706 airplane.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 1707 enqueueBroadcast(makeBroadcastRecord(timezone, callerApp, 1708 List.of(makeRegisteredReceiver(receiverBlueApp, 10), 1709 makeRegisteredReceiver(receiverGreenApp, 10), 1710 makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE), 1711 makeManifestReceiver(PACKAGE_YELLOW, CLASS_YELLOW), 1712 makeRegisteredReceiver(receiverYellowApp, -10)))); 1713 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, 1714 List.of(makeRegisteredReceiver(receiverBlueApp)))); 1715 waitForIdle(); 1716 1717 // Ignore the final foreground broadcast 1718 mScheduledBroadcasts.remove(makeScheduledBroadcast(receiverBlueApp, airplane)); 1719 assertEquals(5, mScheduledBroadcasts.size()); 1720 1721 // We're only concerned about enforcing ordering between tranches; 1722 // within a tranche we're okay with reordering 1723 assertEquals( 1724 Set.of(makeScheduledBroadcast(receiverBlueApp, timezone), 1725 makeScheduledBroadcast(receiverGreenApp, timezone)), 1726 Set.of(mScheduledBroadcasts.remove(0), 1727 mScheduledBroadcasts.remove(0))); 1728 assertEquals( 1729 Set.of(makeScheduledBroadcast(receiverBlueApp, timezone), 1730 makeScheduledBroadcast(receiverYellowApp, timezone)), 1731 Set.of(mScheduledBroadcasts.remove(0), 1732 mScheduledBroadcasts.remove(0))); 1733 assertEquals( 1734 Set.of(makeScheduledBroadcast(receiverYellowApp, timezone)), 1735 Set.of(mScheduledBroadcasts.remove(0))); 1736 } 1737 1738 /** 1739 * Verify prioritized receivers work as expected with deferrable broadcast - broadcast to 1740 * app in cached state should be deferred and the rest should be delivered as per the priority 1741 * order. 1742 */ 1743 @Test 1744 public void testPrioritized_withDeferrableBroadcasts() throws Exception { 1745 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 1746 final ProcessRecord receiverGreenApp = makeActiveProcessRecord(PACKAGE_GREEN); 1747 final ProcessRecord receiverBlueApp = makeActiveProcessRecord(PACKAGE_BLUE); 1748 final ProcessRecord receiverYellowApp = makeActiveProcessRecord(PACKAGE_YELLOW); 1749 final ProcessRecord receiverOrangeApp = makeActiveProcessRecord(PACKAGE_ORANGE); 1750 1751 setProcessFreezable(receiverGreenApp, true, false); 1752 mQueue.onProcessFreezableChangedLocked(receiverGreenApp); 1753 setProcessFreezable(receiverBlueApp, false, true); 1754 mQueue.onProcessFreezableChangedLocked(receiverBlueApp); 1755 1756 final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK); 1757 final BroadcastOptions opts = BroadcastOptions.makeBasic() 1758 .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE); 1759 final List receivers = List.of( 1760 makeRegisteredReceiver(callerApp, 10), 1761 makeRegisteredReceiver(receiverGreenApp, 9), 1762 makeRegisteredReceiver(receiverBlueApp, 8), 1763 makeRegisteredReceiver(receiverYellowApp, 8), 1764 makeRegisteredReceiver(receiverOrangeApp, 7) 1765 ); 1766 enqueueBroadcast(makeBroadcastRecord(timeTick, callerApp, opts, receivers)); 1767 waitForIdle(); 1768 1769 // Green ignored since it's in cached state 1770 verifyScheduleRegisteredReceiver(never(), receiverGreenApp, timeTick); 1771 // Blue ignored since it's in cached state 1772 verifyScheduleRegisteredReceiver(never(), receiverBlueApp, timeTick); 1773 1774 final IApplicationThread redThread = mAms.getProcessRecordLocked(PACKAGE_RED, 1775 getUidForPackage(PACKAGE_RED)).getThread(); 1776 final IApplicationThread yellowThread = mAms.getProcessRecordLocked(PACKAGE_YELLOW, 1777 getUidForPackage(PACKAGE_YELLOW)).getThread(); 1778 final IApplicationThread orangeThread = mAms.getProcessRecordLocked(PACKAGE_ORANGE, 1779 getUidForPackage(PACKAGE_ORANGE)).getThread(); 1780 1781 // Verify apps that are not in cached state will receive the broadcast in the order 1782 // we expect. 1783 final InOrder inOrder = inOrder(redThread, yellowThread, orangeThread); 1784 inOrder.verify(redThread).scheduleRegisteredReceiver( 1785 any(), argThat(filterEqualsIgnoringComponent(timeTick)), 1786 anyInt(), any(), any(), anyBoolean(), anyBoolean(), anyBoolean(), 1787 eq(UserHandle.USER_SYSTEM), anyInt(), anyInt(), any()); 1788 inOrder.verify(yellowThread).scheduleRegisteredReceiver( 1789 any(), argThat(filterEqualsIgnoringComponent(timeTick)), 1790 anyInt(), any(), any(), anyBoolean(), anyBoolean(), anyBoolean(), 1791 eq(UserHandle.USER_SYSTEM), anyInt(), anyInt(), any()); 1792 inOrder.verify(orangeThread).scheduleRegisteredReceiver( 1793 any(), argThat(filterEqualsIgnoringComponent(timeTick)), 1794 anyInt(), any(), any(), anyBoolean(), anyBoolean(), anyBoolean(), 1795 eq(UserHandle.USER_SYSTEM), anyInt(), anyInt(), any()); 1796 1797 // Shift blue to be active and confirm that deferred broadcast is delivered 1798 setProcessFreezable(receiverBlueApp, false, false); 1799 mQueue.onProcessFreezableChangedLocked(receiverBlueApp); 1800 waitForIdle(); 1801 verifyScheduleRegisteredReceiver(times(1), receiverBlueApp, timeTick); 1802 1803 // Shift green to be active and confirm that deferred broadcast is delivered 1804 setProcessFreezable(receiverGreenApp, false, false); 1805 mQueue.onProcessFreezableChangedLocked(receiverGreenApp); 1806 waitForIdle(); 1807 verifyScheduleRegisteredReceiver(times(1), receiverGreenApp, timeTick); 1808 } 1809 1810 /** 1811 * Verify that we handle replacing a pending broadcast. 1812 */ 1813 @Test 1814 public void testReplacePending() throws Exception { 1815 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 1816 final IApplicationThread callerThread = callerApp.getThread(); 1817 1818 final Intent timezoneFirst = new Intent(Intent.ACTION_TIMEZONE_CHANGED); 1819 timezoneFirst.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 1820 timezoneFirst.putExtra(Intent.EXTRA_TIMEZONE, "GMT+5"); 1821 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 1822 final Intent timezoneSecond = new Intent(Intent.ACTION_TIMEZONE_CHANGED); 1823 timezoneSecond.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 1824 timezoneSecond.putExtra(Intent.EXTRA_TIMEZONE, "GMT-5"); 1825 1826 final IIntentReceiver resultToFirst = mock(IIntentReceiver.class); 1827 final IIntentReceiver resultToSecond = mock(IIntentReceiver.class); 1828 1829 enqueueBroadcast(makeOrderedBroadcastRecord(timezoneFirst, callerApp, 1830 List.of(makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE), 1831 makeManifestReceiver(PACKAGE_BLUE, CLASS_GREEN)), 1832 resultToFirst, null)); 1833 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, 1834 List.of(makeManifestReceiver(PACKAGE_BLUE, CLASS_RED)))); 1835 enqueueBroadcast(makeOrderedBroadcastRecord(timezoneSecond, callerApp, 1836 List.of(makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE), 1837 makeManifestReceiver(PACKAGE_BLUE, CLASS_GREEN)), 1838 resultToSecond, null)); 1839 1840 waitForIdle(); 1841 final IApplicationThread blueThread = mAms.getProcessRecordLocked(PACKAGE_BLUE, 1842 getUidForPackage(PACKAGE_BLUE)).getThread(); 1843 final InOrder inOrder = inOrder(callerThread, blueThread); 1844 1845 // First broadcast is canceled 1846 inOrder.verify(callerThread).scheduleRegisteredReceiver( 1847 any(), argThat(filterAndExtrasEquals(timezoneFirst)), 1848 eq(Activity.RESULT_CANCELED), any(), any(), 1849 eq(false), anyBoolean(), eq(true), eq(UserHandle.USER_SYSTEM), 1850 anyInt(), anyInt(), any()); 1851 1852 // We deliver second broadcast to app 1853 timezoneSecond.setClassName(PACKAGE_BLUE, CLASS_BLUE); 1854 inOrder.verify(blueThread).scheduleReceiver( 1855 argThat(filterAndExtrasEquals(timezoneSecond)), any(), any(), 1856 anyInt(), any(), any(), eq(true), eq(false), anyInt(), 1857 anyInt(), anyInt(), any()); 1858 timezoneSecond.setClassName(PACKAGE_BLUE, CLASS_GREEN); 1859 inOrder.verify(blueThread).scheduleReceiver( 1860 argThat(filterAndExtrasEquals(timezoneSecond)), any(), any(), 1861 anyInt(), any(), any(), eq(true), eq(false), anyInt(), 1862 anyInt(), anyInt(), any()); 1863 1864 // Second broadcast is finished 1865 timezoneSecond.setComponent(null); 1866 inOrder.verify(callerThread).scheduleRegisteredReceiver( 1867 any(), argThat(filterAndExtrasEquals(timezoneSecond)), 1868 eq(Activity.RESULT_OK), any(), any(), 1869 eq(false), anyBoolean(), eq(true), eq(UserHandle.USER_SYSTEM), 1870 anyInt(), anyInt(), any()); 1871 1872 // Since we "replaced" the first broadcast in its original position, 1873 // only now do we see the airplane broadcast 1874 airplane.setClassName(PACKAGE_BLUE, CLASS_RED); 1875 inOrder.verify(blueThread).scheduleReceiver( 1876 argThat(filterEquals(airplane)), any(), any(), 1877 anyInt(), any(), any(), eq(false), eq(false), anyInt(), 1878 anyInt(), anyInt(), any()); 1879 } 1880 1881 @Test 1882 public void testReplacePending_withPrioritizedBroadcasts() throws Exception { 1883 mConstants.MAX_RUNNING_ACTIVE_BROADCASTS = 1; 1884 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_GREEN); 1885 1886 final Intent userPresent = new Intent(Intent.ACTION_USER_PRESENT) 1887 .addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 1888 1889 final List receivers = List.of( 1890 withPriority(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN), 100), 1891 withPriority(makeManifestReceiver(PACKAGE_GREEN, CLASS_RED), 50), 1892 withPriority(makeManifestReceiver(PACKAGE_GREEN, CLASS_YELLOW), 10), 1893 withPriority(makeManifestReceiver(PACKAGE_GREEN, CLASS_BLUE), 0)); 1894 1895 // Enqueue the broadcast a few times and verify that broadcast queues are not stuck 1896 // and are emptied eventually. 1897 for (int i = 0; i < 6; ++i) { 1898 enqueueBroadcast(makeBroadcastRecord(userPresent, callerApp, receivers)); 1899 } 1900 waitForIdle(); 1901 } 1902 1903 @Test 1904 public void testReplacePending_withUrgentBroadcast() throws Exception { 1905 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 1906 1907 final Intent timeTickFirst = new Intent(Intent.ACTION_TIME_TICK); 1908 timeTickFirst.putExtra(Intent.EXTRA_INDEX, "one"); 1909 timeTickFirst.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 1910 timeTickFirst.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 1911 1912 final Intent timeTickSecond = new Intent(Intent.ACTION_TIME_TICK); 1913 timeTickFirst.putExtra(Intent.EXTRA_INDEX, "second"); 1914 timeTickSecond.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 1915 1916 final Intent timeTickThird = new Intent(Intent.ACTION_TIME_TICK); 1917 timeTickFirst.putExtra(Intent.EXTRA_INDEX, "third"); 1918 timeTickThird.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 1919 1920 enqueueBroadcast(makeBroadcastRecord(timeTickFirst, callerApp, 1921 List.of(makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE)))); 1922 enqueueBroadcast(makeBroadcastRecord(timeTickSecond, callerApp, 1923 List.of(makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE)))); 1924 enqueueBroadcast(makeBroadcastRecord(timeTickThird, callerApp, 1925 List.of(makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE)))); 1926 1927 waitForIdle(); 1928 final IApplicationThread blueThread = mAms.getProcessRecordLocked(PACKAGE_BLUE, 1929 getUidForPackage(PACKAGE_BLUE)).getThread(); 1930 final InOrder inOrder = inOrder(blueThread); 1931 1932 // First broadcast is delivered. 1933 timeTickFirst.setClassName(PACKAGE_BLUE, CLASS_BLUE); 1934 inOrder.verify(blueThread).scheduleReceiver( 1935 argThat(filterAndExtrasEquals(timeTickFirst)), any(), any(), 1936 anyInt(), any(), any(), eq(false), eq(false), anyInt(), 1937 anyInt(), anyInt(), any()); 1938 1939 // Second broadcast should be replaced by third broadcast. 1940 timeTickThird.setClassName(PACKAGE_BLUE, CLASS_BLUE); 1941 inOrder.verify(blueThread).scheduleReceiver( 1942 argThat(filterAndExtrasEquals(timeTickThird)), any(), any(), 1943 anyInt(), any(), any(), eq(false), eq(false), anyInt(), 1944 anyInt(), anyInt(), any()); 1945 } 1946 1947 @Test 1948 public void testReplacePending_diffReceivers() throws Exception { 1949 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 1950 final ProcessRecord receiverGreenApp = makeActiveProcessRecord(PACKAGE_GREEN); 1951 final ProcessRecord receiverBlueApp = makeActiveProcessRecord(PACKAGE_BLUE); 1952 final ProcessRecord receiverYellowApp = makeActiveProcessRecord(PACKAGE_YELLOW); 1953 final BroadcastFilter receiverGreen = makeRegisteredReceiver(receiverGreenApp); 1954 final BroadcastFilter receiverBlue = makeRegisteredReceiver(receiverBlueApp); 1955 final BroadcastFilter receiverYellow = makeRegisteredReceiver(receiverYellowApp); 1956 1957 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED) 1958 .addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 1959 1960 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, List.of( 1961 withPriority(receiverGreen, 10), 1962 withPriority(receiverBlue, 5), 1963 withPriority(receiverYellow, 0)))); 1964 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, List.of( 1965 withPriority(receiverGreen, 10), 1966 withPriority(receiverBlue, 5)))); 1967 1968 waitForIdle(); 1969 1970 verifyScheduleRegisteredReceiver(times(2), receiverGreenApp, airplane); 1971 verifyScheduleRegisteredReceiver(times(2), receiverBlueApp, airplane); 1972 verifyScheduleRegisteredReceiver(times(1), receiverYellowApp, airplane); 1973 } 1974 1975 @Test 1976 public void testReplacePending_sameProcess_diffReceivers() throws Exception { 1977 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 1978 final ProcessRecord receiverGreenApp = makeActiveProcessRecord(PACKAGE_GREEN); 1979 final BroadcastFilter receiverGreenA = makeRegisteredReceiver(receiverGreenApp); 1980 final BroadcastFilter receiverGreenB = makeRegisteredReceiver(receiverGreenApp); 1981 1982 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED) 1983 .addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 1984 1985 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, List.of( 1986 withPriority(receiverGreenA, 5)))); 1987 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, List.of( 1988 withPriority(receiverGreenB, 10), 1989 withPriority(receiverGreenA, 5)))); 1990 1991 waitForIdle(); 1992 // In the broadcast queue, we don't end up replacing the old broadcast to 1993 // avoid creating priority inversion and so the process will receive 1994 // both the old and new broadcasts. 1995 verifyScheduleRegisteredReceiver(times(3), receiverGreenApp, airplane); 1996 } 1997 1998 @Test 1999 public void testReplacePending_existingDiffReceivers() throws Exception { 2000 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 2001 final ProcessRecord receiverGreenApp = makeActiveProcessRecord(PACKAGE_GREEN); 2002 final ProcessRecord receiverBlueApp = makeActiveProcessRecord(PACKAGE_BLUE); 2003 final BroadcastFilter receiverGreen = makeRegisteredReceiver(receiverGreenApp); 2004 final BroadcastFilter receiverBlue = makeRegisteredReceiver(receiverBlueApp); 2005 2006 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED) 2007 .addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 2008 final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK); 2009 2010 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, List.of( 2011 withPriority(receiverGreen, 5)))); 2012 enqueueBroadcast(makeBroadcastRecord(timeTick, callerApp, List.of( 2013 withPriority(receiverGreen, 10), 2014 withPriority(receiverBlue, 5)))); 2015 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, List.of( 2016 withPriority(receiverBlue, 10), 2017 withPriority(receiverGreen, 5)))); 2018 2019 waitForIdle(); 2020 2021 verifyScheduleRegisteredReceiver(times(1), receiverGreenApp, timeTick); 2022 verifyScheduleRegisteredReceiver(times(1), receiverBlueApp, timeTick); 2023 verifyScheduleRegisteredReceiver(times(2), receiverGreenApp, airplane); 2024 verifyScheduleRegisteredReceiver(times(1), receiverBlueApp, airplane); 2025 } 2026 2027 @Test 2028 public void testReplacePending_withSingletonReceiver() throws Exception { 2029 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_PHONE); 2030 final ProcessRecord systemApp = makeActiveProcessRecord(PACKAGE_ANDROID, PROCESS_SYSTEM); 2031 2032 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED) 2033 .addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 2034 2035 final ResolveInfo systemReceiverA = makeManifestReceiver(PACKAGE_ANDROID, PROCESS_SYSTEM, 2036 CLASS_BLUE, USER_SYSTEM); 2037 final ResolveInfo systemReceiverB = makeManifestReceiver(PACKAGE_ANDROID, PROCESS_SYSTEM, 2038 CLASS_BLUE, USER_GUEST); 2039 2040 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, List.of( 2041 systemReceiverA, systemReceiverB))); 2042 2043 assertEquals("Unexpected userId for receiverA", USER_SYSTEM, 2044 UserHandle.getUserId(systemReceiverA.activityInfo.applicationInfo.uid)); 2045 assertEquals("Unexpected userId for receiverB", USER_SYSTEM, 2046 UserHandle.getUserId(systemReceiverB.activityInfo.applicationInfo.uid)); 2047 2048 waitForIdle(); 2049 2050 verifyScheduleReceiver(times(2), systemApp, airplane); 2051 } 2052 2053 @Test 2054 public void testReplacePendingToCachedProcess_withDeferrableBroadcast() throws Exception { 2055 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 2056 final ProcessRecord receiverGreenApp = makeActiveProcessRecord(PACKAGE_GREEN); 2057 final ProcessRecord receiverBlueApp = makeActiveProcessRecord(PACKAGE_BLUE); 2058 final ProcessRecord receiverYellowApp = makeActiveProcessRecord(PACKAGE_YELLOW); 2059 2060 setProcessFreezable(receiverGreenApp, true, false); 2061 mQueue.onProcessFreezableChangedLocked(receiverGreenApp); 2062 waitForIdle(); 2063 2064 final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK) 2065 .addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 2066 final BroadcastOptions opts = BroadcastOptions.makeBasic() 2067 .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE); 2068 2069 final BroadcastFilter receiverGreen = makeRegisteredReceiver(receiverGreenApp, 10); 2070 final BroadcastFilter receiverBlue = makeRegisteredReceiver(receiverBlueApp, 5); 2071 final BroadcastFilter receiverYellow = makeRegisteredReceiver(receiverYellowApp, 0); 2072 enqueueBroadcast(makeBroadcastRecord(timeTick, callerApp, opts, List.of( 2073 receiverGreen, receiverBlue, receiverYellow))); 2074 2075 // Enqueue the broadcast again to replace the earlier one 2076 enqueueBroadcast(makeBroadcastRecord(timeTick, callerApp, opts, List.of( 2077 receiverGreen, receiverBlue, receiverYellow))); 2078 2079 waitForIdle(); 2080 // Green should still be in the cached state and shouldn't receive the broadcast 2081 verifyScheduleRegisteredReceiver(never(), receiverGreenApp, timeTick); 2082 2083 final IApplicationThread blueThread = receiverBlueApp.getThread(); 2084 final IApplicationThread yellowThread = receiverYellowApp.getThread(); 2085 final InOrder inOrder = inOrder(blueThread, yellowThread); 2086 inOrder.verify(blueThread).scheduleRegisteredReceiver( 2087 any(), argThat(filterEqualsIgnoringComponent(timeTick)), 2088 anyInt(), any(), any(), anyBoolean(), anyBoolean(), anyBoolean(), 2089 eq(UserHandle.USER_SYSTEM), anyInt(), anyInt(), any()); 2090 inOrder.verify(yellowThread).scheduleRegisteredReceiver( 2091 any(), argThat(filterEqualsIgnoringComponent(timeTick)), 2092 anyInt(), any(), any(), anyBoolean(), anyBoolean(), anyBoolean(), 2093 eq(UserHandle.USER_SYSTEM), anyInt(), anyInt(), any()); 2094 2095 setProcessFreezable(receiverGreenApp, false, false); 2096 mQueue.onProcessFreezableChangedLocked(receiverGreenApp); 2097 waitForIdle(); 2098 2099 // Confirm that green receives the broadcast once it comes out of the cached state 2100 verifyScheduleRegisteredReceiver(times(1), receiverGreenApp, timeTick); 2101 } 2102 2103 @Test 2104 public void testIdleAndBarrier() throws Exception { 2105 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 2106 final ProcessRecord receiverApp = makeActiveProcessRecord(PACKAGE_GREEN); 2107 2108 final long beforeFirst; 2109 final long afterFirst; 2110 final long afterSecond; 2111 2112 beforeFirst = SystemClock.uptimeMillis() - 10; 2113 assertTrue(mQueue.isIdleLocked()); 2114 assertTrue(mQueue.isBeyondBarrierLocked(beforeFirst)); 2115 2116 final Intent timezone = new Intent(Intent.ACTION_TIMEZONE_CHANGED); 2117 enqueueBroadcast(makeBroadcastRecord(timezone, callerApp, 2118 List.of(makeRegisteredReceiver(receiverApp)))); 2119 afterFirst = SystemClock.uptimeMillis(); 2120 2121 assertFalse(mQueue.isIdleLocked()); 2122 assertTrue(mQueue.isBeyondBarrierLocked(beforeFirst)); 2123 assertFalse(mQueue.isBeyondBarrierLocked(afterFirst)); 2124 2125 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 2126 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, 2127 List.of(makeRegisteredReceiver(receiverApp)))); 2128 afterSecond = SystemClock.uptimeMillis() + 10; 2129 2130 assertFalse(mQueue.isIdleLocked()); 2131 assertTrue(mQueue.isBeyondBarrierLocked(beforeFirst)); 2132 assertFalse(mQueue.isBeyondBarrierLocked(afterFirst)); 2133 assertFalse(mQueue.isBeyondBarrierLocked(afterSecond)); 2134 2135 mLooper.release(); 2136 2137 mQueue.waitForBarrier(LOG_WRITER_INFO); 2138 assertTrue(mQueue.isBeyondBarrierLocked(afterFirst)); 2139 2140 mQueue.waitForIdle(LOG_WRITER_INFO); 2141 assertTrue(mQueue.isIdleLocked()); 2142 assertTrue(mQueue.isBeyondBarrierLocked(beforeFirst)); 2143 assertTrue(mQueue.isBeyondBarrierLocked(afterFirst)); 2144 assertTrue(mQueue.isBeyondBarrierLocked(afterSecond)); 2145 } 2146 2147 @Test 2148 public void testWaitForBroadcastDispatch() throws Exception { 2149 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 2150 final ProcessRecord receiverApp = makeActiveProcessRecord(PACKAGE_GREEN); 2151 2152 final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK); 2153 assertTrue(mQueue.isDispatchedLocked(timeTick)); 2154 2155 final Intent timezone = new Intent(Intent.ACTION_TIMEZONE_CHANGED); 2156 enqueueBroadcast(makeBroadcastRecord(timezone, callerApp, 2157 List.of(makeRegisteredReceiver(receiverApp)))); 2158 2159 assertTrue(mQueue.isDispatchedLocked(timeTick)); 2160 assertFalse(mQueue.isDispatchedLocked(timezone)); 2161 2162 enqueueBroadcast(makeBroadcastRecord(timeTick, callerApp, 2163 List.of(makeRegisteredReceiver(receiverApp)))); 2164 2165 assertFalse(mQueue.isDispatchedLocked(timeTick)); 2166 assertFalse(mQueue.isDispatchedLocked(timezone)); 2167 2168 mLooper.release(); 2169 2170 mQueue.waitForDispatched(timeTick, LOG_WRITER_INFO); 2171 assertTrue(mQueue.isDispatchedLocked(timeTick)); 2172 2173 mQueue.waitForDispatched(timezone, LOG_WRITER_INFO); 2174 assertTrue(mQueue.isDispatchedLocked(timezone)); 2175 } 2176 2177 /** 2178 * Verify that we OOM adjust for manifest receivers. 2179 */ 2180 @Test 2181 public void testOomAdjust_Manifest() throws Exception { 2182 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 2183 2184 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 2185 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, 2186 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN), 2187 makeManifestReceiver(PACKAGE_GREEN, CLASS_BLUE), 2188 makeManifestReceiver(PACKAGE_GREEN, CLASS_RED)))); 2189 2190 waitForIdle(); 2191 verify(mAms, atLeastOnce()).enqueueOomAdjTargetLocked(any()); 2192 } 2193 2194 /** 2195 * Verify that we OOM adjust for ordered broadcast receivers. 2196 */ 2197 @Test 2198 public void testOomAdjust_Ordered() throws Exception { 2199 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 2200 2201 final IIntentReceiver orderedResultTo = mock(IIntentReceiver.class); 2202 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 2203 enqueueBroadcast(makeOrderedBroadcastRecord(airplane, callerApp, 2204 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN), 2205 makeManifestReceiver(PACKAGE_GREEN, CLASS_BLUE), 2206 makeManifestReceiver(PACKAGE_GREEN, CLASS_RED)), orderedResultTo, null)); 2207 2208 waitForIdle(); 2209 verify(mAms, atLeastOnce()).enqueueOomAdjTargetLocked(any()); 2210 } 2211 2212 /** 2213 * Verify that we OOM adjust for resultTo broadcast receivers. 2214 */ 2215 @Test 2216 public void testOomAdjust_ResultTo() throws Exception { 2217 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 2218 2219 final IIntentReceiver resultTo = mock(IIntentReceiver.class); 2220 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 2221 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, 2222 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN), 2223 makeManifestReceiver(PACKAGE_GREEN, CLASS_BLUE), 2224 makeManifestReceiver(PACKAGE_GREEN, CLASS_RED)), resultTo)); 2225 2226 waitForIdle(); 2227 verify(mAms, atLeastOnce()).enqueueOomAdjTargetLocked(any()); 2228 } 2229 2230 /** 2231 * Verify that we never OOM adjust for registered receivers. 2232 */ 2233 @Test 2234 public void testOomAdjust_Registered() throws Exception { 2235 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 2236 final ProcessRecord receiverApp = makeActiveProcessRecord(PACKAGE_GREEN); 2237 2238 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 2239 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, 2240 List.of(makeRegisteredReceiver(receiverApp), 2241 makeRegisteredReceiver(receiverApp), 2242 makeRegisteredReceiver(receiverApp)))); 2243 2244 waitForIdle(); 2245 verify(mAms, never()).enqueueOomAdjTargetLocked(any()); 2246 } 2247 2248 /** 2249 * Confirm how many times a pathological broadcast pattern results in OOM 2250 * adjusts; watches for performance regressions. 2251 */ 2252 @Test 2253 public void testOomAdjust_TriggerCount() throws Exception { 2254 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 2255 2256 // Send 8 broadcasts, 4 receivers in the first process, 2257 // and 2 alternating in each of the remaining processes 2258 synchronized (mAms) { 2259 for (int i = 0; i < 8; i++) { 2260 final Intent intent = new Intent(Intent.ACTION_TIMEZONE_CHANGED); 2261 mQueue.enqueueBroadcastLocked(makeBroadcastRecord(intent, callerApp, 2262 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN), 2263 makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN), 2264 makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN), 2265 makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN), 2266 makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE), 2267 makeManifestReceiver(PACKAGE_YELLOW, CLASS_YELLOW), 2268 makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE), 2269 makeManifestReceiver(PACKAGE_YELLOW, CLASS_YELLOW)))); 2270 } 2271 } 2272 waitForIdle(); 2273 2274 // The broadcast queue requests once each time we promote a process to 2275 // running; we promote "green" twice, and "blue" and "yellow" once 2276 final int expectedTimes = 4; 2277 verify(mAms, times(expectedTimes)) 2278 .updateOomAdjPendingTargetsLocked(eq(OOM_ADJ_REASON_START_RECEIVER)); 2279 } 2280 2281 /** 2282 * Verify that expected events are triggered when a broadcast is finished. 2283 */ 2284 @Test 2285 public void testNotifyFinished() throws Exception { 2286 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 2287 2288 final Intent intent = new Intent(Intent.ACTION_TIMEZONE_CHANGED); 2289 final BroadcastRecord record = makeBroadcastRecord(intent, callerApp, 2290 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN))); 2291 enqueueBroadcast(record); 2292 2293 waitForIdle(); 2294 verify(mAms).notifyBroadcastFinishedLocked(eq(record)); 2295 verify(mAms).addBroadcastStatLocked(eq(Intent.ACTION_TIMEZONE_CHANGED), eq(PACKAGE_RED), 2296 eq(1), eq(0), anyLong()); 2297 } 2298 2299 /** 2300 * Verify that we skip broadcasts if {@link BroadcastSkipPolicy} decides it should be skipped. 2301 */ 2302 @Test 2303 public void testSkipPolicy() throws Exception { 2304 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 2305 final ProcessRecord receiverGreenApp = makeActiveProcessRecord(PACKAGE_GREEN); 2306 final ProcessRecord receiverBlueApp = makeActiveProcessRecord(PACKAGE_BLUE); 2307 2308 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 2309 final Object greenReceiver = makeRegisteredReceiver(receiverGreenApp); 2310 final Object blueReceiver = makeRegisteredReceiver(receiverBlueApp); 2311 final Object yellowReceiver = makeManifestReceiver(PACKAGE_YELLOW, CLASS_YELLOW); 2312 final Object orangeReceiver = makeManifestReceiver(PACKAGE_ORANGE, CLASS_ORANGE); 2313 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, 2314 List.of(greenReceiver, blueReceiver, yellowReceiver, orangeReceiver))); 2315 2316 doAnswer(invocation -> { 2317 final BroadcastRecord r = invocation.getArgument(0); 2318 final Object o = invocation.getArgument(1); 2319 if (airplane.getAction().equals(r.intent.getAction()) 2320 && (isReceiverEquals(o, greenReceiver) 2321 || isReceiverEquals(o, orangeReceiver))) { 2322 return "test skipped receiver"; 2323 } 2324 return null; 2325 }).when(mSkipPolicy).shouldSkipMessage(any(BroadcastRecord.class), any()); 2326 2327 waitForIdle(); 2328 // Verify that only blue and yellow receiver apps received the broadcast. 2329 verifyScheduleRegisteredReceiver(never(), receiverGreenApp, USER_SYSTEM); 2330 verifyScheduleRegisteredReceiver(receiverBlueApp, airplane); 2331 final ProcessRecord receiverYellowApp = mAms.getProcessRecordLocked(PACKAGE_YELLOW, 2332 getUidForPackage(PACKAGE_YELLOW)); 2333 verifyScheduleReceiver(receiverYellowApp, airplane); 2334 final ProcessRecord receiverOrangeApp = mAms.getProcessRecordLocked(PACKAGE_ORANGE, 2335 getUidForPackage(PACKAGE_ORANGE)); 2336 assertNull(receiverOrangeApp); 2337 } 2338 2339 /** 2340 * Verify that we skip broadcasts at enqueue if {@link BroadcastSkipPolicy} decides it 2341 * should be skipped. 2342 */ 2343 @EnableFlags(Flags.FLAG_AVOID_NOTE_OP_AT_ENQUEUE) 2344 @Test 2345 public void testSkipPolicy_atEnqueueTime() throws Exception { 2346 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 2347 final ProcessRecord receiverGreenApp = makeActiveProcessRecord(PACKAGE_GREEN); 2348 final ProcessRecord receiverBlueApp = makeActiveProcessRecord(PACKAGE_BLUE); 2349 2350 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 2351 final Object greenReceiver = makeRegisteredReceiver(receiverGreenApp); 2352 final Object blueReceiver = makeRegisteredReceiver(receiverBlueApp); 2353 final Object yellowReceiver = makeManifestReceiver(PACKAGE_YELLOW, CLASS_YELLOW); 2354 final Object orangeReceiver = makeManifestReceiver(PACKAGE_ORANGE, CLASS_ORANGE); 2355 2356 doAnswer(invocation -> { 2357 final BroadcastRecord r = invocation.getArgument(0); 2358 final Object o = invocation.getArgument(1); 2359 if (airplane.getAction().equals(r.intent.getAction()) 2360 && (isReceiverEquals(o, greenReceiver) 2361 || isReceiverEquals(o, orangeReceiver))) { 2362 return "test skipped receiver"; 2363 } 2364 return null; 2365 }).when(mSkipPolicy).shouldSkipAtEnqueueMessage(any(BroadcastRecord.class), any()); 2366 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, 2367 List.of(greenReceiver, blueReceiver, yellowReceiver, orangeReceiver))); 2368 2369 waitForIdle(); 2370 // Verify that only blue and yellow receiver apps received the broadcast. 2371 verifyScheduleRegisteredReceiver(never(), receiverGreenApp, USER_SYSTEM); 2372 verify(mSkipPolicy, never()).shouldSkipMessage(any(BroadcastRecord.class), 2373 eq(greenReceiver)); 2374 verifyScheduleRegisteredReceiver(receiverBlueApp, airplane); 2375 final ProcessRecord receiverYellowApp = mAms.getProcessRecordLocked(PACKAGE_YELLOW, 2376 getUidForPackage(PACKAGE_YELLOW)); 2377 verifyScheduleReceiver(receiverYellowApp, airplane); 2378 final ProcessRecord receiverOrangeApp = mAms.getProcessRecordLocked(PACKAGE_ORANGE, 2379 getUidForPackage(PACKAGE_ORANGE)); 2380 assertNull(receiverOrangeApp); 2381 verify(mSkipPolicy, never()).shouldSkipMessage(any(BroadcastRecord.class), 2382 eq(orangeReceiver)); 2383 } 2384 2385 /** 2386 * Verify broadcasts to runtime receivers in cached processes are deferred 2387 * until that process leaves the cached state. 2388 */ 2389 @Test 2390 public void testDeferralPolicy_UntilActive() throws Exception { 2391 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 2392 final ProcessRecord receiverGreenApp = makeActiveProcessRecord(PACKAGE_GREEN); 2393 final ProcessRecord receiverBlueApp = makeActiveProcessRecord(PACKAGE_BLUE); 2394 final ProcessRecord receiverYellowApp = makeActiveProcessRecord(PACKAGE_YELLOW); 2395 2396 setProcessFreezable(receiverGreenApp, true, true); 2397 mQueue.onProcessFreezableChangedLocked(receiverGreenApp); 2398 setProcessFreezable(receiverBlueApp, true, false); 2399 mQueue.onProcessFreezableChangedLocked(receiverBlueApp); 2400 setProcessFreezable(receiverYellowApp, false, false); 2401 mQueue.onProcessFreezableChangedLocked(receiverYellowApp); 2402 2403 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 2404 final BroadcastOptions opts = BroadcastOptions.makeBasic() 2405 .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE); 2406 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, opts, 2407 List.of(makeRegisteredReceiver(receiverGreenApp), 2408 makeRegisteredReceiver(receiverBlueApp), 2409 makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE), 2410 makeRegisteredReceiver(receiverYellowApp)))); 2411 waitForIdle(); 2412 2413 // Green ignored since it's in cached state 2414 verifyScheduleRegisteredReceiver(never(), receiverGreenApp, airplane); 2415 2416 // Blue delivered both since it has a manifest receiver 2417 verifyScheduleReceiver(times(1), receiverBlueApp, airplane); 2418 verifyScheduleRegisteredReceiver(times(1), receiverBlueApp, airplane); 2419 2420 // Yellow delivered since it's not cached 2421 verifyScheduleRegisteredReceiver(times(1), receiverYellowApp, airplane); 2422 2423 // Shift green to be active and confirm that deferred broadcast is delivered 2424 setProcessFreezable(receiverGreenApp, false, false); 2425 mQueue.onProcessFreezableChangedLocked(receiverGreenApp); 2426 waitForIdle(); 2427 verifyScheduleRegisteredReceiver(times(1), receiverGreenApp, airplane); 2428 } 2429 2430 /** 2431 * Verify broadcasts to a runtime receiver in cached process is deferred even when a different 2432 * process in the same package is not cached. 2433 */ 2434 @Test 2435 public void testDeferralPolicy_UntilActive_WithMultiProcessUid() throws Exception { 2436 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 2437 final ProcessRecord receiverGreenApp1 = makeActiveProcessRecord(PACKAGE_GREEN); 2438 final ProcessRecord receiverGreenApp2 = makeActiveProcessRecord(PACKAGE_GREEN, 2439 PACKAGE_GREEN + "_proc2"); 2440 2441 setProcessFreezable(receiverGreenApp1, true, true); 2442 mQueue.onProcessFreezableChangedLocked(receiverGreenApp1); 2443 2444 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 2445 final BroadcastOptions opts = BroadcastOptions.makeBasic() 2446 .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE); 2447 enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, opts, 2448 List.of(makeRegisteredReceiver(receiverGreenApp1), 2449 makeRegisteredReceiver(receiverGreenApp2)))); 2450 waitForIdle(); 2451 2452 // 1st process in Green package is ignored since it is in a cached state 2453 // but the 2nd process should still receive the broadcast. 2454 verifyScheduleRegisteredReceiver(never(), receiverGreenApp1, airplane); 2455 verifyScheduleRegisteredReceiver(times(1), receiverGreenApp2, airplane); 2456 2457 // Shift the 1st process in Green package to be active and confirm that deferred broadcast 2458 // is delivered 2459 setProcessFreezable(receiverGreenApp1, false, false); 2460 mQueue.onProcessFreezableChangedLocked(receiverGreenApp1); 2461 waitForIdle(); 2462 verifyScheduleRegisteredReceiver(times(1), receiverGreenApp1, airplane); 2463 } 2464 2465 @Test 2466 public void testBroadcastDelivery_uidForeground() throws Exception { 2467 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 2468 final ProcessRecord receiverBlueApp = makeActiveProcessRecord(PACKAGE_BLUE); 2469 final ProcessRecord receiverGreenApp = makeActiveProcessRecord(PACKAGE_GREEN); 2470 2471 mUidObserver.onUidStateChanged(receiverGreenApp.info.uid, 2472 ActivityManager.PROCESS_STATE_TOP, 0, ActivityManager.PROCESS_CAPABILITY_NONE); 2473 waitForIdle(); 2474 2475 final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 2476 final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK); 2477 2478 final BroadcastFilter receiverBlue = makeRegisteredReceiver(receiverBlueApp); 2479 final BroadcastFilter receiverGreen = makeRegisteredReceiver(receiverGreenApp); 2480 final BroadcastRecord airplaneRecord = makeBroadcastRecord(airplane, callerApp, 2481 List.of(receiverBlue)); 2482 final BroadcastRecord timeTickRecord = makeBroadcastRecord(timeTick, callerApp, 2483 List.of(receiverBlue, receiverGreen)); 2484 2485 enqueueBroadcast(airplaneRecord); 2486 enqueueBroadcast(timeTickRecord); 2487 2488 waitForIdle(); 2489 // Verify that broadcasts to receiverGreenApp gets scheduled first. 2490 assertThat(getReceiverScheduledTime(timeTickRecord, receiverGreen)) 2491 .isLessThan(getReceiverScheduledTime(airplaneRecord, receiverBlue)); 2492 assertThat(getReceiverScheduledTime(timeTickRecord, receiverGreen)) 2493 .isLessThan(getReceiverScheduledTime(timeTickRecord, receiverBlue)); 2494 } 2495 2496 @DisableFlags(Flags.FLAG_LIMIT_PRIORITY_SCOPE) 2497 @Test 2498 public void testPrioritizedBroadcastDelivery_uidForeground_flagDisabled() throws Exception { 2499 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 2500 final ProcessRecord receiverBlueApp = makeActiveProcessRecord(PACKAGE_BLUE); 2501 final ProcessRecord receiverGreenApp = makeActiveProcessRecord(PACKAGE_GREEN); 2502 2503 mUidObserver.onUidStateChanged(receiverGreenApp.info.uid, 2504 ActivityManager.PROCESS_STATE_TOP, 0, ActivityManager.PROCESS_CAPABILITY_NONE); 2505 waitForIdle(); 2506 2507 final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK); 2508 2509 final BroadcastFilter receiverBlue = makeRegisteredReceiver(receiverBlueApp, 10); 2510 final BroadcastFilter receiverGreen = makeRegisteredReceiver(receiverGreenApp, 5); 2511 final BroadcastRecord prioritizedRecord = makeBroadcastRecord(timeTick, callerApp, 2512 List.of(receiverBlue, receiverGreen)); 2513 2514 enqueueBroadcast(prioritizedRecord); 2515 2516 waitForIdle(); 2517 // Verify that uid foreground-ness does not impact that delivery of prioritized broadcast. 2518 // That is, broadcast to receiverBlueApp gets scheduled before the one to receiverGreenApp. 2519 assertThat(getReceiverScheduledTime(prioritizedRecord, receiverGreen)) 2520 .isGreaterThan(getReceiverScheduledTime(prioritizedRecord, receiverBlue)); 2521 } 2522 2523 @Test 2524 public void testOrderedBroadcastDelivery_uidForeground() throws Exception { 2525 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 2526 final ProcessRecord receiverBlueApp = makeActiveProcessRecord(PACKAGE_BLUE); 2527 final ProcessRecord receiverGreenApp = makeActiveProcessRecord(PACKAGE_GREEN); 2528 2529 mUidObserver.onUidStateChanged(receiverGreenApp.info.uid, 2530 ActivityManager.PROCESS_STATE_TOP, 0, ActivityManager.PROCESS_CAPABILITY_NONE); 2531 waitForIdle(); 2532 2533 final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK); 2534 2535 final BroadcastFilter receiverBlue = makeRegisteredReceiver(receiverBlueApp, 10); 2536 final BroadcastFilter receiverGreen = makeRegisteredReceiver(receiverGreenApp, 5); 2537 final IIntentReceiver resultTo = mock(IIntentReceiver.class); 2538 final BroadcastRecord prioritizedRecord = makeOrderedBroadcastRecord(timeTick, callerApp, 2539 List.of(receiverBlue, receiverGreen), resultTo, null); 2540 2541 enqueueBroadcast(prioritizedRecord); 2542 2543 waitForIdle(); 2544 // Verify that uid foreground-ness does not impact that delivery of prioritized broadcast. 2545 // That is, broadcast to receiverBlueApp gets scheduled before the one to receiverGreenApp. 2546 assertThat(getReceiverScheduledTime(prioritizedRecord, receiverGreen)) 2547 .isGreaterThan(getReceiverScheduledTime(prioritizedRecord, receiverBlue)); 2548 } 2549 2550 @EnableFlags(Flags.FLAG_LIMIT_PRIORITY_SCOPE) 2551 @Test 2552 public void testPrioritizedBroadcastDelivery_uidForeground_changeIdDisabled() throws Exception { 2553 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 2554 final ProcessRecord receiverBlueApp = makeActiveProcessRecord(PACKAGE_BLUE); 2555 final ProcessRecord receiverGreenApp = makeActiveProcessRecord(PACKAGE_GREEN); 2556 2557 doReturn(false).when(mPlatformCompat).isChangeEnabledInternalNoLogging( 2558 eq(BroadcastRecord.LIMIT_PRIORITY_SCOPE), 2559 argThat(appInfoEquals(receiverBlueApp.uid))); 2560 2561 mUidObserver.onUidStateChanged(receiverGreenApp.info.uid, 2562 ActivityManager.PROCESS_STATE_TOP, 0, ActivityManager.PROCESS_CAPABILITY_NONE); 2563 waitForIdle(); 2564 2565 final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK); 2566 2567 final BroadcastFilter receiverBlue = makeRegisteredReceiver(receiverBlueApp, 10); 2568 final BroadcastFilter receiverGreen = makeRegisteredReceiver(receiverGreenApp, 5); 2569 final BroadcastRecord prioritizedRecord = makeBroadcastRecord(timeTick, callerApp, 2570 List.of(receiverBlue, receiverGreen)); 2571 2572 enqueueBroadcast(prioritizedRecord); 2573 2574 waitForIdle(); 2575 // Verify that uid foreground-ness does not impact that delivery of prioritized broadcast. 2576 // That is, broadcast to receiverBlueApp gets scheduled before the one to receiverGreenApp. 2577 assertThat(getReceiverScheduledTime(prioritizedRecord, receiverGreen)) 2578 .isGreaterThan(getReceiverScheduledTime(prioritizedRecord, receiverBlue)); 2579 } 2580 2581 @Test 2582 @RequiresFlagsEnabled(Flags.FLAG_DEFER_OUTGOING_BROADCASTS) 2583 public void testDeferOutgoingBroadcasts() throws Exception { 2584 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 2585 setProcessFreezable(callerApp, true /* pendingFreeze */, false /* frozen */); 2586 mQueue.onProcessFreezableChangedLocked(callerApp); 2587 waitForIdle(); 2588 2589 final ProcessRecord receiverGreenApp = makeActiveProcessRecord(PACKAGE_GREEN); 2590 final ProcessRecord receiverBlueApp = makeActiveProcessRecord(PACKAGE_BLUE); 2591 final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK); 2592 enqueueBroadcast(makeBroadcastRecord(timeTick, callerApp, List.of( 2593 makeRegisteredReceiver(receiverGreenApp), 2594 makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE), 2595 makeManifestReceiver(PACKAGE_YELLOW, CLASS_YELLOW)))); 2596 // Verify that we invoke the call to freeze the caller app. 2597 verify(mAms.mOomAdjuster.mCachedAppOptimizer).freezeAppAsyncImmediateLSP(callerApp); 2598 2599 waitForIdle(); 2600 verifyScheduleRegisteredReceiver(never(), receiverGreenApp, timeTick); 2601 verifyScheduleReceiver(never(), receiverBlueApp, timeTick); 2602 assertNull(mAms.getProcessRecordLocked(PACKAGE_YELLOW, getUidForPackage(PACKAGE_GREEN))); 2603 2604 setProcessFreezable(callerApp, false /* pendingFreeze */, false /* frozen */); 2605 mQueue.onProcessFreezableChangedLocked(callerApp); 2606 waitForIdle(); 2607 2608 verifyScheduleRegisteredReceiver(times(1), receiverGreenApp, timeTick); 2609 verifyScheduleReceiver(times(1), receiverBlueApp, timeTick); 2610 final ProcessRecord receiverYellowApp = mAms.getProcessRecordLocked(PACKAGE_YELLOW, 2611 getUidForPackage(PACKAGE_YELLOW)); 2612 verifyScheduleReceiver(times(1), receiverYellowApp, timeTick); 2613 } 2614 2615 @Test 2616 @RequiresFlagsEnabled(Flags.FLAG_DEFER_OUTGOING_BROADCASTS) 2617 public void testKillProcess_excessiveOutgoingBroadcastsWhileCached() throws Exception { 2618 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 2619 setProcessFreezable(callerApp, true /* pendingFreeze */, false /* frozen */); 2620 waitForIdle(); 2621 2622 final int count = mConstants.MAX_FROZEN_OUTGOING_BROADCASTS + 1; 2623 for (int i = 0; i < count; ++i) { 2624 final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK + "_" + i); 2625 enqueueBroadcast(makeBroadcastRecord(timeTick, callerApp, List.of( 2626 makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE)))); 2627 } 2628 // Verify that we invoke the call to freeze the caller app. 2629 verify(mAms.mOomAdjuster.mCachedAppOptimizer, atLeastOnce()) 2630 .freezeAppAsyncImmediateLSP(callerApp); 2631 2632 // Verify that the caller process is killed 2633 assertTrue(callerApp.isKilled()); 2634 verify(mProcessList).noteAppKill(same(callerApp), 2635 eq(ApplicationExitInfo.REASON_OTHER), 2636 eq(ApplicationExitInfo.SUBREASON_EXCESSIVE_OUTGOING_BROADCASTS_WHILE_CACHED), 2637 any(String.class)); 2638 2639 waitForIdle(); 2640 assertNull(mAms.getProcessRecordLocked(PACKAGE_BLUE, getUidForPackage(PACKAGE_BLUE))); 2641 } 2642 2643 @Test 2644 public void testBroadcastAppStartInfoReported() throws Exception { 2645 final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); 2646 2647 final Intent timezone = new Intent(Intent.ACTION_TIME_TICK); 2648 enqueueBroadcast(makeBroadcastRecord(timezone, callerApp, 2649 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN)))); 2650 2651 waitForIdle(); 2652 2653 verify(mAppStartInfoTracker, times(1)).handleProcessBroadcastStart(anyLong(), any(), any(), 2654 anyBoolean()); 2655 } 2656 2657 private long getReceiverScheduledTime(@NonNull BroadcastRecord r, @NonNull Object receiver) { 2658 for (int i = 0; i < r.receivers.size(); ++i) { 2659 if (isReceiverEquals(receiver, r.receivers.get(i))) { 2660 return r.scheduledTime[i]; 2661 } 2662 } 2663 fail(receiver + "not found in " + r); 2664 return -1; 2665 } 2666 } 2667