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