• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
21 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
22 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
23 import static com.android.internal.util.FrameworkStatsLog.BROADCAST_DELIVERY_EVENT_REPORTED;
24 import static com.android.internal.util.FrameworkStatsLog.BROADCAST_DELIVERY_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_COLD;
25 import static com.android.internal.util.FrameworkStatsLog.BROADCAST_DELIVERY_EVENT_REPORTED__RECEIVER_TYPE__MANIFEST;
26 import static com.android.server.am.ActivityManagerDebugConfig.LOG_WRITER_INFO;
27 import static com.android.server.am.BroadcastProcessQueue.REASON_CONTAINS_ALARM;
28 import static com.android.server.am.BroadcastProcessQueue.REASON_CONTAINS_FOREGROUND;
29 import static com.android.server.am.BroadcastProcessQueue.REASON_CONTAINS_INTERACTIVE;
30 import static com.android.server.am.BroadcastProcessQueue.REASON_CONTAINS_MANIFEST;
31 import static com.android.server.am.BroadcastProcessQueue.REASON_CONTAINS_ORDERED;
32 import static com.android.server.am.BroadcastProcessQueue.REASON_CONTAINS_PRIORITIZED;
33 import static com.android.server.am.BroadcastProcessQueue.insertIntoRunnableList;
34 import static com.android.server.am.BroadcastProcessQueue.removeFromRunnableList;
35 import static com.android.server.am.BroadcastRecord.isReceiverEquals;
36 
37 import static com.google.common.truth.Truth.assertThat;
38 
39 import static org.junit.Assert.assertEquals;
40 import static org.junit.Assert.assertFalse;
41 import static org.junit.Assert.assertNotEquals;
42 import static org.junit.Assert.assertNull;
43 import static org.junit.Assert.assertTrue;
44 import static org.junit.Assert.fail;
45 import static org.mockito.ArgumentMatchers.any;
46 import static org.mockito.ArgumentMatchers.anyBoolean;
47 import static org.mockito.ArgumentMatchers.anyInt;
48 import static org.mockito.ArgumentMatchers.anyLong;
49 import static org.mockito.ArgumentMatchers.anyString;
50 import static org.mockito.ArgumentMatchers.argThat;
51 import static org.mockito.ArgumentMatchers.eq;
52 import static org.mockito.ArgumentMatchers.nullable;
53 import static org.mockito.Mockito.doAnswer;
54 import static org.mockito.Mockito.mock;
55 import static org.mockito.Mockito.spy;
56 import static org.mockito.Mockito.times;
57 
58 import android.annotation.NonNull;
59 import android.app.Activity;
60 import android.app.ActivityManager;
61 import android.app.AppOpsManager;
62 import android.app.BackgroundStartPrivileges;
63 import android.app.BroadcastOptions;
64 import android.appwidget.AppWidgetManager;
65 import android.content.IIntentReceiver;
66 import android.content.Intent;
67 import android.content.IntentFilter;
68 import android.content.pm.ApplicationInfo;
69 import android.media.AudioManager;
70 import android.os.Bundle;
71 import android.os.BundleMerger;
72 import android.os.DropBoxManager;
73 import android.os.Process;
74 import android.os.SystemClock;
75 import android.os.UserHandle;
76 import android.platform.test.annotations.DisableFlags;
77 import android.platform.test.annotations.EnableFlags;
78 import android.util.IndentingPrintWriter;
79 import android.util.Pair;
80 
81 import androidx.test.filters.SmallTest;
82 import androidx.test.platform.app.InstrumentationRegistry;
83 
84 import com.android.internal.util.FrameworkStatsLog;
85 
86 import org.junit.After;
87 import org.junit.Before;
88 import org.junit.Test;
89 import org.mockito.Mock;
90 import org.mockito.Mockito;
91 
92 import java.io.PrintWriter;
93 import java.io.Writer;
94 import java.lang.reflect.Array;
95 import java.util.ArrayList;
96 import java.util.List;
97 import java.util.Objects;
98 
99 @SmallTest
100 public final class BroadcastQueueImplTest extends BaseBroadcastQueueTest {
101     private static final String TAG = "BroadcastQueueImplTest";
102 
103     private static final int TEST_UID = android.os.Process.FIRST_APPLICATION_UID;
104     private static final int TEST_UID2 = android.os.Process.FIRST_APPLICATION_UID + 1;
105 
106     ProcessRecord mProcess;
107 
108     @Mock BroadcastProcessQueue mQueue1;
109     @Mock BroadcastProcessQueue mQueue2;
110     @Mock BroadcastProcessQueue mQueue3;
111     @Mock BroadcastProcessQueue mQueue4;
112 
113     BroadcastQueueImpl mImpl;
114 
115     BroadcastProcessQueue mHead;
116 
117     @Before
setUp()118     public void setUp() throws Exception {
119         super.setUp();
120 
121         mConstants.DELAY_URGENT_MILLIS = -120_000;
122         mConstants.DELAY_NORMAL_MILLIS = 10_000;
123         mConstants.DELAY_CACHED_MILLIS = 120_000;
124 
125         mImpl = new BroadcastQueueImpl(mAms, mHandlerThread.getThreadHandler(),
126                 mConstants, mConstants, mSkipPolicy, mEmptyHistory);
127         mAms.setBroadcastQueueForTest(mImpl);
128 
129         doReturn(1L).when(mQueue1).getRunnableAt();
130         doReturn(2L).when(mQueue2).getRunnableAt();
131         doReturn(3L).when(mQueue3).getRunnableAt();
132         doReturn(4L).when(mQueue4).getRunnableAt();
133 
134         final ApplicationInfo ai = makeApplicationInfo(PACKAGE_ORANGE);
135         mProcess = spy(new ProcessRecord(mAms, ai, ai.processName, ai.uid));
136     }
137 
138     @After
tearDown()139     public void tearDown() throws Exception {
140         super.tearDown();
141     }
142 
143     @Override
getTag()144     public String getTag() {
145         return TAG;
146     }
147 
148     /**
149      * Un-pause our handler to process pending events, wait for our queue to go
150      * idle, and then re-pause the handler.
151      */
waitForIdle()152     private void waitForIdle() throws Exception {
153         mLooper.release();
154         mImpl.waitForIdle(LOG_WRITER_INFO);
155         mLooper = Objects.requireNonNull(InstrumentationRegistry.getInstrumentation()
156                 .acquireLooperManager(mHandlerThread.getLooper()));
157     }
158 
assertOrphan(BroadcastProcessQueue queue)159     private static void assertOrphan(BroadcastProcessQueue queue) {
160         assertNull(queue.runnableAtNext);
161         assertNull(queue.runnableAtPrev);
162     }
163 
assertRunnableList(@onNull List<BroadcastProcessQueue> expected, @NonNull BroadcastProcessQueue actualHead)164     private static void assertRunnableList(@NonNull List<BroadcastProcessQueue> expected,
165             @NonNull BroadcastProcessQueue actualHead) {
166         BroadcastProcessQueue test = actualHead;
167         final int N = expected.size();
168         for (int i = 0; i < N; i++) {
169             final BroadcastProcessQueue expectedPrev = (i > 0) ? expected.get(i - 1) : null;
170             final BroadcastProcessQueue expectedTest = expected.get(i);
171             final BroadcastProcessQueue expectedNext = (i < N - 1) ? expected.get(i + 1) : null;
172 
173             assertEquals("prev", expectedPrev, test.runnableAtPrev);
174             assertEquals("test", expectedTest, test);
175             assertEquals("next", expectedNext, test.runnableAtNext);
176 
177             test = test.runnableAtNext;
178         }
179         if (N == 0) {
180             assertNull(actualHead);
181         }
182     }
183 
makeMockIntent()184     private static Intent makeMockIntent() {
185         return mock(Intent.class);
186     }
187 
makeMockRegisteredReceiver()188     private static BroadcastFilter makeMockRegisteredReceiver() {
189         final BroadcastFilter filter = mock(BroadcastFilter.class);
190         final ApplicationInfo info = makeApplicationInfo(PACKAGE_ORANGE);
191         doReturn(info).when(filter).getApplicationInfo();
192         return filter;
193     }
194 
makeBroadcastRecord(Intent intent)195     private BroadcastRecord makeBroadcastRecord(Intent intent) {
196         return makeBroadcastRecord(intent, BroadcastOptions.makeBasic(),
197                 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN)), false);
198     }
199 
makeBroadcastRecord(Intent intent, List receivers)200     private BroadcastRecord makeBroadcastRecord(Intent intent, List receivers) {
201         return makeBroadcastRecord(intent, BroadcastOptions.makeBasic(), receivers, false);
202     }
203 
makeBroadcastRecord(Intent intent, BroadcastOptions options)204     private BroadcastRecord makeBroadcastRecord(Intent intent, BroadcastOptions options) {
205         return makeBroadcastRecord(intent, options,
206                 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN)), false);
207     }
208 
makeBroadcastRecord(Intent intent, BroadcastOptions options, List receivers, boolean ordered)209     private BroadcastRecord makeBroadcastRecord(Intent intent, BroadcastOptions options,
210             List receivers, boolean ordered) {
211         return makeBroadcastRecord(intent, options, receivers, null, ordered);
212     }
213 
makeBroadcastRecord(Intent intent, BroadcastOptions options, List receivers, IIntentReceiver resultTo, boolean ordered)214     private BroadcastRecord makeBroadcastRecord(Intent intent, BroadcastOptions options,
215             List receivers, IIntentReceiver resultTo, boolean ordered) {
216         return new BroadcastRecord(mImpl, intent, mProcess, PACKAGE_RED, null, 21, TEST_UID, false,
217                 null, null, null, null, AppOpsManager.OP_NONE, options, receivers, null, resultTo,
218                 Activity.RESULT_OK, null, null, ordered, false, false, UserHandle.USER_SYSTEM,
219                 BackgroundStartPrivileges.NONE, false, null, PROCESS_STATE_UNKNOWN,
220                 mPlatformCompat);
221     }
222 
enqueueOrReplaceBroadcast(BroadcastProcessQueue queue, BroadcastRecord record, int recordIndex)223     private void enqueueOrReplaceBroadcast(BroadcastProcessQueue queue,
224             BroadcastRecord record, int recordIndex) {
225         enqueueOrReplaceBroadcast(queue, record, recordIndex, 42_000_000L);
226     }
227 
enqueueOrReplaceBroadcast(BroadcastProcessQueue queue, BroadcastRecord record, int recordIndex, long enqueueTime)228     private void enqueueOrReplaceBroadcast(BroadcastProcessQueue queue,
229             BroadcastRecord record, int recordIndex, long enqueueTime) {
230         record.enqueueTime = enqueueTime;
231         record.enqueueRealTime = enqueueTime;
232         record.enqueueClockTime = enqueueTime;
233         queue.enqueueOrReplaceBroadcast(record, recordIndex, (r, i) -> {
234             throw new UnsupportedOperationException();
235         });
236     }
237 
238     @Test
testRunnableList_Simple()239     public void testRunnableList_Simple() {
240         assertRunnableList(List.of(), mHead);
241 
242         mHead = insertIntoRunnableList(mHead, mQueue1);
243         assertRunnableList(List.of(mQueue1), mHead);
244 
245         mHead = removeFromRunnableList(mHead, mQueue1);
246         assertRunnableList(List.of(), mHead);
247     }
248 
249     @Test
testRunnableList_InsertLast()250     public void testRunnableList_InsertLast() {
251         mHead = insertIntoRunnableList(mHead, mQueue1);
252         mHead = insertIntoRunnableList(mHead, mQueue2);
253         mHead = insertIntoRunnableList(mHead, mQueue3);
254         mHead = insertIntoRunnableList(mHead, mQueue4);
255         assertRunnableList(List.of(mQueue1, mQueue2, mQueue3, mQueue4), mHead);
256     }
257 
258     @Test
testRunnableList_InsertFirst()259     public void testRunnableList_InsertFirst() {
260         mHead = insertIntoRunnableList(mHead, mQueue4);
261         mHead = insertIntoRunnableList(mHead, mQueue3);
262         mHead = insertIntoRunnableList(mHead, mQueue2);
263         mHead = insertIntoRunnableList(mHead, mQueue1);
264         assertRunnableList(List.of(mQueue1, mQueue2, mQueue3, mQueue4), mHead);
265     }
266 
267     @Test
testRunnableList_InsertMiddle()268     public void testRunnableList_InsertMiddle() {
269         mHead = insertIntoRunnableList(mHead, mQueue1);
270         mHead = insertIntoRunnableList(mHead, mQueue3);
271         mHead = insertIntoRunnableList(mHead, mQueue2);
272         assertRunnableList(List.of(mQueue1, mQueue2, mQueue3), mHead);
273     }
274 
275     @Test
testRunnableList_Remove()276     public void testRunnableList_Remove() {
277         mHead = insertIntoRunnableList(mHead, mQueue1);
278         mHead = insertIntoRunnableList(mHead, mQueue2);
279         mHead = insertIntoRunnableList(mHead, mQueue3);
280         mHead = insertIntoRunnableList(mHead, mQueue4);
281 
282         mHead = removeFromRunnableList(mHead, mQueue3);
283         assertRunnableList(List.of(mQueue1, mQueue2, mQueue4), mHead);
284 
285         mHead = removeFromRunnableList(mHead, mQueue1);
286         assertRunnableList(List.of(mQueue2, mQueue4), mHead);
287 
288         mHead = removeFromRunnableList(mHead, mQueue4);
289         assertRunnableList(List.of(mQueue2), mHead);
290 
291         mHead = removeFromRunnableList(mHead, mQueue2);
292         assertRunnableList(List.of(), mHead);
293 
294         // Verify all links cleaned up during removal
295         assertOrphan(mQueue1);
296         assertOrphan(mQueue2);
297         assertOrphan(mQueue3);
298         assertOrphan(mQueue4);
299     }
300 
301     @Test
testRunnableList_sameRunnableAt()302     public void testRunnableList_sameRunnableAt() {
303         doReturn(2L).when(mQueue1).getRunnableAt();
304         doReturn(2L).when(mQueue2).getRunnableAt();
305         doReturn(2L).when(mQueue3).getRunnableAt();
306         doReturn(2L).when(mQueue4).getRunnableAt();
307 
308         mHead = insertIntoRunnableList(mHead, mQueue1);
309         mHead = insertIntoRunnableList(mHead, mQueue2);
310         mHead = insertIntoRunnableList(mHead, mQueue3);
311         mHead = insertIntoRunnableList(mHead, mQueue4);
312         assertRunnableList(List.of(mQueue1, mQueue2, mQueue3, mQueue4), mHead);
313     }
314 
315     @Test
testProcessQueue_Complex()316     public void testProcessQueue_Complex() {
317         BroadcastProcessQueue red = mImpl.getOrCreateProcessQueue(PACKAGE_RED, TEST_UID);
318         BroadcastProcessQueue green = mImpl.getOrCreateProcessQueue(PACKAGE_GREEN, TEST_UID);
319         BroadcastProcessQueue blue = mImpl.getOrCreateProcessQueue(PACKAGE_BLUE, TEST_UID);
320 
321         assertEquals(PACKAGE_RED, red.processName);
322         assertEquals(PACKAGE_GREEN, green.processName);
323         assertEquals(PACKAGE_BLUE, blue.processName);
324 
325         // Verify that removing middle queue works
326         mImpl.removeProcessQueue(PACKAGE_GREEN, TEST_UID);
327         assertEquals(red, mImpl.getProcessQueue(PACKAGE_RED, TEST_UID));
328         assertNull(mImpl.getProcessQueue(PACKAGE_GREEN, TEST_UID));
329         assertEquals(blue, mImpl.getProcessQueue(PACKAGE_BLUE, TEST_UID));
330         assertNull(mImpl.getProcessQueue(PACKAGE_YELLOW, TEST_UID));
331 
332         // Verify that removing head queue works
333         mImpl.removeProcessQueue(PACKAGE_RED, TEST_UID);
334         assertNull(mImpl.getProcessQueue(PACKAGE_RED, TEST_UID));
335         assertNull(mImpl.getProcessQueue(PACKAGE_GREEN, TEST_UID));
336         assertEquals(blue, mImpl.getProcessQueue(PACKAGE_BLUE, TEST_UID));
337         assertNull(mImpl.getProcessQueue(PACKAGE_YELLOW, TEST_UID));
338 
339         // Verify that removing last queue works
340         mImpl.removeProcessQueue(PACKAGE_BLUE, TEST_UID);
341         assertNull(mImpl.getProcessQueue(PACKAGE_RED, TEST_UID));
342         assertNull(mImpl.getProcessQueue(PACKAGE_GREEN, TEST_UID));
343         assertNull(mImpl.getProcessQueue(PACKAGE_BLUE, TEST_UID));
344         assertNull(mImpl.getProcessQueue(PACKAGE_YELLOW, TEST_UID));
345 
346         // Verify that removing missing doesn't crash
347         mImpl.removeProcessQueue(PACKAGE_YELLOW, TEST_UID);
348 
349         // Verify that we can start all over again safely
350         BroadcastProcessQueue yellow = mImpl.getOrCreateProcessQueue(PACKAGE_YELLOW, TEST_UID);
351         assertEquals(yellow, mImpl.getProcessQueue(PACKAGE_YELLOW, TEST_UID));
352     }
353 
354     /**
355      * Empty queue isn't runnable.
356      */
357     @Test
testRunnableAt_Empty()358     public void testRunnableAt_Empty() {
359         final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants,
360                 PACKAGE_GREEN, getUidForPackage(PACKAGE_GREEN));
361         assertFalse(queue.isRunnable());
362         assertEquals(Long.MAX_VALUE, queue.getRunnableAt());
363         assertEquals(ProcessList.SCHED_GROUP_UNDEFINED, queue.getPreferredSchedulingGroupLocked());
364     }
365 
366     /**
367      * Queue with a "normal" and "deferrable" broadcast is runnable at different times depending
368      * on process cached state; when cached it's delayed indefinitely.
369      */
370     @Test
testRunnableAt_Normal_Deferrable()371     public void testRunnableAt_Normal_Deferrable() {
372         final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants,
373                 PACKAGE_GREEN, getUidForPackage(PACKAGE_GREEN));
374 
375         final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
376         final BroadcastOptions options = BroadcastOptions.makeBasic()
377                 .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE);
378         final BroadcastRecord airplaneRecord = makeBroadcastRecord(airplane, options,
379                 List.of(makeMockRegisteredReceiver()), false);
380         enqueueOrReplaceBroadcast(queue, airplaneRecord, 0);
381 
382         queue.setProcessAndUidState(mProcess, false, false);
383         final long notCachedRunnableAt = queue.getRunnableAt();
384         queue.setProcessAndUidState(mProcess, false, true);
385         final long cachedRunnableAt = queue.getRunnableAt();
386         assertThat(cachedRunnableAt).isGreaterThan(notCachedRunnableAt);
387         assertFalse(queue.isRunnable());
388         assertEquals(BroadcastProcessQueue.REASON_CACHED_INFINITE_DEFER,
389                 queue.getRunnableAtReason());
390         assertTrue(queue.shouldBeDeferred());
391         assertEquals(ProcessList.SCHED_GROUP_UNDEFINED, queue.getPreferredSchedulingGroupLocked());
392     }
393 
394     /**
395      * Queue with a "normal" broadcast is runnable at different times depending
396      * on process cached state; when cached it's delayed by some amount.
397      */
398     @Test
testRunnableAt_Normal()399     public void testRunnableAt_Normal() {
400         final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants,
401                 PACKAGE_GREEN, getUidForPackage(PACKAGE_GREEN));
402 
403         final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
404         final BroadcastOptions options = BroadcastOptions.makeBasic()
405                 .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_NONE);
406         final BroadcastRecord airplaneRecord = makeBroadcastRecord(airplane, options,
407                 List.of(makeMockRegisteredReceiver()), false);
408         enqueueOrReplaceBroadcast(queue, airplaneRecord, 0);
409 
410         queue.setProcessAndUidState(mProcess, false, false);
411         final long notCachedRunnableAt = queue.getRunnableAt();
412         queue.setProcessAndUidState(mProcess, false, true);
413         final long cachedRunnableAt = queue.getRunnableAt();
414         assertThat(cachedRunnableAt).isGreaterThan(notCachedRunnableAt);
415         assertTrue(queue.isRunnable());
416         assertEquals(BroadcastProcessQueue.REASON_CACHED, queue.getRunnableAtReason());
417         assertTrue(queue.shouldBeDeferred());
418         assertEquals(ProcessList.SCHED_GROUP_UNDEFINED, queue.getPreferredSchedulingGroupLocked());
419     }
420 
421     /**
422      * Queue with foreground broadcast is always runnable immediately,
423      * regardless of process cached state.
424      */
425     @Test
testRunnableAt_Foreground()426     public void testRunnableAt_Foreground() {
427         final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants,
428                 PACKAGE_GREEN, getUidForPackage(PACKAGE_GREEN));
429 
430         // enqueue a bg-priority broadcast then a fg-priority one
431         final Intent timezone = new Intent(Intent.ACTION_TIMEZONE_CHANGED);
432         final BroadcastRecord timezoneRecord = makeBroadcastRecord(timezone);
433         enqueueOrReplaceBroadcast(queue, timezoneRecord, 0);
434 
435         final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
436         airplane.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
437         final BroadcastRecord airplaneRecord = makeBroadcastRecord(airplane);
438         enqueueOrReplaceBroadcast(queue, airplaneRecord, 0);
439 
440         // verify that:
441         // (a) the queue is immediately runnable by existence of a fg-priority broadcast
442         // (b) the next one up is the fg-priority broadcast despite its later enqueue time
443         queue.setProcessAndUidState(null, false, false);
444         assertTrue(queue.isRunnable());
445         assertThat(queue.getRunnableAt()).isAtMost(airplaneRecord.enqueueClockTime);
446         assertEquals(ProcessList.SCHED_GROUP_UNDEFINED, queue.getPreferredSchedulingGroupLocked());
447         assertEquals(queue.peekNextBroadcastRecord(), airplaneRecord);
448 
449         queue.setProcessAndUidState(null, false, true);
450         assertTrue(queue.isRunnable());
451         assertThat(queue.getRunnableAt()).isAtMost(airplaneRecord.enqueueClockTime);
452         assertEquals(ProcessList.SCHED_GROUP_UNDEFINED, queue.getPreferredSchedulingGroupLocked());
453         assertEquals(queue.peekNextBroadcastRecord(), airplaneRecord);
454     }
455 
456     /**
457      * Queue with ordered broadcast is runnable only once we've made enough
458      * progress on earlier blocking items.
459      */
460     @Test
testRunnableAt_Ordered()461     public void testRunnableAt_Ordered() {
462         final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants,
463                 PACKAGE_GREEN, getUidForPackage(PACKAGE_GREEN));
464 
465         final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
466         final BroadcastRecord airplaneRecord = makeBroadcastRecord(airplane, null,
467                 List.of(withPriority(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN), 10),
468                         withPriority(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN), 0)), true);
469         enqueueOrReplaceBroadcast(queue, airplaneRecord, 1);
470 
471         assertFalse(queue.isRunnable());
472         assertEquals(BroadcastProcessQueue.REASON_BLOCKED, queue.getRunnableAtReason());
473 
474         // Bumping past barrier makes us now runnable
475         airplaneRecord.setDeliveryState(0, BroadcastRecord.DELIVERY_DELIVERED,
476                 "testRunnableAt_Ordered");
477         queue.invalidateRunnableAt();
478         assertTrue(queue.isRunnable());
479         assertNotEquals(BroadcastProcessQueue.REASON_BLOCKED, queue.getRunnableAtReason());
480     }
481 
482     /**
483      * Queue with too many pending broadcasts is runnable.
484      */
485     @Test
testRunnableAt_Huge()486     public void testRunnableAt_Huge() {
487         BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants,
488                 PACKAGE_GREEN, getUidForPackage(PACKAGE_GREEN));
489 
490         final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
491         final BroadcastRecord airplaneRecord = makeBroadcastRecord(airplane,
492                 List.of(makeMockRegisteredReceiver()));
493         enqueueOrReplaceBroadcast(queue, airplaneRecord, 0);
494 
495         mConstants.MAX_PENDING_BROADCASTS = 128;
496         queue.invalidateRunnableAt();
497         assertThat(queue.getRunnableAt()).isGreaterThan(airplaneRecord.enqueueTime);
498         assertEquals(BroadcastProcessQueue.REASON_NORMAL, queue.getRunnableAtReason());
499         assertFalse(queue.shouldBeDeferred());
500 
501         mConstants.MAX_PENDING_BROADCASTS = 1;
502         queue.invalidateRunnableAt();
503         assertThat(queue.getRunnableAt()).isAtMost(airplaneRecord.enqueueTime);
504         assertEquals(BroadcastProcessQueue.REASON_MAX_PENDING, queue.getRunnableAtReason());
505         assertFalse(queue.shouldBeDeferred());
506     }
507 
508     @Test
testRunnableAt_uidForeground()509     public void testRunnableAt_uidForeground() {
510         final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants, PACKAGE_GREEN,
511                 getUidForPackage(PACKAGE_GREEN));
512 
513         final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK);
514         final BroadcastRecord timeTickRecord = makeBroadcastRecord(timeTick,
515                 List.of(makeMockRegisteredReceiver()));
516         enqueueOrReplaceBroadcast(queue, timeTickRecord, 0);
517 
518         assertThat(queue.getRunnableAt()).isGreaterThan(timeTickRecord.enqueueTime);
519         assertEquals(BroadcastProcessQueue.REASON_NORMAL, queue.getRunnableAtReason());
520 
521         queue.setProcessAndUidState(mProcess, true, false);
522         assertThat(queue.getRunnableAt()).isLessThan(timeTickRecord.enqueueTime);
523         assertEquals(BroadcastProcessQueue.REASON_FOREGROUND, queue.getRunnableAtReason());
524         assertFalse(queue.shouldBeDeferred());
525 
526         queue.setProcessAndUidState(mProcess, false, false);
527         assertThat(queue.getRunnableAt()).isGreaterThan(timeTickRecord.enqueueTime);
528         assertEquals(BroadcastProcessQueue.REASON_NORMAL, queue.getRunnableAtReason());
529         assertFalse(queue.shouldBeDeferred());
530     }
531 
532     @Test
testRunnableAt_processTop()533     public void testRunnableAt_processTop() {
534         final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants, PACKAGE_GREEN,
535                 getUidForPackage(PACKAGE_GREEN));
536 
537         doReturn(ActivityManager.PROCESS_STATE_TOP).when(mProcess).getSetProcState();
538         queue.setProcessAndUidState(mProcess, false, false);
539 
540         final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK);
541         final BroadcastRecord timeTickRecord = makeBroadcastRecord(timeTick,
542                 List.of(makeMockRegisteredReceiver()));
543         enqueueOrReplaceBroadcast(queue, timeTickRecord, 0);
544 
545         assertThat(queue.getRunnableAt()).isLessThan(timeTickRecord.enqueueTime);
546         assertEquals(BroadcastProcessQueue.REASON_TOP_PROCESS, queue.getRunnableAtReason());
547         assertFalse(queue.shouldBeDeferred());
548 
549         doReturn(ActivityManager.PROCESS_STATE_SERVICE).when(mProcess).getSetProcState();
550         queue.setProcessAndUidState(mProcess, false, false);
551 
552         // The new process state will only be taken into account the next time a broadcast
553         // is sent to the process.
554         enqueueOrReplaceBroadcast(queue, makeBroadcastRecord(timeTick,
555                 List.of(makeMockRegisteredReceiver())), 0);
556         assertThat(queue.getRunnableAt()).isGreaterThan(timeTickRecord.enqueueTime);
557         assertEquals(BroadcastProcessQueue.REASON_NORMAL, queue.getRunnableAtReason());
558         assertFalse(queue.shouldBeDeferred());
559     }
560 
561     @Test
testRunnableAt_persistentProc()562     public void testRunnableAt_persistentProc() {
563         final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants, PACKAGE_GREEN,
564                 getUidForPackage(PACKAGE_GREEN));
565 
566         final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK);
567         final BroadcastRecord timeTickRecord = makeBroadcastRecord(timeTick,
568                 List.of(makeMockRegisteredReceiver()));
569         enqueueOrReplaceBroadcast(queue, timeTickRecord, 0);
570 
571         assertThat(queue.getRunnableAt()).isGreaterThan(timeTickRecord.enqueueTime);
572         assertEquals(BroadcastProcessQueue.REASON_NORMAL, queue.getRunnableAtReason());
573         assertFalse(queue.shouldBeDeferred());
574 
575         doReturn(true).when(mProcess).isPersistent();
576         queue.setProcessAndUidState(mProcess, false, false);
577         assertThat(queue.getRunnableAt()).isLessThan(timeTickRecord.enqueueTime);
578         assertEquals(BroadcastProcessQueue.REASON_PERSISTENT, queue.getRunnableAtReason());
579         assertFalse(queue.shouldBeDeferred());
580 
581         doReturn(false).when(mProcess).isPersistent();
582         queue.setProcessAndUidState(mProcess, false, false);
583         assertThat(queue.getRunnableAt()).isGreaterThan(timeTickRecord.enqueueTime);
584         assertEquals(BroadcastProcessQueue.REASON_NORMAL, queue.getRunnableAtReason());
585         assertFalse(queue.shouldBeDeferred());
586     }
587 
588     @Test
testRunnableAt_coreUid()589     public void testRunnableAt_coreUid() {
590         final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants,
591                 "com.android.bluetooth", Process.BLUETOOTH_UID);
592 
593         final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK);
594         final BroadcastRecord timeTickRecord = makeBroadcastRecord(timeTick,
595                 List.of(makeMockRegisteredReceiver()));
596         enqueueOrReplaceBroadcast(queue, timeTickRecord, 0);
597 
598         assertThat(queue.getRunnableAt()).isEqualTo(timeTickRecord.enqueueTime);
599         assertEquals(BroadcastProcessQueue.REASON_CORE_UID, queue.getRunnableAtReason());
600         assertFalse(queue.shouldBeDeferred());
601     }
602 
603     @Test
testRunnableAt_freezableCoreUid()604     public void testRunnableAt_freezableCoreUid() {
605         final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants,
606                 "com.android.bluetooth", Process.BLUETOOTH_UID);
607 
608         // Mark the process as freezable
609         queue.setProcessAndUidState(mProcess, false, true);
610         final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK);
611         final BroadcastOptions options = BroadcastOptions.makeWithDeferUntilActive(true);
612         final BroadcastRecord timeTickRecord = makeBroadcastRecord(timeTick, options,
613                 List.of(makeMockRegisteredReceiver()), false);
614         enqueueOrReplaceBroadcast(queue, timeTickRecord, 0);
615 
616         assertEquals(Long.MAX_VALUE, queue.getRunnableAt());
617         assertEquals(BroadcastProcessQueue.REASON_CACHED_INFINITE_DEFER,
618                 queue.getRunnableAtReason());
619         assertTrue(queue.shouldBeDeferred());
620 
621         queue.setProcessAndUidState(mProcess, false, false);
622         assertThat(queue.getRunnableAt()).isEqualTo(timeTickRecord.enqueueTime);
623         assertEquals(BroadcastProcessQueue.REASON_CORE_UID, queue.getRunnableAtReason());
624         assertFalse(queue.shouldBeDeferred());
625     }
626 
627     /**
628      * Verify that a cached process that would normally be delayed becomes
629      * immediately runnable when the given broadcast is enqueued.
630      */
doRunnableAt_Cached(BroadcastRecord testRecord, int testRunnableAtReason)631     private void doRunnableAt_Cached(BroadcastRecord testRecord, int testRunnableAtReason) {
632         final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants,
633                 PACKAGE_GREEN, getUidForPackage(PACKAGE_GREEN));
634         queue.setProcessAndUidState(null, false, true);
635 
636         final BroadcastRecord lazyRecord = makeBroadcastRecord(
637                 new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED),
638                 List.of(makeMockRegisteredReceiver()));
639 
640         enqueueOrReplaceBroadcast(queue, lazyRecord, 0);
641         assertThat(queue.getRunnableAt()).isGreaterThan(lazyRecord.enqueueTime);
642         assertThat(queue.getRunnableAtReason()).isNotEqualTo(testRunnableAtReason);
643 
644         enqueueOrReplaceBroadcast(queue, testRecord, 0);
645         assertThat(queue.getRunnableAt()).isAtMost(testRecord.enqueueTime);
646         assertThat(queue.getRunnableAtReason()).isEqualTo(testRunnableAtReason);
647     }
648 
649     @Test
testRunnableAt_Cached_Manifest()650     public void testRunnableAt_Cached_Manifest() {
651         doRunnableAt_Cached(makeBroadcastRecord(makeMockIntent(), null,
652                 List.of(makeManifestReceiver(PACKAGE_RED, CLASS_RED)), null, false),
653                 REASON_CONTAINS_MANIFEST);
654     }
655 
656     @Test
testRunnableAt_Cached_Ordered()657     public void testRunnableAt_Cached_Ordered() {
658         doRunnableAt_Cached(makeBroadcastRecord(makeMockIntent(), null,
659                 List.of(makeMockRegisteredReceiver()), null, true), REASON_CONTAINS_ORDERED);
660     }
661 
662     @Test
testRunnableAt_Cached_Foreground()663     public void testRunnableAt_Cached_Foreground() {
664         final Intent foregroundIntent = new Intent();
665         foregroundIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
666         doRunnableAt_Cached(makeBroadcastRecord(foregroundIntent, null,
667                 List.of(makeMockRegisteredReceiver()), null, false), REASON_CONTAINS_FOREGROUND);
668     }
669 
670     @Test
testRunnableAt_Cached_Interactive()671     public void testRunnableAt_Cached_Interactive() {
672         final BroadcastOptions options = BroadcastOptions.makeBasic();
673         options.setInteractive(true);
674         doRunnableAt_Cached(makeBroadcastRecord(makeMockIntent(), options,
675                 List.of(makeMockRegisteredReceiver()), null, false), REASON_CONTAINS_INTERACTIVE);
676     }
677 
678     @Test
testRunnableAt_Cached_Alarm()679     public void testRunnableAt_Cached_Alarm() {
680         final BroadcastOptions options = BroadcastOptions.makeBasic();
681         options.setAlarmBroadcast(true);
682         doRunnableAt_Cached(makeBroadcastRecord(makeMockIntent(), options,
683                 List.of(makeMockRegisteredReceiver()), null, false), REASON_CONTAINS_ALARM);
684     }
685 
686     @DisableFlags(Flags.FLAG_LIMIT_PRIORITY_SCOPE)
687     @Test
testRunnableAt_Cached_Prioritized_NonDeferrable_flagDisabled()688     public void testRunnableAt_Cached_Prioritized_NonDeferrable_flagDisabled() {
689         final List receivers = List.of(
690                 withPriority(makeManifestReceiver(PACKAGE_RED, PACKAGE_RED), 10),
691                 withPriority(makeManifestReceiver(PACKAGE_GREEN, PACKAGE_GREEN), -10));
692         final BroadcastOptions options = BroadcastOptions.makeBasic()
693                 .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_NONE);
694         doRunnableAt_Cached(makeBroadcastRecord(makeMockIntent(), options,
695                 receivers, null, false), REASON_CONTAINS_PRIORITIZED);
696     }
697 
698     @EnableFlags(Flags.FLAG_LIMIT_PRIORITY_SCOPE)
699     @Test
testRunnableAt_Cached_Prioritized_NonDeferrable()700     public void testRunnableAt_Cached_Prioritized_NonDeferrable() {
701         final List receivers = List.of(
702                 withPriority(makeManifestReceiver(PACKAGE_RED, PACKAGE_RED), 10),
703                 withPriority(makeManifestReceiver(PACKAGE_GREEN, PACKAGE_GREEN), -10));
704         final BroadcastOptions options = BroadcastOptions.makeBasic()
705                 .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_NONE);
706         doRunnableAt_Cached(makeBroadcastRecord(makeMockIntent(), options,
707                 receivers, null, false), REASON_CONTAINS_MANIFEST);
708     }
709 
710     @Test
testRunnableAt_Cached_Ordered_NonDeferrable()711     public void testRunnableAt_Cached_Ordered_NonDeferrable() {
712         final List receivers = List.of(
713                 withPriority(makeManifestReceiver(PACKAGE_RED, PACKAGE_RED), 10),
714                 withPriority(makeManifestReceiver(PACKAGE_GREEN, PACKAGE_GREEN), -10));
715         final BroadcastOptions options = BroadcastOptions.makeBasic()
716                 .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_NONE);
717         doRunnableAt_Cached(makeBroadcastRecord(makeMockIntent(), options,
718                 receivers, mock(IIntentReceiver.class), true), REASON_CONTAINS_ORDERED);
719     }
720 
721     @EnableFlags(Flags.FLAG_LIMIT_PRIORITY_SCOPE)
722     @Test
testRunnableAt_Cached_Prioritized_NonDeferrable_changeIdDisabled()723     public void testRunnableAt_Cached_Prioritized_NonDeferrable_changeIdDisabled() {
724         doReturn(false).when(mPlatformCompat).isChangeEnabledInternalNoLogging(
725                 eq(BroadcastRecord.LIMIT_PRIORITY_SCOPE),
726                 argThat(appInfoEquals(getUidForPackage(PACKAGE_GREEN))));
727         final List receivers = List.of(
728                 withPriority(makeManifestReceiver(PACKAGE_RED, PACKAGE_RED), 10),
729                 withPriority(makeManifestReceiver(PACKAGE_GREEN, PACKAGE_GREEN), -10));
730         final BroadcastOptions options = BroadcastOptions.makeBasic()
731                 .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_NONE);
732         doRunnableAt_Cached(makeBroadcastRecord(makeMockIntent(), options,
733                 receivers, null, false), REASON_CONTAINS_PRIORITIZED);
734     }
735 
736     /**
737      * Confirm that we always prefer running pending items marked as "urgent",
738      * then "normal", then "offload", dispatching by the relative ordering
739      * within each of those clustering groups.
740      */
741     @Test
testMakeActiveNextPending()742     public void testMakeActiveNextPending() {
743         BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants,
744                 PACKAGE_GREEN, getUidForPackage(PACKAGE_GREEN));
745 
746         enqueueOrReplaceBroadcast(queue,
747                 makeBroadcastRecord(new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED)
748                         .addFlags(Intent.FLAG_RECEIVER_OFFLOAD)), 0);
749         enqueueOrReplaceBroadcast(queue,
750                 makeBroadcastRecord(new Intent(Intent.ACTION_TIMEZONE_CHANGED)), 0);
751         enqueueOrReplaceBroadcast(queue,
752                 makeBroadcastRecord(new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
753                         .addFlags(Intent.FLAG_RECEIVER_FOREGROUND)), 0);
754         enqueueOrReplaceBroadcast(queue,
755                 makeBroadcastRecord(new Intent(Intent.ACTION_ALARM_CHANGED)
756                         .addFlags(Intent.FLAG_RECEIVER_OFFLOAD)), 0);
757         enqueueOrReplaceBroadcast(queue,
758                 makeBroadcastRecord(new Intent(Intent.ACTION_TIME_TICK)), 0);
759         enqueueOrReplaceBroadcast(queue,
760                 makeBroadcastRecord(new Intent(Intent.ACTION_LOCALE_CHANGED)
761                         .addFlags(Intent.FLAG_RECEIVER_FOREGROUND)), 0);
762 
763         queue.makeActiveNextPending();
764         assertEquals(Intent.ACTION_LOCKED_BOOT_COMPLETED, queue.getActive().intent.getAction());
765 
766         // To maximize test coverage, dump current state; we're not worried
767         // about the actual output, just that we don't crash
768         queue.getActive().setDeliveryState(0, BroadcastRecord.DELIVERY_SCHEDULED, "Test-driven");
769         queue.dumpLocked(SystemClock.uptimeMillis(),
770                 new IndentingPrintWriter(new PrintWriter(Writer.nullWriter())));
771 
772         queue.makeActiveNextPending();
773         assertEquals(Intent.ACTION_LOCALE_CHANGED, queue.getActive().intent.getAction());
774         queue.makeActiveNextPending();
775         assertEquals(Intent.ACTION_TIMEZONE_CHANGED, queue.getActive().intent.getAction());
776         queue.makeActiveNextPending();
777         assertEquals(Intent.ACTION_TIME_TICK, queue.getActive().intent.getAction());
778         queue.makeActiveNextPending();
779         assertEquals(Intent.ACTION_AIRPLANE_MODE_CHANGED, queue.getActive().intent.getAction());
780         queue.makeActiveNextPending();
781         assertEquals(Intent.ACTION_ALARM_CHANGED, queue.getActive().intent.getAction());
782         assertTrue(queue.isEmpty());
783     }
784 
785     /**
786      * Verify that we don't let urgent broadcasts starve delivery of non-urgent
787      */
788     @Test
testUrgentStarvation()789     public void testUrgentStarvation() {
790         final BroadcastOptions optInteractive = BroadcastOptions.makeBasic();
791         optInteractive.setInteractive(true);
792 
793         mConstants.MAX_CONSECUTIVE_URGENT_DISPATCHES = 2;
794         BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants,
795                 PACKAGE_GREEN, getUidForPackage(PACKAGE_GREEN));
796         long timeCounter = 100;
797 
798         // mix of broadcasts, with more than 2 fg/urgent
799         enqueueOrReplaceBroadcast(queue,
800                 makeBroadcastRecord(new Intent(Intent.ACTION_TIMEZONE_CHANGED)),
801                         0, timeCounter++);
802         enqueueOrReplaceBroadcast(queue,
803                 makeBroadcastRecord(new Intent(Intent.ACTION_ALARM_CHANGED)),
804                         0, timeCounter++);
805         enqueueOrReplaceBroadcast(queue,
806                 makeBroadcastRecord(new Intent(Intent.ACTION_TIME_TICK)), 0, timeCounter++);
807         enqueueOrReplaceBroadcast(queue,
808                 makeBroadcastRecord(new Intent(Intent.ACTION_LOCALE_CHANGED)
809                         .addFlags(Intent.FLAG_RECEIVER_FOREGROUND)), 0, timeCounter++);
810         enqueueOrReplaceBroadcast(queue,
811                 makeBroadcastRecord(new Intent(Intent.ACTION_APPLICATION_PREFERENCES),
812                         optInteractive), 0, timeCounter++);
813         enqueueOrReplaceBroadcast(queue,
814                 makeBroadcastRecord(new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE),
815                         optInteractive), 0, timeCounter++);
816         enqueueOrReplaceBroadcast(queue,
817                 makeBroadcastRecord(new Intent(Intent.ACTION_INPUT_METHOD_CHANGED)
818                         .addFlags(Intent.FLAG_RECEIVER_FOREGROUND)), 0, timeCounter++);
819         enqueueOrReplaceBroadcast(queue,
820                 makeBroadcastRecord(new Intent(Intent.ACTION_NEW_OUTGOING_CALL),
821                         optInteractive), 0, timeCounter++);
822 
823         queue.makeActiveNextPending();
824         assertEquals(Intent.ACTION_LOCALE_CHANGED, queue.getActive().intent.getAction());
825         queue.makeActiveNextPending();
826         assertEquals(Intent.ACTION_APPLICATION_PREFERENCES, queue.getActive().intent.getAction());
827         // after MAX_CONSECUTIVE_URGENT_DISPATCHES expect an ordinary one next
828         queue.makeActiveNextPending();
829         assertEquals(Intent.ACTION_TIMEZONE_CHANGED, queue.getActive().intent.getAction());
830         // and then back to prioritizing urgent ones
831         queue.makeActiveNextPending();
832         assertEquals(AppWidgetManager.ACTION_APPWIDGET_UPDATE,
833                 queue.getActive().intent.getAction());
834         queue.makeActiveNextPending();
835         assertEquals(Intent.ACTION_INPUT_METHOD_CHANGED, queue.getActive().intent.getAction());
836         // verify the reset-count-then-resume worked too
837         queue.makeActiveNextPending();
838         assertEquals(Intent.ACTION_ALARM_CHANGED, queue.getActive().intent.getAction());
839     }
840 
841     /**
842      * Verify that offload broadcasts are not starved because of broadcasts in higher priority
843      * queues.
844      */
845     @Test
testOffloadStarvation()846     public void testOffloadStarvation() {
847         final BroadcastOptions optInteractive = BroadcastOptions.makeBasic();
848         optInteractive.setInteractive(true);
849 
850         mConstants.MAX_CONSECUTIVE_URGENT_DISPATCHES = 1;
851         mConstants.MAX_CONSECUTIVE_NORMAL_DISPATCHES = 2;
852         final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants,
853                 PACKAGE_GREEN, getUidForPackage(PACKAGE_GREEN));
854         long timeCounter = 100;
855 
856         // mix of broadcasts, with more than 2 normal
857         enqueueOrReplaceBroadcast(queue,
858                 makeBroadcastRecord(new Intent(Intent.ACTION_BOOT_COMPLETED)
859                         .addFlags(Intent.FLAG_RECEIVER_OFFLOAD)), 0, timeCounter++);
860         enqueueOrReplaceBroadcast(queue,
861                 makeBroadcastRecord(new Intent(Intent.ACTION_TIMEZONE_CHANGED)),
862                         0, timeCounter++);
863         enqueueOrReplaceBroadcast(queue,
864                 makeBroadcastRecord(new Intent(Intent.ACTION_PACKAGE_CHANGED)
865                         .addFlags(Intent.FLAG_RECEIVER_OFFLOAD)), 0, timeCounter++);
866         enqueueOrReplaceBroadcast(queue,
867                 makeBroadcastRecord(new Intent(Intent.ACTION_ALARM_CHANGED)),
868                 0, timeCounter++);
869         enqueueOrReplaceBroadcast(queue,
870                 makeBroadcastRecord(new Intent(Intent.ACTION_TIME_TICK)), 0, timeCounter++);
871         enqueueOrReplaceBroadcast(queue,
872                 makeBroadcastRecord(new Intent(Intent.ACTION_LOCALE_CHANGED)
873                         .addFlags(Intent.FLAG_RECEIVER_FOREGROUND)), 0, timeCounter++);
874         enqueueOrReplaceBroadcast(queue,
875                 makeBroadcastRecord(new Intent(Intent.ACTION_APPLICATION_PREFERENCES),
876                         optInteractive), 0, timeCounter++);
877         enqueueOrReplaceBroadcast(queue,
878                 makeBroadcastRecord(new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE),
879                         optInteractive), 0, timeCounter++);
880         enqueueOrReplaceBroadcast(queue,
881                 makeBroadcastRecord(new Intent(Intent.ACTION_INPUT_METHOD_CHANGED)
882                         .addFlags(Intent.FLAG_RECEIVER_FOREGROUND)), 0, timeCounter++);
883         enqueueOrReplaceBroadcast(queue,
884                 makeBroadcastRecord(new Intent(Intent.ACTION_NEW_OUTGOING_CALL),
885                         optInteractive), 0, timeCounter++);
886 
887         queue.makeActiveNextPending();
888         assertEquals(Intent.ACTION_LOCALE_CHANGED, queue.getActive().intent.getAction());
889         // after MAX_CONSECUTIVE_URGENT_DISPATCHES expect an ordinary one next
890         queue.makeActiveNextPending();
891         assertEquals(Intent.ACTION_TIMEZONE_CHANGED, queue.getActive().intent.getAction());
892         // and then back to prioritizing urgent ones
893         queue.makeActiveNextPending();
894         assertEquals(Intent.ACTION_APPLICATION_PREFERENCES, queue.getActive().intent.getAction());
895         // after MAX_CONSECUTIVE_URGENT_DISPATCHES, again an ordinary one next
896         queue.makeActiveNextPending();
897         assertEquals(Intent.ACTION_ALARM_CHANGED, queue.getActive().intent.getAction());
898         // and then back to prioritizing urgent ones
899         queue.makeActiveNextPending();
900         assertEquals(AppWidgetManager.ACTION_APPWIDGET_UPDATE,
901                 queue.getActive().intent.getAction());
902         // after MAX_CONSECUTIVE_URGENT_DISPATCHES and MAX_CONSECUTIVE_NORMAL_DISPATCHES,
903         // expect an offload one
904         queue.makeActiveNextPending();
905         assertEquals(Intent.ACTION_BOOT_COMPLETED, queue.getActive().intent.getAction());
906         // and then back to prioritizing urgent ones
907         queue.makeActiveNextPending();
908         assertEquals(Intent.ACTION_INPUT_METHOD_CHANGED, queue.getActive().intent.getAction());
909     }
910 
911     /**
912      * Verify that BroadcastProcessQueue#setPrioritizeEarliest() works as expected.
913      */
914     @Test
testPrioritizeEarliest()915     public void testPrioritizeEarliest() {
916         final BroadcastOptions optInteractive = BroadcastOptions.makeBasic();
917         optInteractive.setInteractive(true);
918 
919         BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants,
920                 PACKAGE_GREEN, getUidForPackage(PACKAGE_GREEN));
921         queue.addPrioritizeEarliestRequest();
922         long timeCounter = 100;
923 
924         enqueueOrReplaceBroadcast(queue,
925                 makeBroadcastRecord(new Intent(Intent.ACTION_BOOT_COMPLETED)
926                         .addFlags(Intent.FLAG_RECEIVER_OFFLOAD)), 0, timeCounter++);
927         enqueueOrReplaceBroadcast(queue,
928                 makeBroadcastRecord(new Intent(Intent.ACTION_TIMEZONE_CHANGED)),
929                         0, timeCounter++);
930         enqueueOrReplaceBroadcast(queue,
931                 makeBroadcastRecord(new Intent(Intent.ACTION_PACKAGE_CHANGED)
932                         .addFlags(Intent.FLAG_RECEIVER_OFFLOAD)), 0, timeCounter++);
933         enqueueOrReplaceBroadcast(queue,
934                 makeBroadcastRecord(new Intent(Intent.ACTION_ALARM_CHANGED)),
935                         0, timeCounter++);
936         enqueueOrReplaceBroadcast(queue,
937                 makeBroadcastRecord(new Intent(Intent.ACTION_TIME_TICK)),
938                         0, timeCounter++);
939         enqueueOrReplaceBroadcast(queue,
940                 makeBroadcastRecord(new Intent(Intent.ACTION_LOCALE_CHANGED)
941                         .addFlags(Intent.FLAG_RECEIVER_FOREGROUND)), 0, timeCounter++);
942         enqueueOrReplaceBroadcast(queue,
943                 makeBroadcastRecord(new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE),
944                         optInteractive), 0, timeCounter++);
945 
946         // When we mark BroadcastProcessQueue to prioritize earliest, we should
947         // expect to dispatch broadcasts in the order they were enqueued
948         queue.makeActiveNextPending();
949         assertEquals(Intent.ACTION_BOOT_COMPLETED, queue.getActive().intent.getAction());
950         queue.makeActiveNextPending();
951         assertEquals(Intent.ACTION_TIMEZONE_CHANGED, queue.getActive().intent.getAction());
952         // after MAX_CONSECUTIVE_URGENT_DISPATCHES expect an ordinary one next
953         queue.makeActiveNextPending();
954         assertEquals(Intent.ACTION_PACKAGE_CHANGED, queue.getActive().intent.getAction());
955         // and then back to prioritizing urgent ones
956         queue.makeActiveNextPending();
957         assertEquals(Intent.ACTION_ALARM_CHANGED, queue.getActive().intent.getAction());
958         queue.makeActiveNextPending();
959         assertEquals(Intent.ACTION_TIME_TICK, queue.getActive().intent.getAction());
960         queue.makeActiveNextPending();
961         assertEquals(Intent.ACTION_LOCALE_CHANGED, queue.getActive().intent.getAction());
962         // verify the reset-count-then-resume worked too
963         queue.makeActiveNextPending();
964         assertEquals(AppWidgetManager.ACTION_APPWIDGET_UPDATE,
965                 queue.getActive().intent.getAction());
966 
967 
968         queue.removePrioritizeEarliestRequest();
969 
970         enqueueOrReplaceBroadcast(queue,
971                 makeBroadcastRecord(new Intent(Intent.ACTION_BOOT_COMPLETED)
972                         .addFlags(Intent.FLAG_RECEIVER_OFFLOAD)), 0, timeCounter++);
973         enqueueOrReplaceBroadcast(queue,
974                 makeBroadcastRecord(new Intent(Intent.ACTION_TIMEZONE_CHANGED)),
975                 0, timeCounter++);
976         enqueueOrReplaceBroadcast(queue,
977                 makeBroadcastRecord(new Intent(Intent.ACTION_LOCALE_CHANGED)
978                         .addFlags(Intent.FLAG_RECEIVER_FOREGROUND)), 0, timeCounter++);
979 
980         // Once the request to prioritize earliest is removed, we should expect broadcasts
981         // to be dispatched in the order of foreground, normal and then offload.
982         queue.makeActiveNextPending();
983         assertEquals(Intent.ACTION_LOCALE_CHANGED, queue.getActive().intent.getAction());
984         queue.makeActiveNextPending();
985         assertEquals(Intent.ACTION_TIMEZONE_CHANGED, queue.getActive().intent.getAction());
986         queue.makeActiveNextPending();
987         assertEquals(Intent.ACTION_BOOT_COMPLETED, queue.getActive().intent.getAction());
988     }
989 
990     /**
991      * Verify that sending a broadcast with DELIVERY_GROUP_POLICY_MOST_RECENT works as expected.
992      */
993     @Test
testDeliveryGroupPolicy_mostRecent()994     public void testDeliveryGroupPolicy_mostRecent() {
995         final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK);
996         final BroadcastOptions optionsTimeTick = BroadcastOptions.makeBasic();
997         optionsTimeTick.setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT);
998 
999         final Intent musicVolumeChanged = new Intent(AudioManager.VOLUME_CHANGED_ACTION);
1000         musicVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE,
1001                 AudioManager.STREAM_MUSIC);
1002         final BroadcastOptions optionsMusicVolumeChanged = BroadcastOptions.makeBasic();
1003         optionsMusicVolumeChanged.setDeliveryGroupPolicy(
1004                 BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT);
1005         optionsMusicVolumeChanged.setDeliveryGroupMatchingKey("audio",
1006                 String.valueOf(AudioManager.STREAM_MUSIC));
1007 
1008         final Intent alarmVolumeChanged = new Intent(AudioManager.VOLUME_CHANGED_ACTION);
1009         alarmVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE,
1010                 AudioManager.STREAM_ALARM);
1011         final BroadcastOptions optionsAlarmVolumeChanged = BroadcastOptions.makeBasic();
1012         optionsAlarmVolumeChanged.setDeliveryGroupPolicy(
1013                 BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT);
1014         optionsAlarmVolumeChanged.setDeliveryGroupMatchingKey("audio",
1015                 String.valueOf(AudioManager.STREAM_ALARM));
1016 
1017         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(timeTick, optionsTimeTick));
1018         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(musicVolumeChanged,
1019                 optionsMusicVolumeChanged));
1020         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(alarmVolumeChanged,
1021                 optionsAlarmVolumeChanged));
1022         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(musicVolumeChanged,
1023                 optionsMusicVolumeChanged));
1024 
1025         final BroadcastProcessQueue queue = mImpl.getProcessQueue(PACKAGE_GREEN,
1026                 getUidForPackage(PACKAGE_GREEN));
1027         // Verify that the older musicVolumeChanged has been removed.
1028         verifyPendingRecords(queue,
1029                 List.of(timeTick, alarmVolumeChanged, musicVolumeChanged));
1030 
1031         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(timeTick, optionsTimeTick));
1032         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(alarmVolumeChanged,
1033                 optionsAlarmVolumeChanged));
1034         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(musicVolumeChanged,
1035                 optionsMusicVolumeChanged));
1036         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(alarmVolumeChanged,
1037                 optionsAlarmVolumeChanged));
1038         // Verify that the older alarmVolumeChanged has been removed.
1039         verifyPendingRecords(queue,
1040                 List.of(timeTick, musicVolumeChanged, alarmVolumeChanged));
1041 
1042         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(timeTick, optionsTimeTick));
1043         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(musicVolumeChanged,
1044                 optionsMusicVolumeChanged));
1045         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(alarmVolumeChanged,
1046                 optionsAlarmVolumeChanged));
1047         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(timeTick, optionsTimeTick));
1048         // Verify that the older timeTick has been removed.
1049         verifyPendingRecords(queue,
1050                 List.of(musicVolumeChanged, alarmVolumeChanged, timeTick));
1051     }
1052 
1053     @Test
testDeliveryGroupPolicy_diffReceivers()1054     public void testDeliveryGroupPolicy_diffReceivers() {
1055         final Intent screenOn = new Intent(Intent.ACTION_SCREEN_ON);
1056         final Intent screenOff = new Intent(Intent.ACTION_SCREEN_OFF);
1057         final BroadcastOptions screenOnOffOptions = BroadcastOptions.makeBasic()
1058                 .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT)
1059                 .setDeliveryGroupMatchingKey("screenOnOff", Intent.ACTION_SCREEN_ON);
1060 
1061         final Object greenReceiver = makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN);
1062         final Object redReceiver = makeManifestReceiver(PACKAGE_RED, CLASS_RED);
1063         final Object blueReceiver = makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE);
1064 
1065         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
1066                 List.of(greenReceiver, blueReceiver), false));
1067         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
1068                 List.of(greenReceiver, redReceiver, blueReceiver), false));
1069         final BroadcastProcessQueue greenQueue = mImpl.getProcessQueue(PACKAGE_GREEN,
1070                 getUidForPackage(PACKAGE_GREEN));
1071         final BroadcastProcessQueue redQueue = mImpl.getProcessQueue(PACKAGE_RED,
1072                 getUidForPackage(PACKAGE_RED));
1073         final BroadcastProcessQueue blueQueue = mImpl.getProcessQueue(PACKAGE_BLUE,
1074                 getUidForPackage(PACKAGE_BLUE));
1075         verifyPendingRecords(greenQueue, List.of(screenOff));
1076         verifyPendingRecords(redQueue, List.of(screenOff));
1077         verifyPendingRecords(blueQueue, List.of(screenOff));
1078 
1079         assertTrue(greenQueue.isEmpty());
1080         assertTrue(redQueue.isEmpty());
1081         assertTrue(blueQueue.isEmpty());
1082 
1083         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
1084                 List.of(greenReceiver, redReceiver, blueReceiver), false));
1085         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
1086                 List.of(greenReceiver, blueReceiver), false));
1087         verifyPendingRecords(greenQueue, List.of(screenOn));
1088         verifyPendingRecords(redQueue, List.of(screenOff));
1089         verifyPendingRecords(blueQueue, List.of(screenOn));
1090     }
1091 
1092     @Test
testDeliveryGroupPolicy_ordered_diffReceivers()1093     public void testDeliveryGroupPolicy_ordered_diffReceivers() {
1094         final Intent screenOn = new Intent(Intent.ACTION_SCREEN_ON);
1095         final Intent screenOff = new Intent(Intent.ACTION_SCREEN_OFF);
1096         final BroadcastOptions screenOnOffOptions = BroadcastOptions.makeBasic()
1097                 .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT)
1098                 .setDeliveryGroupMatchingKey("screenOnOff", Intent.ACTION_SCREEN_ON);
1099 
1100         final Object greenReceiver = makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN);
1101         final Object redReceiver = makeManifestReceiver(PACKAGE_RED, CLASS_RED);
1102         final Object blueReceiver = makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE);
1103 
1104         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
1105                 List.of(greenReceiver, blueReceiver), true));
1106         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
1107                 List.of(greenReceiver, redReceiver, blueReceiver), true));
1108         final BroadcastProcessQueue greenQueue = mImpl.getProcessQueue(PACKAGE_GREEN,
1109                 getUidForPackage(PACKAGE_GREEN));
1110         final BroadcastProcessQueue redQueue = mImpl.getProcessQueue(PACKAGE_RED,
1111                 getUidForPackage(PACKAGE_RED));
1112         final BroadcastProcessQueue blueQueue = mImpl.getProcessQueue(PACKAGE_BLUE,
1113                 getUidForPackage(PACKAGE_BLUE));
1114         verifyPendingRecords(greenQueue, List.of(screenOff));
1115         verifyPendingRecords(redQueue, List.of(screenOff));
1116         verifyPendingRecords(blueQueue, List.of(screenOff));
1117 
1118         assertTrue(greenQueue.isEmpty());
1119         assertTrue(redQueue.isEmpty());
1120         assertTrue(blueQueue.isEmpty());
1121 
1122         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
1123                 List.of(greenReceiver, redReceiver, blueReceiver), true));
1124         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
1125                 List.of(greenReceiver, blueReceiver), true));
1126         verifyPendingRecords(greenQueue, List.of(screenOff, screenOn));
1127         verifyPendingRecords(redQueue, List.of(screenOff));
1128         verifyPendingRecords(blueQueue, List.of(screenOff, screenOn));
1129     }
1130 
1131     @Test
testDeliveryGroupPolicy_resultTo_diffReceivers()1132     public void testDeliveryGroupPolicy_resultTo_diffReceivers() {
1133         final Intent screenOn = new Intent(Intent.ACTION_SCREEN_ON);
1134         final Intent screenOff = new Intent(Intent.ACTION_SCREEN_OFF);
1135         final BroadcastOptions screenOnOffOptions = BroadcastOptions.makeBasic()
1136                 .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT)
1137                 .setDeliveryGroupMatchingKey("screenOnOff", Intent.ACTION_SCREEN_ON);
1138 
1139         final Object greenReceiver = makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN);
1140         final Object redReceiver = makeManifestReceiver(PACKAGE_RED, CLASS_RED);
1141         final Object blueReceiver = makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE);
1142         final IIntentReceiver resultTo = mock(IIntentReceiver.class);
1143 
1144         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
1145                 List.of(greenReceiver, blueReceiver), resultTo, false));
1146         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
1147                 List.of(greenReceiver, redReceiver, blueReceiver), resultTo, false));
1148         final BroadcastProcessQueue greenQueue = mImpl.getProcessQueue(PACKAGE_GREEN,
1149                 getUidForPackage(PACKAGE_GREEN));
1150         final BroadcastProcessQueue redQueue = mImpl.getProcessQueue(PACKAGE_RED,
1151                 getUidForPackage(PACKAGE_RED));
1152         final BroadcastProcessQueue blueQueue = mImpl.getProcessQueue(PACKAGE_BLUE,
1153                 getUidForPackage(PACKAGE_BLUE));
1154         verifyPendingRecords(greenQueue, List.of(screenOff));
1155         verifyPendingRecords(redQueue, List.of(screenOff));
1156         verifyPendingRecords(blueQueue, List.of(screenOff));
1157 
1158         assertTrue(greenQueue.isEmpty());
1159         assertTrue(redQueue.isEmpty());
1160         assertTrue(blueQueue.isEmpty());
1161 
1162         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
1163                 List.of(greenReceiver, redReceiver, blueReceiver), resultTo, false));
1164         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
1165                 List.of(greenReceiver, blueReceiver), resultTo, false));
1166         verifyPendingRecords(greenQueue, List.of(screenOff, screenOn));
1167         verifyPendingRecords(redQueue, List.of(screenOff));
1168         verifyPendingRecords(blueQueue, List.of(screenOff, screenOn));
1169 
1170         final BroadcastRecord screenOffRecord = makeBroadcastRecord(screenOff, screenOnOffOptions,
1171                 List.of(greenReceiver, redReceiver, blueReceiver), resultTo, false);
1172         screenOffRecord.setDeliveryState(2, BroadcastRecord.DELIVERY_DEFERRED,
1173                 "testDeliveryGroupPolicy_resultTo_diffReceivers");
1174         mImpl.enqueueBroadcastLocked(screenOffRecord);
1175         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
1176                 List.of(greenReceiver, blueReceiver), resultTo, false));
1177         verifyPendingRecords(greenQueue, List.of(screenOff, screenOn));
1178         verifyPendingRecords(redQueue, List.of(screenOff));
1179         verifyPendingRecords(blueQueue, List.of(screenOn));
1180     }
1181 
1182     @DisableFlags(Flags.FLAG_LIMIT_PRIORITY_SCOPE)
1183     @SuppressWarnings("GuardedBy")
1184     @Test
testDeliveryGroupPolicy_prioritized_diffReceivers_flagDisabled()1185     public void testDeliveryGroupPolicy_prioritized_diffReceivers_flagDisabled() {
1186         final Intent screenOn = new Intent(Intent.ACTION_SCREEN_ON);
1187         final Intent screenOff = new Intent(Intent.ACTION_SCREEN_OFF);
1188         final BroadcastOptions screenOnOffOptions = BroadcastOptions.makeBasic()
1189                 .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT)
1190                 .setDeliveryGroupMatchingKey("screenOnOff", Intent.ACTION_SCREEN_ON);
1191 
1192         final Object greenReceiver = withPriority(
1193                 makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN), 10);
1194         final Object redReceiver = withPriority(
1195                 makeManifestReceiver(PACKAGE_RED, CLASS_RED), 5);
1196         final Object blueReceiver = withPriority(
1197                 makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE), 0);
1198 
1199         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
1200                 List.of(greenReceiver, blueReceiver), false));
1201         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
1202                 List.of(greenReceiver, redReceiver, blueReceiver), false));
1203         final BroadcastProcessQueue greenQueue = mImpl.getProcessQueue(PACKAGE_GREEN,
1204                 getUidForPackage(PACKAGE_GREEN));
1205         final BroadcastProcessQueue redQueue = mImpl.getProcessQueue(PACKAGE_RED,
1206                 getUidForPackage(PACKAGE_RED));
1207         final BroadcastProcessQueue blueQueue = mImpl.getProcessQueue(PACKAGE_BLUE,
1208                 getUidForPackage(PACKAGE_BLUE));
1209         verifyPendingRecords(greenQueue, List.of(screenOff));
1210         verifyPendingRecords(redQueue, List.of(screenOff));
1211         verifyPendingRecords(blueQueue, List.of(screenOff));
1212 
1213         assertTrue(greenQueue.isEmpty());
1214         assertTrue(redQueue.isEmpty());
1215         assertTrue(blueQueue.isEmpty());
1216 
1217         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
1218                 List.of(greenReceiver, redReceiver, blueReceiver), false));
1219         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
1220                 List.of(greenReceiver, blueReceiver), false));
1221         verifyPendingRecords(greenQueue, List.of(screenOff, screenOn));
1222         verifyPendingRecords(redQueue, List.of(screenOff));
1223         verifyPendingRecords(blueQueue, List.of(screenOff, screenOn));
1224 
1225         final BroadcastRecord screenOffRecord = makeBroadcastRecord(screenOff, screenOnOffOptions,
1226                 List.of(greenReceiver, redReceiver, blueReceiver), false);
1227         screenOffRecord.setDeliveryState(2, BroadcastRecord.DELIVERY_DEFERRED,
1228                 "testDeliveryGroupPolicy_prioritized_diffReceivers_flagDisabled");
1229         mImpl.enqueueBroadcastLocked(screenOffRecord);
1230         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
1231                 List.of(greenReceiver, blueReceiver), false));
1232         verifyPendingRecords(greenQueue, List.of(screenOff, screenOn));
1233         verifyPendingRecords(redQueue, List.of(screenOff));
1234         verifyPendingRecords(blueQueue, List.of(screenOn));
1235     }
1236 
1237     @EnableFlags(Flags.FLAG_LIMIT_PRIORITY_SCOPE)
1238     @SuppressWarnings("GuardedBy")
1239     @Test
testDeliveryGroupPolicy_prioritized_diffReceivers()1240     public void testDeliveryGroupPolicy_prioritized_diffReceivers() {
1241         final Intent screenOn = new Intent(Intent.ACTION_SCREEN_ON);
1242         final Intent screenOff = new Intent(Intent.ACTION_SCREEN_OFF);
1243         final BroadcastOptions screenOnOffOptions = BroadcastOptions.makeBasic()
1244                 .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT)
1245                 .setDeliveryGroupMatchingKey("screenOnOff", Intent.ACTION_SCREEN_ON);
1246 
1247         final Object greenReceiver = withPriority(
1248                 makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN), 10);
1249         final Object redReceiver = withPriority(
1250                 makeManifestReceiver(PACKAGE_RED, CLASS_RED), 5);
1251         final Object blueReceiver = withPriority(
1252                 makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE), 0);
1253 
1254         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
1255                 List.of(greenReceiver, blueReceiver), false));
1256         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
1257                 List.of(greenReceiver, redReceiver, blueReceiver), false));
1258         final BroadcastProcessQueue greenQueue = mImpl.getProcessQueue(PACKAGE_GREEN,
1259                 getUidForPackage(PACKAGE_GREEN));
1260         final BroadcastProcessQueue redQueue = mImpl.getProcessQueue(PACKAGE_RED,
1261                 getUidForPackage(PACKAGE_RED));
1262         final BroadcastProcessQueue blueQueue = mImpl.getProcessQueue(PACKAGE_BLUE,
1263                 getUidForPackage(PACKAGE_BLUE));
1264         verifyPendingRecords(greenQueue, List.of(screenOff));
1265         verifyPendingRecords(redQueue, List.of(screenOff));
1266         verifyPendingRecords(blueQueue, List.of(screenOff));
1267 
1268         assertTrue(greenQueue.isEmpty());
1269         assertTrue(redQueue.isEmpty());
1270         assertTrue(blueQueue.isEmpty());
1271 
1272         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
1273                 List.of(greenReceiver, redReceiver, blueReceiver), false));
1274         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
1275                 List.of(greenReceiver, blueReceiver), false));
1276         verifyPendingRecords(greenQueue, List.of(screenOn));
1277         verifyPendingRecords(redQueue, List.of(screenOff));
1278         verifyPendingRecords(blueQueue, List.of(screenOn));
1279 
1280         final BroadcastRecord screenOffRecord = makeBroadcastRecord(screenOff, screenOnOffOptions,
1281                 List.of(greenReceiver, redReceiver, blueReceiver), false);
1282         screenOffRecord.setDeliveryState(2, BroadcastRecord.DELIVERY_DEFERRED,
1283                 "testDeliveryGroupPolicy_prioritized_diffReceivers");
1284         mImpl.enqueueBroadcastLocked(screenOffRecord);
1285         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
1286                 List.of(greenReceiver, blueReceiver), false));
1287         verifyPendingRecords(greenQueue, List.of(screenOn));
1288         verifyPendingRecords(redQueue, List.of(screenOff));
1289         verifyPendingRecords(blueQueue, List.of(screenOn));
1290     }
1291 
1292     @EnableFlags(Flags.FLAG_LIMIT_PRIORITY_SCOPE)
1293     @SuppressWarnings("GuardedBy")
1294     @Test
testDeliveryGroupPolicy_prioritized_diffReceivers_changeIdDisabled()1295     public void testDeliveryGroupPolicy_prioritized_diffReceivers_changeIdDisabled() {
1296         doReturn(false).when(mPlatformCompat).isChangeEnabledInternalNoLogging(
1297                 eq(BroadcastRecord.LIMIT_PRIORITY_SCOPE),
1298                 argThat(appInfoEquals(getUidForPackage(PACKAGE_GREEN))));
1299 
1300         final Intent screenOn = new Intent(Intent.ACTION_SCREEN_ON);
1301         final Intent screenOff = new Intent(Intent.ACTION_SCREEN_OFF);
1302         final BroadcastOptions screenOnOffOptions = BroadcastOptions.makeBasic()
1303                 .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT)
1304                 .setDeliveryGroupMatchingKey("screenOnOff", Intent.ACTION_SCREEN_ON);
1305 
1306         final Object greenReceiver = withPriority(
1307                 makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN), 10);
1308         final Object redReceiver = withPriority(
1309                 makeManifestReceiver(PACKAGE_RED, CLASS_RED), 5);
1310         final Object blueReceiver = withPriority(
1311                 makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE), 0);
1312 
1313         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
1314                 List.of(greenReceiver, blueReceiver), false));
1315         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
1316                 List.of(greenReceiver, redReceiver, blueReceiver), false));
1317         final BroadcastProcessQueue greenQueue = mImpl.getProcessQueue(PACKAGE_GREEN,
1318                 getUidForPackage(PACKAGE_GREEN));
1319         final BroadcastProcessQueue redQueue = mImpl.getProcessQueue(PACKAGE_RED,
1320                 getUidForPackage(PACKAGE_RED));
1321         final BroadcastProcessQueue blueQueue = mImpl.getProcessQueue(PACKAGE_BLUE,
1322                 getUidForPackage(PACKAGE_BLUE));
1323         verifyPendingRecords(greenQueue, List.of(screenOff));
1324         verifyPendingRecords(redQueue, List.of(screenOff));
1325         verifyPendingRecords(blueQueue, List.of(screenOff));
1326 
1327         assertTrue(greenQueue.isEmpty());
1328         assertTrue(redQueue.isEmpty());
1329         assertTrue(blueQueue.isEmpty());
1330 
1331         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
1332                 List.of(greenReceiver, redReceiver, blueReceiver), false));
1333         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
1334                 List.of(greenReceiver, blueReceiver), false));
1335         verifyPendingRecords(greenQueue, List.of(screenOff, screenOn));
1336         verifyPendingRecords(redQueue, List.of(screenOff));
1337         verifyPendingRecords(blueQueue, List.of(screenOff, screenOn));
1338 
1339         final BroadcastRecord screenOffRecord = makeBroadcastRecord(screenOff, screenOnOffOptions,
1340                 List.of(greenReceiver, redReceiver, blueReceiver), false);
1341         screenOffRecord.setDeliveryState(2, BroadcastRecord.DELIVERY_DEFERRED,
1342                 "testDeliveryGroupPolicy_prioritized_diffReceivers");
1343         mImpl.enqueueBroadcastLocked(screenOffRecord);
1344         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
1345                 List.of(greenReceiver, blueReceiver), false));
1346         verifyPendingRecords(greenQueue, List.of(screenOff, screenOn));
1347         verifyPendingRecords(redQueue, List.of(screenOff));
1348         verifyPendingRecords(blueQueue, List.of(screenOn));
1349     }
1350 
1351     /**
1352      * Verify that sending a broadcast with DELIVERY_GROUP_POLICY_MERGED works as expected.
1353      */
1354     @Test
testDeliveryGroupPolicy_merged()1355     public void testDeliveryGroupPolicy_merged() {
1356         final BundleMerger extrasMerger = new BundleMerger();
1357         extrasMerger.setMergeStrategy(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST,
1358                 BundleMerger.STRATEGY_ARRAY_APPEND);
1359 
1360         final Intent packageChangedForUid = createPackageChangedIntent(TEST_UID,
1361                 List.of("com.testuid.component1"));
1362         final BroadcastOptions optionsPackageChangedForUid = BroadcastOptions.makeBasic();
1363         optionsPackageChangedForUid.setDeliveryGroupPolicy(
1364                 BroadcastOptions.DELIVERY_GROUP_POLICY_MERGED);
1365         optionsPackageChangedForUid.setDeliveryGroupMatchingKey("package",
1366                 String.valueOf(TEST_UID));
1367         optionsPackageChangedForUid.setDeliveryGroupExtrasMerger(extrasMerger);
1368 
1369         final Intent secondPackageChangedForUid = createPackageChangedIntent(TEST_UID,
1370                 List.of("com.testuid.component2", "com.testuid.component3"));
1371 
1372         final Intent packageChangedForUid2 = createPackageChangedIntent(TEST_UID2,
1373                 List.of("com.testuid2.component1"));
1374         final BroadcastOptions optionsPackageChangedForUid2 = BroadcastOptions.makeBasic();
1375         optionsPackageChangedForUid.setDeliveryGroupPolicy(
1376                 BroadcastOptions.DELIVERY_GROUP_POLICY_MERGED);
1377         optionsPackageChangedForUid.setDeliveryGroupMatchingKey("package",
1378                 String.valueOf(TEST_UID2));
1379         optionsPackageChangedForUid.setDeliveryGroupExtrasMerger(extrasMerger);
1380 
1381         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(packageChangedForUid,
1382                 optionsPackageChangedForUid));
1383         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(packageChangedForUid2,
1384                 optionsPackageChangedForUid2));
1385         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(secondPackageChangedForUid,
1386                 optionsPackageChangedForUid));
1387 
1388         final BroadcastProcessQueue queue = mImpl.getProcessQueue(PACKAGE_GREEN,
1389                 getUidForPackage(PACKAGE_GREEN));
1390         final Intent expectedPackageChangedForUid = createPackageChangedIntent(TEST_UID,
1391                 List.of("com.testuid.component2", "com.testuid.component3",
1392                         "com.testuid.component1"));
1393         // Verify that packageChangedForUid and secondPackageChangedForUid broadcasts
1394         // have been merged.
1395         verifyPendingRecords(queue, List.of(packageChangedForUid2, expectedPackageChangedForUid));
1396     }
1397 
1398     @Test
testDeliveryGroupPolicy_matchingFilter()1399     public void testDeliveryGroupPolicy_matchingFilter() {
1400         final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK);
1401         final BroadcastOptions optionsTimeTick = BroadcastOptions.makeBasic();
1402         optionsTimeTick.setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT);
1403 
1404         final Intent musicVolumeChanged = new Intent(AudioManager.VOLUME_CHANGED_ACTION);
1405         musicVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE,
1406                 AudioManager.STREAM_MUSIC);
1407         final IntentFilter filterMusicVolumeChanged = new IntentFilter(
1408                 AudioManager.VOLUME_CHANGED_ACTION);
1409         filterMusicVolumeChanged.addExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE,
1410                 AudioManager.STREAM_MUSIC);
1411         final BroadcastOptions optionsMusicVolumeChanged = BroadcastOptions.makeBasic();
1412         optionsMusicVolumeChanged.setDeliveryGroupPolicy(
1413                 BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT);
1414         optionsMusicVolumeChanged.setDeliveryGroupMatchingFilter(filterMusicVolumeChanged);
1415 
1416         final Intent alarmVolumeChanged = new Intent(AudioManager.VOLUME_CHANGED_ACTION);
1417         alarmVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE,
1418                 AudioManager.STREAM_ALARM);
1419         final IntentFilter filterAlarmVolumeChanged = new IntentFilter(
1420                 AudioManager.VOLUME_CHANGED_ACTION);
1421         filterAlarmVolumeChanged.addExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE,
1422                 AudioManager.STREAM_ALARM);
1423         final BroadcastOptions optionsAlarmVolumeChanged = BroadcastOptions.makeBasic();
1424         optionsAlarmVolumeChanged.setDeliveryGroupPolicy(
1425                 BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT);
1426         optionsAlarmVolumeChanged.setDeliveryGroupMatchingFilter(filterAlarmVolumeChanged);
1427 
1428         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(timeTick, optionsTimeTick));
1429         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(musicVolumeChanged,
1430                 optionsMusicVolumeChanged));
1431         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(alarmVolumeChanged,
1432                 optionsAlarmVolumeChanged));
1433         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(musicVolumeChanged,
1434                 optionsMusicVolumeChanged));
1435 
1436         final BroadcastProcessQueue queue = mImpl.getProcessQueue(PACKAGE_GREEN,
1437                 getUidForPackage(PACKAGE_GREEN));
1438         // Verify that the older musicVolumeChanged has been removed.
1439         verifyPendingRecords(queue,
1440                 List.of(timeTick, alarmVolumeChanged, musicVolumeChanged));
1441 
1442         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(timeTick, optionsTimeTick));
1443         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(alarmVolumeChanged,
1444                 optionsAlarmVolumeChanged));
1445         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(musicVolumeChanged,
1446                 optionsMusicVolumeChanged));
1447         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(alarmVolumeChanged,
1448                 optionsAlarmVolumeChanged));
1449         // Verify that the older alarmVolumeChanged has been removed.
1450         verifyPendingRecords(queue,
1451                 List.of(timeTick, musicVolumeChanged, alarmVolumeChanged));
1452 
1453         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(timeTick, optionsTimeTick));
1454         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(musicVolumeChanged,
1455                 optionsMusicVolumeChanged));
1456         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(alarmVolumeChanged,
1457                 optionsAlarmVolumeChanged));
1458         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(timeTick, optionsTimeTick));
1459         // Verify that the older timeTick has been removed.
1460         verifyPendingRecords(queue,
1461                 List.of(musicVolumeChanged, alarmVolumeChanged, timeTick));
1462     }
1463 
1464     @Test
testDeliveryGroupPolicy_merged_matchingFilter()1465     public void testDeliveryGroupPolicy_merged_matchingFilter() {
1466         final long now = SystemClock.elapsedRealtime();
1467         final Pair<Intent, BroadcastOptions> dropboxEntryBroadcast1 = createDropboxBroadcast(
1468                 "TAG_A", now, 2);
1469         final Pair<Intent, BroadcastOptions> dropboxEntryBroadcast2 = createDropboxBroadcast(
1470                 "TAG_B", now + 1000, 4);
1471         final Pair<Intent, BroadcastOptions> dropboxEntryBroadcast3 = createDropboxBroadcast(
1472                 "TAG_A", now + 2000, 7);
1473 
1474         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(dropboxEntryBroadcast1.first,
1475                 dropboxEntryBroadcast1.second));
1476         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(dropboxEntryBroadcast2.first,
1477                 dropboxEntryBroadcast2.second));
1478         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(dropboxEntryBroadcast3.first,
1479                 dropboxEntryBroadcast3.second));
1480 
1481         final BroadcastProcessQueue queue = mImpl.getProcessQueue(PACKAGE_GREEN,
1482                 getUidForPackage(PACKAGE_GREEN));
1483         // dropboxEntryBroadcast1 and dropboxEntryBroadcast3 should be merged as they use the same
1484         // tag and there shouldn't be a change to dropboxEntryBroadcast2.
1485         final Pair<Intent, BroadcastOptions> expectedMergedBroadcast = createDropboxBroadcast(
1486                 "TAG_A", now + 2000, 10);
1487         verifyPendingRecords(queue, List.of(
1488                 dropboxEntryBroadcast2.first, expectedMergedBroadcast.first));
1489     }
1490 
1491     @Test
testDeliveryGroupPolicy_merged_multipleReceivers()1492     public void testDeliveryGroupPolicy_merged_multipleReceivers() {
1493         final long now = SystemClock.elapsedRealtime();
1494         final Pair<Intent, BroadcastOptions> dropboxEntryBroadcast1 = createDropboxBroadcast(
1495                 "TAG_A", now, 2);
1496         final Pair<Intent, BroadcastOptions> dropboxEntryBroadcast2 = createDropboxBroadcast(
1497                 "TAG_A", now + 1000, 4);
1498 
1499         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(dropboxEntryBroadcast1.first,
1500                 dropboxEntryBroadcast1.second,
1501                 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN),
1502                         makeManifestReceiver(PACKAGE_RED, CLASS_RED)),
1503                 false));
1504         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(dropboxEntryBroadcast2.first,
1505                 dropboxEntryBroadcast2.second,
1506                 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN),
1507                         makeManifestReceiver(PACKAGE_RED, CLASS_RED)),
1508                 false));
1509 
1510         final BroadcastProcessQueue greenQueue = mImpl.getProcessQueue(PACKAGE_GREEN,
1511                 getUidForPackage(PACKAGE_GREEN));
1512         final BroadcastProcessQueue redQueue = mImpl.getProcessQueue(PACKAGE_RED,
1513                 getUidForPackage(PACKAGE_RED));
1514 
1515         verifyPendingRecords(greenQueue,
1516                 List.of(dropboxEntryBroadcast1.first, dropboxEntryBroadcast2.first));
1517         verifyPendingRecords(redQueue,
1518                 List.of(dropboxEntryBroadcast1.first, dropboxEntryBroadcast2.first));
1519     }
1520 
1521     @Test
testDeliveryGroupPolicy_sameAction_differentMatchingCriteria()1522     public void testDeliveryGroupPolicy_sameAction_differentMatchingCriteria() {
1523         final Intent closeSystemDialogs1 = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
1524         final BroadcastOptions optionsCloseSystemDialog1 = BroadcastOptions.makeBasic()
1525                 .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT);
1526 
1527         final Intent closeSystemDialogs2 = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)
1528                 .putExtra("reason", "testing");
1529         final BroadcastOptions optionsCloseSystemDialog2 = BroadcastOptions.makeBasic()
1530                 .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT)
1531                 .setDeliveryGroupMatchingKey(Intent.ACTION_CLOSE_SYSTEM_DIALOGS, "testing");
1532 
1533         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(
1534                 closeSystemDialogs1, optionsCloseSystemDialog1));
1535         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(
1536                 closeSystemDialogs2, optionsCloseSystemDialog2));
1537         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(
1538                 closeSystemDialogs1, optionsCloseSystemDialog1));
1539         // Verify that only the older broadcast with no extras was removed.
1540         final BroadcastProcessQueue queue = mImpl.getProcessQueue(PACKAGE_GREEN,
1541                 getUidForPackage(PACKAGE_GREEN));
1542         verifyPendingRecords(queue, List.of(closeSystemDialogs2, closeSystemDialogs1));
1543 
1544         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(
1545                 closeSystemDialogs2, optionsCloseSystemDialog2));
1546         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(
1547                 closeSystemDialogs1, optionsCloseSystemDialog1));
1548         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(
1549                 closeSystemDialogs2, optionsCloseSystemDialog2));
1550         // Verify that only the older broadcast with no extras was removed.
1551         verifyPendingRecords(queue, List.of(closeSystemDialogs1, closeSystemDialogs2));
1552     }
1553 
1554     @SuppressWarnings("GuardedBy")
1555     @Test
testDeliveryGroupPolicy_sameAction_multiplePolicies()1556     public void testDeliveryGroupPolicy_sameAction_multiplePolicies() {
1557         // Create a PACKAGE_CHANGED broadcast corresponding to a change in the whole PACKAGE_GREEN
1558         // package.
1559         final Intent greenPackageChangedIntent = createPackageChangedIntent(
1560                 getUidForPackage(PACKAGE_GREEN), List.of(PACKAGE_GREEN));
1561         // Create delivery group policy such that when there are multiple broadcasts within the
1562         // delivery group identified by "com.example.green/10002", only the most recent one
1563         // gets delivered and the rest get discarded.
1564         final BroadcastOptions optionsMostRecentPolicyForPackageGreen =
1565                 BroadcastOptions.makeBasic();
1566         optionsMostRecentPolicyForPackageGreen.setDeliveryGroupMatchingKey("package_changed",
1567                 PACKAGE_GREEN + "/" + getUidForPackage(PACKAGE_GREEN));
1568         optionsMostRecentPolicyForPackageGreen.setDeliveryGroupPolicy(
1569                 BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT);
1570 
1571         // Create a PACKAGE_CHANGED broadcast corresponding to a change in the whole PACKAGE_RED
1572         // package.
1573         final Intent redPackageChangedIntent = createPackageChangedIntent(
1574                 getUidForPackage(PACKAGE_RED), List.of(PACKAGE_RED));
1575         // Create delivery group policy such that when there are multiple broadcasts within the
1576         // delivery group identified by "com.example.red/10001", only the most recent one
1577         // gets delivered and the rest get discarded.
1578         final BroadcastOptions optionsMostRecentPolicyForPackageRed =
1579                 BroadcastOptions.makeBasic();
1580         optionsMostRecentPolicyForPackageRed.setDeliveryGroupMatchingKey("package_changed",
1581                 PACKAGE_RED + "/" + getUidForPackage(PACKAGE_RED));
1582         optionsMostRecentPolicyForPackageRed.setDeliveryGroupPolicy(
1583                 BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT);
1584 
1585         // Create a PACKAGE_CHANGED broadcast corresponding to a change in some components of
1586         // PACKAGE_GREEN package.
1587         final Intent greenPackageComponentsChangedIntent1 = createPackageChangedIntent(
1588                 getUidForPackage(PACKAGE_GREEN),
1589                 List.of(PACKAGE_GREEN + ".comp1", PACKAGE_GREEN + ".comp2"));
1590         final Intent greenPackageComponentsChangedIntent2 = createPackageChangedIntent(
1591                 getUidForPackage(PACKAGE_GREEN),
1592                 List.of(PACKAGE_GREEN + ".comp3"));
1593         // Create delivery group policy such that when there are multiple broadcasts within the
1594         // delivery group identified by "components-com.example.green/10002", merge the extras
1595         // within these broadcasts such that only one broadcast is sent and the rest are
1596         // discarded. Couple of things to note here:
1597         // 1. We are intentionally using a different policy group
1598         //    "components-com.example.green/10002" (as opposed to "com.example.green/10002" used
1599         //    earlier), because this is corresponding to a change in some particular components,
1600         //    rather than a change to the whole package and we want to keep these two types of
1601         //    broadcasts independent.
1602         // 2. We are using 'extrasMerger' to indicate how we want the extras to be merged. This
1603         //    assumes that broadcasts belonging to the group 'components-com.example.green/10002'
1604         //    will have the same values for all the extras, except for the one extra
1605         //    'EXTRA_CHANGED_COMPONENT_NAME_LIST'. So, we explicitly specify how to merge this
1606         //    extra by using 'STRATEGY_ARRAY_APPEND' strategy, which basically indicates that
1607         //    the extra values which are arrays should be concatenated.
1608         final BundleMerger extrasMerger = new BundleMerger();
1609         extrasMerger.setMergeStrategy(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST,
1610                 BundleMerger.STRATEGY_ARRAY_APPEND);
1611         final BroadcastOptions optionsMergedPolicyForPackageGreen = BroadcastOptions.makeBasic();
1612         optionsMergedPolicyForPackageGreen.setDeliveryGroupMatchingKey("package_changed",
1613                 "components-" + PACKAGE_GREEN + "/" + getUidForPackage(PACKAGE_GREEN));
1614         optionsMergedPolicyForPackageGreen.setDeliveryGroupPolicy(
1615                 BroadcastOptions.DELIVERY_GROUP_POLICY_MERGED);
1616         optionsMergedPolicyForPackageGreen.setDeliveryGroupExtrasMerger(extrasMerger);
1617 
1618         // Create a PACKAGE_CHANGED broadcast corresponding to a change in some components of
1619         // PACKAGE_RED package.
1620         final Intent redPackageComponentsChangedIntent = createPackageChangedIntent(
1621                 getUidForPackage(PACKAGE_RED),
1622                 List.of(PACKAGE_RED + ".comp1", PACKAGE_RED + ".comp2"));
1623         // Create delivery group policy such that when there are multiple broadcasts within the
1624         // delivery group identified by "components-com.example.red/10001", merge the extras
1625         // within these broadcasts such that only one broadcast is sent and the rest are
1626         // discarded.
1627         final BroadcastOptions optionsMergedPolicyForPackageRed = BroadcastOptions.makeBasic();
1628         optionsMergedPolicyForPackageGreen.setDeliveryGroupMatchingKey("package_changed",
1629                 "components-" + PACKAGE_RED + "/" + getUidForPackage(PACKAGE_RED));
1630         optionsMergedPolicyForPackageRed.setDeliveryGroupPolicy(
1631                 BroadcastOptions.DELIVERY_GROUP_POLICY_MERGED);
1632         optionsMergedPolicyForPackageRed.setDeliveryGroupExtrasMerger(extrasMerger);
1633 
1634         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(greenPackageChangedIntent,
1635                 optionsMostRecentPolicyForPackageGreen));
1636         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(redPackageChangedIntent,
1637                 optionsMostRecentPolicyForPackageRed));
1638         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(greenPackageComponentsChangedIntent1,
1639                 optionsMergedPolicyForPackageGreen));
1640         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(redPackageComponentsChangedIntent,
1641                 optionsMergedPolicyForPackageRed));
1642         // Since this broadcast has DELIVERY_GROUP_MOST_RECENT policy set, the earlier
1643         // greenPackageChangedIntent broadcast with the same policy will be discarded.
1644         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(greenPackageChangedIntent,
1645                 optionsMostRecentPolicyForPackageGreen));
1646         // Since this broadcast has DELIVERY_GROUP_MERGED policy set, the earlier
1647         // greenPackageComponentsChangedIntent1 broadcast with the same policy will be merged
1648         // with this one and then will be discarded.
1649         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(greenPackageComponentsChangedIntent2,
1650                 optionsMergedPolicyForPackageGreen));
1651 
1652         final BroadcastProcessQueue queue = mImpl.getProcessQueue(PACKAGE_GREEN,
1653                 getUidForPackage(PACKAGE_GREEN));
1654         // The extra EXTRA_CHANGED_COMPONENT_NAME_LIST values from
1655         // greenPackageComponentsChangedIntent1 and
1656         // greenPackageComponentsChangedIntent2 broadcasts would be merged, since
1657         // STRATEGY_ARRAY_APPEND was used for this extra.
1658         final Intent expectedGreenPackageComponentsChangedIntent = createPackageChangedIntent(
1659                 getUidForPackage(PACKAGE_GREEN), List.of(PACKAGE_GREEN + ".comp3",
1660                         PACKAGE_GREEN + ".comp1", PACKAGE_GREEN + ".comp2"));
1661         verifyPendingRecords(queue, List.of(redPackageChangedIntent,
1662                 redPackageComponentsChangedIntent, greenPackageChangedIntent,
1663                 expectedGreenPackageComponentsChangedIntent));
1664     }
1665 
createDropboxBroadcast(String tag, long timestampMs, int droppedCount)1666     private Pair<Intent, BroadcastOptions> createDropboxBroadcast(String tag, long timestampMs,
1667             int droppedCount) {
1668         final Intent dropboxEntryAdded = new Intent(DropBoxManager.ACTION_DROPBOX_ENTRY_ADDED);
1669         dropboxEntryAdded.putExtra(DropBoxManager.EXTRA_TAG, tag);
1670         dropboxEntryAdded.putExtra(DropBoxManager.EXTRA_TIME, timestampMs);
1671         dropboxEntryAdded.putExtra(DropBoxManager.EXTRA_DROPPED_COUNT, droppedCount);
1672 
1673         final BundleMerger extrasMerger = new BundleMerger();
1674         extrasMerger.setDefaultMergeStrategy(BundleMerger.STRATEGY_FIRST);
1675         extrasMerger.setMergeStrategy(DropBoxManager.EXTRA_TIME,
1676                 BundleMerger.STRATEGY_COMPARABLE_MAX);
1677         extrasMerger.setMergeStrategy(DropBoxManager.EXTRA_DROPPED_COUNT,
1678                 BundleMerger.STRATEGY_NUMBER_INCREMENT_FIRST_AND_ADD);
1679         final IntentFilter matchingFilter = new IntentFilter(
1680                 DropBoxManager.ACTION_DROPBOX_ENTRY_ADDED);
1681         matchingFilter.addExtra(DropBoxManager.EXTRA_TAG, tag);
1682         final BroadcastOptions optionsDropboxEntryAdded = BroadcastOptions.makeBasic()
1683                 .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MERGED)
1684                 .setDeliveryGroupMatchingFilter(matchingFilter)
1685                 .setDeliveryGroupExtrasMerger(extrasMerger);
1686         return Pair.create(dropboxEntryAdded, optionsDropboxEntryAdded);
1687     }
1688 
1689     @Test
testVerifyEnqueuedTime_withReplacePending()1690     public void testVerifyEnqueuedTime_withReplacePending() {
1691         final Intent userPresent = new Intent(Intent.ACTION_USER_PRESENT);
1692         userPresent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
1693 
1694         final BroadcastRecord userPresentRecord1 = makeBroadcastRecord(userPresent);
1695         final BroadcastRecord userPresentRecord2 = makeBroadcastRecord(userPresent);
1696 
1697         mImpl.enqueueBroadcastLocked(userPresentRecord1);
1698         // Wait for a few ms before sending another broadcast to allow comparing the
1699         // enqueue timestamps of these broadcasts.
1700         SystemClock.sleep(5);
1701         mImpl.enqueueBroadcastLocked(userPresentRecord2);
1702 
1703         final BroadcastProcessQueue queue = mImpl.getProcessQueue(PACKAGE_GREEN,
1704                 getUidForPackage(PACKAGE_GREEN));
1705         queue.makeActiveNextPending();
1706 
1707         // Verify that there is only one record pending and its enqueueTime is
1708         // same as that of userPresentRecord1.
1709         final BroadcastRecord activeRecord = queue.getActive();
1710         assertEquals(userPresentRecord1.enqueueTime, activeRecord.enqueueTime);
1711         assertEquals(userPresentRecord1.enqueueRealTime, activeRecord.enqueueRealTime);
1712         assertEquals(userPresentRecord1.enqueueClockTime, activeRecord.enqueueClockTime);
1713         assertThat(activeRecord.originalEnqueueClockTime)
1714                 .isGreaterThan(activeRecord.enqueueClockTime);
1715         assertTrue(queue.isEmpty());
1716     }
1717 
1718     @Test
testCleanupDisabledPackageReceiversLocked()1719     public void testCleanupDisabledPackageReceiversLocked() {
1720         final Intent userPresent = new Intent(Intent.ACTION_USER_PRESENT);
1721         final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK);
1722 
1723         final BroadcastRecord record1 = makeBroadcastRecord(userPresent, List.of(
1724                 makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN),
1725                 makeManifestReceiver(PACKAGE_RED, CLASS_BLUE),
1726                 makeManifestReceiver(PACKAGE_YELLOW, CLASS_RED),
1727                 makeManifestReceiver(PACKAGE_BLUE, CLASS_GREEN)
1728         ));
1729         final BroadcastRecord record2 = makeBroadcastRecord(timeTick, List.of(
1730                 makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN),
1731                 makeManifestReceiver(PACKAGE_RED, CLASS_RED),
1732                 makeManifestReceiver(PACKAGE_YELLOW, CLASS_YELLOW)
1733         ));
1734 
1735         mImpl.enqueueBroadcastLocked(record1);
1736         mImpl.enqueueBroadcastLocked(record2);
1737 
1738         mImpl.cleanupDisabledPackageReceiversLocked(null, null, UserHandle.USER_SYSTEM);
1739 
1740         // Verify that all receivers have been marked as "skipped".
1741         for (BroadcastRecord record : new BroadcastRecord[] {record1, record2}) {
1742             for (int i = 0; i < record.receivers.size(); ++i) {
1743                 final String errMsg = "Unexpected delivery state for record:" + record
1744                         + "; receiver=" + record.receivers.get(i);
1745                 assertEquals(errMsg, BroadcastRecord.DELIVERY_SKIPPED, record.getDeliveryState(i));
1746             }
1747         }
1748     }
1749 
1750     @Test
testBroadcastDeliveryEventReported()1751     public void testBroadcastDeliveryEventReported() throws Exception {
1752         final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK);
1753         final BroadcastOptions optionsTimeTick = BroadcastOptions.makeBasic();
1754         optionsTimeTick.setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT);
1755 
1756         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(timeTick, optionsTimeTick));
1757         mImpl.enqueueBroadcastLocked(makeBroadcastRecord(timeTick, optionsTimeTick));
1758         waitForIdle();
1759 
1760         // Verify that there is only one delivery event reported since one of the broadcasts
1761         // should have been skipped.
1762         verify(() -> FrameworkStatsLog.write(eq(BROADCAST_DELIVERY_EVENT_REPORTED),
1763                 eq(getUidForPackage(PACKAGE_GREEN)), anyInt(), eq(Intent.ACTION_TIME_TICK),
1764                 eq(BROADCAST_DELIVERY_EVENT_REPORTED__RECEIVER_TYPE__MANIFEST),
1765                 eq(BROADCAST_DELIVERY_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_COLD),
1766                 anyLong(), anyLong(), anyLong(), anyInt(), nullable(String.class),
1767                 anyString(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(),
1768                 anyBoolean(), anyLong()),
1769                 times(1));
1770     }
1771 
1772     @Test
testBroadcastProcessedEventRecord_broadcastDelivered_processedEventLogged()1773     public void testBroadcastProcessedEventRecord_broadcastDelivered_processedEventLogged()
1774             throws Exception {
1775         testBroadcastProcessedEventRecordLogged(
1776                 /* isAssumedDelivered= */ false,
1777                 /* isDelivered= */ true,
1778                 /* numberOfInvocations= */ 1);
1779     }
1780 
1781     @Test
testBroadcastProcessedEventRecord_broadcastDeliveryFailed_eventNotLogged()1782     public void testBroadcastProcessedEventRecord_broadcastDeliveryFailed_eventNotLogged()
1783             throws Exception {
1784         testBroadcastProcessedEventRecordLogged(
1785                 /* isAssumedDelivered= */ false,
1786                 /* isDelivered= */ false,
1787                 /* numberOfInvocations= */ 0);
1788     }
1789 
1790     @Test
testBroadcastProcessedEventRecord_broadcastAssumedDelivered_eventNotLogged()1791     public void testBroadcastProcessedEventRecord_broadcastAssumedDelivered_eventNotLogged()
1792             throws Exception {
1793         testBroadcastProcessedEventRecordLogged(
1794                 /* isAssumedDelivered= */ true,
1795                 /* isDelivered= */ true,
1796                 /* numberOfInvocations= */ 0);
1797     }
1798 
1799     @Test
testGetPreferredSchedulingGroup()1800     public void testGetPreferredSchedulingGroup() throws Exception {
1801         final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants,
1802                 PACKAGE_GREEN, getUidForPackage(PACKAGE_GREEN));
1803 
1804         assertEquals(ProcessList.SCHED_GROUP_UNDEFINED, queue.getPreferredSchedulingGroupLocked());
1805 
1806         final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK)
1807                 .addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
1808         enqueueOrReplaceBroadcast(queue, makeBroadcastRecord(timeTick,
1809                 List.of(makeMockRegisteredReceiver())), 0);
1810         assertEquals(ProcessList.SCHED_GROUP_UNDEFINED, queue.getPreferredSchedulingGroupLocked());
1811 
1812         // Make the foreground broadcast as active.
1813         queue.makeActiveNextPending();
1814         assertEquals(ProcessList.SCHED_GROUP_DEFAULT, queue.getPreferredSchedulingGroupLocked());
1815 
1816         queue.makeActiveIdle();
1817         assertEquals(ProcessList.SCHED_GROUP_UNDEFINED, queue.getPreferredSchedulingGroupLocked());
1818 
1819         final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
1820         enqueueOrReplaceBroadcast(queue, makeBroadcastRecord(airplane,
1821                 List.of(makeMockRegisteredReceiver())), 0);
1822 
1823         // Make the background broadcast as active.
1824         queue.makeActiveNextPending();
1825         assertEquals(ProcessList.SCHED_GROUP_BACKGROUND, queue.getPreferredSchedulingGroupLocked());
1826 
1827         enqueueOrReplaceBroadcast(queue, makeBroadcastRecord(timeTick,
1828                 List.of(makeMockRegisteredReceiver())), 0);
1829         // Even though the active broadcast is not a foreground one, scheduling group will be
1830         // DEFAULT since there is a foreground broadcast waiting to be delivered.
1831         assertEquals(ProcessList.SCHED_GROUP_DEFAULT, queue.getPreferredSchedulingGroupLocked());
1832     }
1833 
1834     @SuppressWarnings("GuardedBy")
1835     @DisableFlags(Flags.FLAG_AVOID_NOTE_OP_AT_ENQUEUE)
1836     @Test
testSkipPolicy_atEnqueueTime_flagDisabled()1837     public void testSkipPolicy_atEnqueueTime_flagDisabled() throws Exception {
1838         final Intent userPresent = new Intent(Intent.ACTION_USER_PRESENT);
1839         final Object greenReceiver = makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN);
1840         final Object redReceiver = makeManifestReceiver(PACKAGE_RED, CLASS_RED);
1841 
1842         final BroadcastRecord userPresentRecord = makeBroadcastRecord(userPresent,
1843                 List.of(greenReceiver, redReceiver));
1844 
1845         final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK);
1846         final BroadcastRecord timeTickRecord = makeBroadcastRecord(timeTick,
1847                 List.of(greenReceiver, redReceiver));
1848 
1849         doAnswer(invocation -> {
1850             final BroadcastRecord r = invocation.getArgument(0);
1851             final Object o = invocation.getArgument(1);
1852             if (userPresent.getAction().equals(r.intent.getAction())
1853                     && isReceiverEquals(o, greenReceiver)) {
1854                 return "receiver skipped by test";
1855             }
1856             return null;
1857         }).when(mSkipPolicy).shouldSkipMessage(any(BroadcastRecord.class), any());
1858 
1859         mImpl.enqueueBroadcastLocked(userPresentRecord);
1860         mImpl.enqueueBroadcastLocked(timeTickRecord);
1861 
1862         final BroadcastProcessQueue greenQueue = mImpl.getProcessQueue(PACKAGE_GREEN,
1863                 getUidForPackage(PACKAGE_GREEN));
1864         // There should be only one broadcast for green process as the other would have
1865         // been skipped.
1866         verifyPendingRecords(greenQueue, List.of(timeTick));
1867         final BroadcastProcessQueue redQueue = mImpl.getProcessQueue(PACKAGE_RED,
1868                 getUidForPackage(PACKAGE_RED));
1869         verifyPendingRecords(redQueue, List.of(userPresent, timeTick));
1870     }
1871 
1872     @SuppressWarnings("GuardedBy")
1873     @EnableFlags(Flags.FLAG_AVOID_NOTE_OP_AT_ENQUEUE)
1874     @Test
testSkipPolicy_atEnqueueTime()1875     public void testSkipPolicy_atEnqueueTime() throws Exception {
1876         final Intent userPresent = new Intent(Intent.ACTION_USER_PRESENT);
1877         final Object greenReceiver = makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN);
1878         final Object redReceiver = makeManifestReceiver(PACKAGE_RED, CLASS_RED);
1879 
1880         final BroadcastRecord userPresentRecord = makeBroadcastRecord(userPresent,
1881                 List.of(greenReceiver, redReceiver));
1882 
1883         final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK);
1884         final BroadcastRecord timeTickRecord = makeBroadcastRecord(timeTick,
1885                 List.of(greenReceiver, redReceiver));
1886 
1887         doAnswer(invocation -> {
1888             final BroadcastRecord r = invocation.getArgument(0);
1889             final Object o = invocation.getArgument(1);
1890             if (userPresent.getAction().equals(r.intent.getAction())
1891                     && isReceiverEquals(o, greenReceiver)) {
1892                 return "receiver skipped by test";
1893             }
1894             return null;
1895         }).when(mSkipPolicy).shouldSkipAtEnqueueMessage(any(BroadcastRecord.class), any());
1896 
1897         mImpl.enqueueBroadcastLocked(userPresentRecord);
1898         mImpl.enqueueBroadcastLocked(timeTickRecord);
1899 
1900         final BroadcastProcessQueue greenQueue = mImpl.getProcessQueue(PACKAGE_GREEN,
1901                 getUidForPackage(PACKAGE_GREEN));
1902         // There should be only one broadcast for green process as the other would have
1903         // been skipped.
1904         verifyPendingRecords(greenQueue, List.of(timeTick));
1905         final BroadcastProcessQueue redQueue = mImpl.getProcessQueue(PACKAGE_RED,
1906                 getUidForPackage(PACKAGE_RED));
1907         verifyPendingRecords(redQueue, List.of(userPresent, timeTick));
1908     }
1909 
1910     @DisableFlags(Flags.FLAG_LIMIT_PRIORITY_SCOPE)
1911     @Test
testDeliveryDeferredForCached_flagDisabled()1912     public void testDeliveryDeferredForCached_flagDisabled() throws Exception {
1913         final ProcessRecord greenProcess = makeProcessRecord(makeApplicationInfo(PACKAGE_GREEN));
1914         final ProcessRecord redProcess = makeProcessRecord(makeApplicationInfo(PACKAGE_RED));
1915 
1916         final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK);
1917         final BroadcastRecord timeTickRecord = makeBroadcastRecord(timeTick,
1918                 List.of(makeRegisteredReceiver(greenProcess, 0)));
1919 
1920         final Intent batteryChanged = new Intent(Intent.ACTION_BATTERY_CHANGED);
1921         final BroadcastOptions optionsBatteryChanged =
1922                 BroadcastOptions.makeWithDeferUntilActive(true);
1923         final BroadcastRecord batteryChangedRecord = makeBroadcastRecord(batteryChanged,
1924                 optionsBatteryChanged,
1925                 List.of(makeRegisteredReceiver(greenProcess, 10),
1926                         makeRegisteredReceiver(redProcess, 0)),
1927                 false /* ordered */);
1928 
1929         mImpl.enqueueBroadcastLocked(timeTickRecord);
1930         mImpl.enqueueBroadcastLocked(batteryChangedRecord);
1931 
1932         final BroadcastProcessQueue greenQueue = mImpl.getProcessQueue(PACKAGE_GREEN,
1933                 getUidForPackage(PACKAGE_GREEN));
1934         final BroadcastProcessQueue redQueue = mImpl.getProcessQueue(PACKAGE_RED,
1935                 getUidForPackage(PACKAGE_RED));
1936         assertEquals(BroadcastProcessQueue.REASON_NORMAL, greenQueue.getRunnableAtReason());
1937         assertFalse(greenQueue.shouldBeDeferred());
1938         assertEquals(BroadcastProcessQueue.REASON_BLOCKED, redQueue.getRunnableAtReason());
1939         assertFalse(redQueue.shouldBeDeferred());
1940 
1941         // Simulate process state change
1942         greenQueue.setProcessAndUidState(greenProcess, false /* uidForeground */,
1943                 true /* processFreezable */);
1944         greenQueue.updateDeferredStates(mImpl.mBroadcastConsumerDeferApply,
1945                 mImpl.mBroadcastConsumerDeferClear);
1946 
1947         assertEquals(BroadcastProcessQueue.REASON_CACHED, greenQueue.getRunnableAtReason());
1948         assertTrue(greenQueue.shouldBeDeferred());
1949         // Once the broadcasts to green process are deferred, broadcasts to red process
1950         // shouldn't be blocked anymore.
1951         assertEquals(BroadcastProcessQueue.REASON_NORMAL, redQueue.getRunnableAtReason());
1952         assertFalse(redQueue.shouldBeDeferred());
1953 
1954         // All broadcasts to green process should be deferred.
1955         greenQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> {
1956             assertEquals("Unexpected state for " + r,
1957                     BroadcastRecord.DELIVERY_DEFERRED, r.getDeliveryState(i));
1958         }, false /* andRemove */);
1959         redQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> {
1960             assertEquals("Unexpected state for " + r,
1961                     BroadcastRecord.DELIVERY_PENDING, r.getDeliveryState(i));
1962         }, false /* andRemove */);
1963 
1964         final Intent packageChanged = new Intent(Intent.ACTION_PACKAGE_CHANGED);
1965         final BroadcastRecord packageChangedRecord = makeBroadcastRecord(packageChanged,
1966                 List.of(makeRegisteredReceiver(greenProcess, 0)));
1967         mImpl.enqueueBroadcastLocked(packageChangedRecord);
1968 
1969         assertEquals(BroadcastProcessQueue.REASON_CACHED, greenQueue.getRunnableAtReason());
1970         assertTrue(greenQueue.shouldBeDeferred());
1971         assertEquals(BroadcastProcessQueue.REASON_NORMAL, redQueue.getRunnableAtReason());
1972         assertFalse(redQueue.shouldBeDeferred());
1973 
1974         // All broadcasts to the green process, including the newly enqueued one, should be
1975         // deferred.
1976         greenQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> {
1977             assertEquals("Unexpected state for " + r,
1978                     BroadcastRecord.DELIVERY_DEFERRED, r.getDeliveryState(i));
1979         }, false /* andRemove */);
1980         redQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> {
1981             assertEquals("Unexpected state for " + r,
1982                     BroadcastRecord.DELIVERY_PENDING, r.getDeliveryState(i));
1983         }, false /* andRemove */);
1984 
1985         // Simulate process state change
1986         greenQueue.setProcessAndUidState(greenProcess, false /* uidForeground */,
1987                 false /* processFreezable */);
1988         greenQueue.updateDeferredStates(mImpl.mBroadcastConsumerDeferApply,
1989                 mImpl.mBroadcastConsumerDeferClear);
1990 
1991         assertEquals(BroadcastProcessQueue.REASON_NORMAL, greenQueue.getRunnableAtReason());
1992         assertFalse(greenQueue.shouldBeDeferred());
1993         assertEquals(BroadcastProcessQueue.REASON_NORMAL, redQueue.getRunnableAtReason());
1994         assertFalse(redQueue.shouldBeDeferred());
1995 
1996         greenQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> {
1997             assertEquals("Unexpected state for " + r,
1998                     BroadcastRecord.DELIVERY_PENDING, r.getDeliveryState(i));
1999         }, false /* andRemove */);
2000         redQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> {
2001             assertEquals("Unexpected state for " + r,
2002                     BroadcastRecord.DELIVERY_PENDING, r.getDeliveryState(i));
2003         }, false /* andRemove */);
2004     }
2005 
2006     @EnableFlags(Flags.FLAG_LIMIT_PRIORITY_SCOPE)
2007     @SuppressWarnings("GuardedBy")
2008     @Test
testDeliveryDeferredForCached_changeIdDisabled()2009     public void testDeliveryDeferredForCached_changeIdDisabled() throws Exception {
2010         doReturn(false).when(mPlatformCompat).isChangeEnabledInternalNoLogging(
2011                 eq(BroadcastRecord.LIMIT_PRIORITY_SCOPE),
2012                 argThat(appInfoEquals(getUidForPackage(PACKAGE_GREEN))));
2013 
2014         final ProcessRecord greenProcess = makeProcessRecord(makeApplicationInfo(PACKAGE_GREEN));
2015         final ProcessRecord redProcess = makeProcessRecord(makeApplicationInfo(PACKAGE_RED));
2016 
2017         final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK);
2018         final BroadcastRecord timeTickRecord = makeBroadcastRecord(timeTick,
2019                 List.of(makeRegisteredReceiver(greenProcess, 0)));
2020 
2021         final Intent batteryChanged = new Intent(Intent.ACTION_BATTERY_CHANGED);
2022         final BroadcastOptions optionsBatteryChanged =
2023                 BroadcastOptions.makeWithDeferUntilActive(true);
2024         final BroadcastRecord batteryChangedRecord = makeBroadcastRecord(batteryChanged,
2025                 optionsBatteryChanged,
2026                 List.of(makeRegisteredReceiver(greenProcess, 10),
2027                         makeRegisteredReceiver(redProcess, 0)),
2028                 false /* ordered */);
2029 
2030         mImpl.enqueueBroadcastLocked(timeTickRecord);
2031         mImpl.enqueueBroadcastLocked(batteryChangedRecord);
2032 
2033         final BroadcastProcessQueue greenQueue = mImpl.getProcessQueue(PACKAGE_GREEN,
2034                 getUidForPackage(PACKAGE_GREEN));
2035         final BroadcastProcessQueue redQueue = mImpl.getProcessQueue(PACKAGE_RED,
2036                 getUidForPackage(PACKAGE_RED));
2037         assertEquals(BroadcastProcessQueue.REASON_NORMAL, greenQueue.getRunnableAtReason());
2038         assertFalse(greenQueue.shouldBeDeferred());
2039         assertEquals(BroadcastProcessQueue.REASON_BLOCKED, redQueue.getRunnableAtReason());
2040         assertFalse(redQueue.shouldBeDeferred());
2041 
2042         // Simulate process state change
2043         greenQueue.setProcessAndUidState(greenProcess, false /* uidForeground */,
2044                 true /* processFreezable */);
2045         greenQueue.updateDeferredStates(mImpl.mBroadcastConsumerDeferApply,
2046                 mImpl.mBroadcastConsumerDeferClear);
2047 
2048         assertEquals(BroadcastProcessQueue.REASON_CACHED, greenQueue.getRunnableAtReason());
2049         assertTrue(greenQueue.shouldBeDeferred());
2050         // Once the broadcasts to green process are deferred, broadcasts to red process
2051         // shouldn't be blocked anymore.
2052         assertEquals(BroadcastProcessQueue.REASON_NORMAL, redQueue.getRunnableAtReason());
2053         assertFalse(redQueue.shouldBeDeferred());
2054 
2055         // All broadcasts to green process should be deferred.
2056         greenQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> {
2057             assertEquals("Unexpected state for " + r,
2058                     BroadcastRecord.DELIVERY_DEFERRED, r.getDeliveryState(i));
2059         }, false /* andRemove */);
2060         redQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> {
2061             assertEquals("Unexpected state for " + r,
2062                     BroadcastRecord.DELIVERY_PENDING, r.getDeliveryState(i));
2063         }, false /* andRemove */);
2064 
2065         final Intent packageChanged = new Intent(Intent.ACTION_PACKAGE_CHANGED);
2066         final BroadcastRecord packageChangedRecord = makeBroadcastRecord(packageChanged,
2067                 List.of(makeRegisteredReceiver(greenProcess, 0)));
2068         mImpl.enqueueBroadcastLocked(packageChangedRecord);
2069 
2070         assertEquals(BroadcastProcessQueue.REASON_CACHED, greenQueue.getRunnableAtReason());
2071         assertTrue(greenQueue.shouldBeDeferred());
2072         assertEquals(BroadcastProcessQueue.REASON_NORMAL, redQueue.getRunnableAtReason());
2073         assertFalse(redQueue.shouldBeDeferred());
2074 
2075         // All broadcasts to the green process, including the newly enqueued one, should be
2076         // deferred.
2077         greenQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> {
2078             assertEquals("Unexpected state for " + r,
2079                     BroadcastRecord.DELIVERY_DEFERRED, r.getDeliveryState(i));
2080         }, false /* andRemove */);
2081         redQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> {
2082             assertEquals("Unexpected state for " + r,
2083                     BroadcastRecord.DELIVERY_PENDING, r.getDeliveryState(i));
2084         }, false /* andRemove */);
2085 
2086         // Simulate process state change
2087         greenQueue.setProcessAndUidState(greenProcess, false /* uidForeground */,
2088                 false /* processFreezable */);
2089         greenQueue.updateDeferredStates(mImpl.mBroadcastConsumerDeferApply,
2090                 mImpl.mBroadcastConsumerDeferClear);
2091 
2092         assertEquals(BroadcastProcessQueue.REASON_NORMAL, greenQueue.getRunnableAtReason());
2093         assertFalse(greenQueue.shouldBeDeferred());
2094         assertEquals(BroadcastProcessQueue.REASON_NORMAL, redQueue.getRunnableAtReason());
2095         assertFalse(redQueue.shouldBeDeferred());
2096 
2097         greenQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> {
2098             assertEquals("Unexpected state for " + r,
2099                     BroadcastRecord.DELIVERY_PENDING, r.getDeliveryState(i));
2100         }, false /* andRemove */);
2101         redQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> {
2102             assertEquals("Unexpected state for " + r,
2103                     BroadcastRecord.DELIVERY_PENDING, r.getDeliveryState(i));
2104         }, false /* andRemove */);
2105     }
2106 
2107     @DisableFlags(Flags.FLAG_LIMIT_PRIORITY_SCOPE)
2108     @SuppressWarnings("GuardedBy")
2109     @Test
testDeliveryDeferredForCached_withInfiniteDeferred_flagDisabled()2110     public void testDeliveryDeferredForCached_withInfiniteDeferred_flagDisabled() throws Exception {
2111         final ProcessRecord greenProcess = makeProcessRecord(makeApplicationInfo(PACKAGE_GREEN));
2112         final ProcessRecord redProcess = makeProcessRecord(makeApplicationInfo(PACKAGE_RED));
2113 
2114         final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK);
2115         final BroadcastOptions optionsTimeTick = BroadcastOptions.makeWithDeferUntilActive(true);
2116         final BroadcastRecord timeTickRecord = makeBroadcastRecord(timeTick, optionsTimeTick,
2117                 List.of(makeRegisteredReceiver(greenProcess, 0)), false /* ordered */);
2118 
2119         final Intent batteryChanged = new Intent(Intent.ACTION_BATTERY_CHANGED);
2120         final BroadcastOptions optionsBatteryChanged =
2121                 BroadcastOptions.makeWithDeferUntilActive(true);
2122         final BroadcastRecord batteryChangedRecord = makeBroadcastRecord(batteryChanged,
2123                 optionsBatteryChanged,
2124                 List.of(makeRegisteredReceiver(greenProcess, 10),
2125                         makeRegisteredReceiver(redProcess, 0)),
2126                 false /* ordered */);
2127 
2128         mImpl.enqueueBroadcastLocked(timeTickRecord);
2129         mImpl.enqueueBroadcastLocked(batteryChangedRecord);
2130 
2131         final BroadcastProcessQueue greenQueue = mImpl.getProcessQueue(PACKAGE_GREEN,
2132                 getUidForPackage(PACKAGE_GREEN));
2133         final BroadcastProcessQueue redQueue = mImpl.getProcessQueue(PACKAGE_RED,
2134                 getUidForPackage(PACKAGE_RED));
2135         assertEquals(BroadcastProcessQueue.REASON_NORMAL, greenQueue.getRunnableAtReason());
2136         assertFalse(greenQueue.shouldBeDeferred());
2137         assertEquals(BroadcastProcessQueue.REASON_BLOCKED, redQueue.getRunnableAtReason());
2138         assertFalse(redQueue.shouldBeDeferred());
2139 
2140         // Simulate process state change
2141         greenQueue.setProcessAndUidState(greenProcess, false /* uidForeground */,
2142                 true /* processFreezable */);
2143         greenQueue.updateDeferredStates(mImpl.mBroadcastConsumerDeferApply,
2144                 mImpl.mBroadcastConsumerDeferClear);
2145 
2146         assertEquals(BroadcastProcessQueue.REASON_CACHED_INFINITE_DEFER,
2147                 greenQueue.getRunnableAtReason());
2148         assertTrue(greenQueue.shouldBeDeferred());
2149         // Once the broadcasts to green process are deferred, broadcasts to red process
2150         // shouldn't be blocked anymore.
2151         assertEquals(BroadcastProcessQueue.REASON_NORMAL, redQueue.getRunnableAtReason());
2152         assertFalse(redQueue.shouldBeDeferred());
2153 
2154         // All broadcasts to green process should be deferred.
2155         greenQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> {
2156             assertEquals("Unexpected state for " + r,
2157                     BroadcastRecord.DELIVERY_DEFERRED, r.getDeliveryState(i));
2158         }, false /* andRemove */);
2159         redQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> {
2160             assertEquals("Unexpected state for " + r,
2161                     BroadcastRecord.DELIVERY_PENDING, r.getDeliveryState(i));
2162         }, false /* andRemove */);
2163 
2164         final Intent packageChanged = new Intent(Intent.ACTION_PACKAGE_CHANGED);
2165         final BroadcastOptions optionsPackageChanged =
2166                 BroadcastOptions.makeWithDeferUntilActive(true);
2167         final BroadcastRecord packageChangedRecord = makeBroadcastRecord(packageChanged,
2168                 optionsPackageChanged,
2169                 List.of(makeRegisteredReceiver(greenProcess, 0)), false /* ordered */);
2170         mImpl.enqueueBroadcastLocked(packageChangedRecord);
2171 
2172         assertEquals(BroadcastProcessQueue.REASON_CACHED_INFINITE_DEFER,
2173                 greenQueue.getRunnableAtReason());
2174         assertTrue(greenQueue.shouldBeDeferred());
2175         assertEquals(BroadcastProcessQueue.REASON_NORMAL, redQueue.getRunnableAtReason());
2176         assertFalse(redQueue.shouldBeDeferred());
2177 
2178         // All broadcasts to the green process, including the newly enqueued one, should be
2179         // deferred.
2180         greenQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> {
2181             assertEquals("Unexpected state for " + r,
2182                     BroadcastRecord.DELIVERY_DEFERRED, r.getDeliveryState(i));
2183         }, false /* andRemove */);
2184         redQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> {
2185             assertEquals("Unexpected state for " + r,
2186                     BroadcastRecord.DELIVERY_PENDING, r.getDeliveryState(i));
2187         }, false /* andRemove */);
2188 
2189         // Simulate process state change
2190         greenQueue.setProcessAndUidState(greenProcess, false /* uidForeground */,
2191                 false /* processFreezable */);
2192         greenQueue.updateDeferredStates(mImpl.mBroadcastConsumerDeferApply,
2193                 mImpl.mBroadcastConsumerDeferClear);
2194 
2195         assertEquals(BroadcastProcessQueue.REASON_NORMAL, greenQueue.getRunnableAtReason());
2196         assertFalse(greenQueue.shouldBeDeferred());
2197         assertEquals(BroadcastProcessQueue.REASON_NORMAL, redQueue.getRunnableAtReason());
2198         assertFalse(redQueue.shouldBeDeferred());
2199 
2200         greenQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> {
2201             assertEquals("Unexpected state for " + r,
2202                     BroadcastRecord.DELIVERY_PENDING, r.getDeliveryState(i));
2203         }, false /* andRemove */);
2204         redQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> {
2205             assertEquals("Unexpected state for " + r,
2206                     BroadcastRecord.DELIVERY_PENDING, r.getDeliveryState(i));
2207         }, false /* andRemove */);
2208     }
2209 
2210     @EnableFlags(Flags.FLAG_LIMIT_PRIORITY_SCOPE)
2211     @Test
testDeliveryDeferredForCached_withInfiniteDeferred_changeIdDisabled()2212     public void testDeliveryDeferredForCached_withInfiniteDeferred_changeIdDisabled()
2213             throws Exception {
2214         doReturn(false).when(mPlatformCompat).isChangeEnabledInternalNoLogging(
2215                 eq(BroadcastRecord.LIMIT_PRIORITY_SCOPE),
2216                 argThat(appInfoEquals(getUidForPackage(PACKAGE_GREEN))));
2217         final ProcessRecord greenProcess = makeProcessRecord(makeApplicationInfo(PACKAGE_GREEN));
2218         final ProcessRecord redProcess = makeProcessRecord(makeApplicationInfo(PACKAGE_RED));
2219 
2220         final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK);
2221         final BroadcastOptions optionsTimeTick = BroadcastOptions.makeWithDeferUntilActive(true);
2222         final BroadcastRecord timeTickRecord = makeBroadcastRecord(timeTick, optionsTimeTick,
2223                 List.of(makeRegisteredReceiver(greenProcess, 0)), false /* ordered */);
2224 
2225         final Intent batteryChanged = new Intent(Intent.ACTION_BATTERY_CHANGED);
2226         final BroadcastOptions optionsBatteryChanged =
2227                 BroadcastOptions.makeWithDeferUntilActive(true);
2228         final BroadcastRecord batteryChangedRecord = makeBroadcastRecord(batteryChanged,
2229                 optionsBatteryChanged,
2230                 List.of(makeRegisteredReceiver(greenProcess, 10),
2231                         makeRegisteredReceiver(redProcess, 0)),
2232                 false /* ordered */);
2233 
2234         mImpl.enqueueBroadcastLocked(timeTickRecord);
2235         mImpl.enqueueBroadcastLocked(batteryChangedRecord);
2236 
2237         final BroadcastProcessQueue greenQueue = mImpl.getProcessQueue(PACKAGE_GREEN,
2238                 getUidForPackage(PACKAGE_GREEN));
2239         final BroadcastProcessQueue redQueue = mImpl.getProcessQueue(PACKAGE_RED,
2240                 getUidForPackage(PACKAGE_RED));
2241         assertEquals(BroadcastProcessQueue.REASON_NORMAL, greenQueue.getRunnableAtReason());
2242         assertFalse(greenQueue.shouldBeDeferred());
2243         assertEquals(BroadcastProcessQueue.REASON_BLOCKED, redQueue.getRunnableAtReason());
2244         assertFalse(redQueue.shouldBeDeferred());
2245 
2246         // Simulate process state change
2247         greenQueue.setProcessAndUidState(greenProcess, false /* uidForeground */,
2248                 true /* processFreezable */);
2249         greenQueue.updateDeferredStates(mImpl.mBroadcastConsumerDeferApply,
2250                 mImpl.mBroadcastConsumerDeferClear);
2251 
2252         assertEquals(BroadcastProcessQueue.REASON_CACHED_INFINITE_DEFER,
2253                 greenQueue.getRunnableAtReason());
2254         assertTrue(greenQueue.shouldBeDeferred());
2255         // Once the broadcasts to green process are deferred, broadcasts to red process
2256         // shouldn't be blocked anymore.
2257         assertEquals(BroadcastProcessQueue.REASON_NORMAL, redQueue.getRunnableAtReason());
2258         assertFalse(redQueue.shouldBeDeferred());
2259 
2260         // All broadcasts to green process should be deferred.
2261         greenQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> {
2262             assertEquals("Unexpected state for " + r,
2263                     BroadcastRecord.DELIVERY_DEFERRED, r.getDeliveryState(i));
2264         }, false /* andRemove */);
2265         redQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> {
2266             assertEquals("Unexpected state for " + r,
2267                     BroadcastRecord.DELIVERY_PENDING, r.getDeliveryState(i));
2268         }, false /* andRemove */);
2269 
2270         final Intent packageChanged = new Intent(Intent.ACTION_PACKAGE_CHANGED);
2271         final BroadcastOptions optionsPackageChanged =
2272                 BroadcastOptions.makeWithDeferUntilActive(true);
2273         final BroadcastRecord packageChangedRecord = makeBroadcastRecord(packageChanged,
2274                 optionsPackageChanged,
2275                 List.of(makeRegisteredReceiver(greenProcess, 0)), false /* ordered */);
2276         mImpl.enqueueBroadcastLocked(packageChangedRecord);
2277 
2278         assertEquals(BroadcastProcessQueue.REASON_CACHED_INFINITE_DEFER,
2279                 greenQueue.getRunnableAtReason());
2280         assertTrue(greenQueue.shouldBeDeferred());
2281         assertEquals(BroadcastProcessQueue.REASON_NORMAL, redQueue.getRunnableAtReason());
2282         assertFalse(redQueue.shouldBeDeferred());
2283 
2284         // All broadcasts to the green process, including the newly enqueued one, should be
2285         // deferred.
2286         greenQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> {
2287             assertEquals("Unexpected state for " + r,
2288                     BroadcastRecord.DELIVERY_DEFERRED, r.getDeliveryState(i));
2289         }, false /* andRemove */);
2290         redQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> {
2291             assertEquals("Unexpected state for " + r,
2292                     BroadcastRecord.DELIVERY_PENDING, r.getDeliveryState(i));
2293         }, false /* andRemove */);
2294 
2295         // Simulate process state change
2296         greenQueue.setProcessAndUidState(greenProcess, false /* uidForeground */,
2297                 false /* processFreezable */);
2298         greenQueue.updateDeferredStates(mImpl.mBroadcastConsumerDeferApply,
2299                 mImpl.mBroadcastConsumerDeferClear);
2300 
2301         assertEquals(BroadcastProcessQueue.REASON_NORMAL, greenQueue.getRunnableAtReason());
2302         assertFalse(greenQueue.shouldBeDeferred());
2303         assertEquals(BroadcastProcessQueue.REASON_NORMAL, redQueue.getRunnableAtReason());
2304         assertFalse(redQueue.shouldBeDeferred());
2305 
2306         greenQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> {
2307             assertEquals("Unexpected state for " + r,
2308                     BroadcastRecord.DELIVERY_PENDING, r.getDeliveryState(i));
2309         }, false /* andRemove */);
2310         redQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> {
2311             assertEquals("Unexpected state for " + r,
2312                     BroadcastRecord.DELIVERY_PENDING, r.getDeliveryState(i));
2313         }, false /* andRemove */);
2314     }
2315 
2316     @Test
testIsProcessFreezable()2317     public void testIsProcessFreezable() throws Exception {
2318         final ProcessRecord greenProcess = makeProcessRecord(makeApplicationInfo(PACKAGE_GREEN));
2319 
2320         setProcessFreezable(greenProcess, true /* pendingFreeze */, true /* frozen */);
2321         mImpl.onProcessFreezableChangedLocked(greenProcess);
2322         waitForIdle();
2323         assertTrue(mImpl.isProcessFreezable(greenProcess));
2324 
2325         setProcessFreezable(greenProcess, true /* pendingFreeze */, false /* frozen */);
2326         mImpl.onProcessFreezableChangedLocked(greenProcess);
2327         waitForIdle();
2328         assertTrue(mImpl.isProcessFreezable(greenProcess));
2329 
2330         setProcessFreezable(greenProcess, false /* pendingFreeze */, true /* frozen */);
2331         mImpl.onProcessFreezableChangedLocked(greenProcess);
2332         waitForIdle();
2333         assertTrue(mImpl.isProcessFreezable(greenProcess));
2334 
2335         setProcessFreezable(greenProcess, false /* pendingFreeze */, false /* frozen */);
2336         mImpl.onProcessFreezableChangedLocked(greenProcess);
2337         waitForIdle();
2338         assertFalse(mImpl.isProcessFreezable(greenProcess));
2339     }
2340 
2341     @SuppressWarnings("GuardedBy")
testBroadcastProcessedEventRecordLogged( boolean isAssumedDelivered, boolean isDelivered, int numberOfInvocations)2342     private void testBroadcastProcessedEventRecordLogged(
2343             boolean isAssumedDelivered,
2344             boolean isDelivered,
2345             int numberOfInvocations) throws Exception {
2346         final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK);
2347         final BroadcastOptions optionsTimeTick = BroadcastOptions.makeBasic();
2348         optionsTimeTick.setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT);
2349 
2350         final BroadcastRecord broadcastRecordSpy = Mockito.spy(
2351                 makeBroadcastRecord(timeTick, optionsTimeTick));
2352         mImpl.enqueueBroadcastLocked(broadcastRecordSpy);
2353 
2354         doReturn(isDelivered).when(broadcastRecordSpy).wasDelivered(anyInt());
2355         doReturn(isAssumedDelivered).when(broadcastRecordSpy).isAssumedDelivered(anyInt());
2356         waitForIdle();
2357 
2358         verify(broadcastRecordSpy, times(numberOfInvocations)).updateBroadcastProcessedEventRecord(
2359                 any(), anyLong());
2360         verify(broadcastRecordSpy).logBroadcastProcessedEventRecord();
2361     }
2362 
makeRegisteredReceiver(ProcessRecord app, int priority)2363     BroadcastFilter makeRegisteredReceiver(ProcessRecord app, int priority) {
2364         final IIntentReceiver receiver = mock(IIntentReceiver.class);
2365         final ReceiverList receiverList = new ReceiverList(mAms, app, app.getPid(), app.info.uid,
2366                 UserHandle.getUserId(app.info.uid), receiver);
2367         return makeRegisteredReceiver(receiverList, priority, null /* requiredPermission */);
2368     }
2369 
createPackageChangedIntent(int uid, List<String> componentNameList)2370     private Intent createPackageChangedIntent(int uid, List<String> componentNameList) {
2371         final Intent packageChangedIntent = new Intent(Intent.ACTION_PACKAGE_CHANGED);
2372         packageChangedIntent.putExtra(Intent.EXTRA_UID, uid);
2373         packageChangedIntent.putExtra(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST,
2374                 componentNameList.toArray());
2375         return packageChangedIntent;
2376     }
2377 
verifyPendingRecords(BroadcastProcessQueue queue, List<Intent> intents)2378     private void verifyPendingRecords(BroadcastProcessQueue queue,
2379             List<Intent> intents) {
2380         for (int i = 0; i < intents.size(); i++) {
2381             queue.makeActiveNextPending();
2382 
2383             // While we're here, give our health check some test coverage
2384             queue.assertHealthLocked();
2385             queue.dumpLocked(0L, new IndentingPrintWriter(Writer.nullWriter()));
2386 
2387             final Intent actualIntent = queue.getActive().intent;
2388             final Intent expectedIntent = intents.get(i);
2389             final String errMsg = "actual=" + actualIntent + ", expected=" + expectedIntent
2390                     + ", actual_extras=" + actualIntent.getExtras()
2391                     + ", expected_extras=" + expectedIntent.getExtras();
2392             assertTrue(errMsg, actualIntent.filterEquals(expectedIntent));
2393             assertBundleEquals(expectedIntent.getExtras(), actualIntent.getExtras());
2394         }
2395         assertTrue(queue.isEmpty());
2396     }
2397 
assertBundleEquals(Bundle expected, Bundle actual)2398     private void assertBundleEquals(Bundle expected, Bundle actual) {
2399         final String errMsg = "expected=" + expected + ", actual=" + actual;
2400         if (expected == actual) {
2401             return;
2402         } else if (expected == null || actual == null) {
2403             fail(errMsg);
2404         }
2405         if (!expected.keySet().equals(actual.keySet())) {
2406             fail(errMsg);
2407         }
2408         for (String key : expected.keySet()) {
2409             final Object expectedValue = expected.get(key);
2410             final Object actualValue = actual.get(key);
2411             if (expectedValue == actualValue) {
2412                 continue;
2413             } else if (expectedValue == null || actualValue == null) {
2414                 fail(errMsg);
2415             }
2416             assertEquals(errMsg, expectedValue.getClass(), actualValue.getClass());
2417             if (expectedValue.getClass().isArray()) {
2418                 assertEquals(errMsg, Array.getLength(expectedValue), Array.getLength(actualValue));
2419                 for (int i = 0; i < Array.getLength(expectedValue); ++i) {
2420                     assertEquals(errMsg, Array.get(expectedValue, i), Array.get(actualValue, i));
2421                 }
2422             } else if (expectedValue instanceof ArrayList) {
2423                 final ArrayList<?> expectedList = (ArrayList<?>) expectedValue;
2424                 final ArrayList<?> actualList = (ArrayList<?>) actualValue;
2425                 assertEquals(errMsg, expectedList.size(), actualList.size());
2426                 for (int i = 0; i < expectedList.size(); ++i) {
2427                     assertEquals(errMsg, expectedList.get(i), actualList.get(i));
2428                 }
2429             } else {
2430                 assertEquals(errMsg, expectedValue, actualValue);
2431             }
2432         }
2433     }
2434 }
2435