1 /*
2  * Copyright (C) 2018 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.server.am.BroadcastRecord.DELIVERY_DEFERRED;
22 import static com.android.server.am.BroadcastRecord.DELIVERY_DELIVERED;
23 import static com.android.server.am.BroadcastRecord.DELIVERY_PENDING;
24 import static com.android.server.am.BroadcastRecord.DELIVERY_SKIPPED;
25 import static com.android.server.am.BroadcastRecord.DELIVERY_TIMEOUT;
26 import static com.android.server.am.BroadcastRecord.calculateBlockedUntilBeyondCount;
27 import static com.android.server.am.BroadcastRecord.calculateDeferUntilActive;
28 import static com.android.server.am.BroadcastRecord.calculateUrgent;
29 import static com.android.server.am.BroadcastRecord.isReceiverEquals;
30 
31 import static org.junit.Assert.assertArrayEquals;
32 import static org.junit.Assert.assertEquals;
33 import static org.junit.Assert.assertFalse;
34 import static org.junit.Assert.assertNull;
35 import static org.junit.Assert.assertTrue;
36 
37 import android.app.BackgroundStartPrivileges;
38 import android.app.BroadcastOptions;
39 import android.content.IIntentReceiver;
40 import android.content.Intent;
41 import android.content.IntentFilter;
42 import android.content.pm.ActivityInfo;
43 import android.content.pm.ApplicationInfo;
44 import android.content.pm.ResolveInfo;
45 import android.os.Bundle;
46 import android.os.PersistableBundle;
47 import android.os.Process;
48 import android.os.UserHandle;
49 import android.telephony.SubscriptionManager;
50 
51 import androidx.test.filters.SmallTest;
52 
53 import org.junit.Before;
54 import org.junit.Test;
55 import org.junit.runner.RunWith;
56 import org.mockito.Mock;
57 import org.mockito.MockitoAnnotations;
58 import org.mockito.junit.MockitoJUnitRunner;
59 
60 import java.util.ArrayList;
61 import java.util.Collections;
62 import java.util.List;
63 import java.util.function.BiFunction;
64 
65 /**
66  * Test class for {@link BroadcastRecord}.
67  *
68  * Build/Install/Run:
69  *  atest FrameworksServicesTests:BroadcastRecordTest
70  */
71 @SmallTest
72 @RunWith(MockitoJUnitRunner.class)
73 public class BroadcastRecordTest {
74     private static final String TAG = "BroadcastRecordTest";
75 
76     private static final int USER0 = UserHandle.USER_SYSTEM;
77     private static final String PACKAGE1 = "pkg1";
78     private static final String PACKAGE2 = "pkg2";
79     private static final String PACKAGE3 = "pkg3";
80 
81     private static final int SYSTEM_UID = android.os.Process.SYSTEM_UID;
82     private static final int APP_UID = android.os.Process.FIRST_APPLICATION_UID;
83 
84     private static final BroadcastOptions OPT_DEFAULT = BroadcastOptions.makeBasic();
85     private static final BroadcastOptions OPT_NONE = BroadcastOptions.makeBasic()
86             .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_NONE);
87     private static final BroadcastOptions OPT_UNTIL_ACTIVE = BroadcastOptions.makeBasic()
88             .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE);
89 
90     @Mock BroadcastQueue mQueue;
91     @Mock ProcessRecord mProcess;
92 
93     @Before
setUp()94     public void setUp() throws Exception {
95         MockitoAnnotations.initMocks(this);
96     }
97 
98     @Test
testIsPrioritized_Empty()99     public void testIsPrioritized_Empty() {
100         assertFalse(isPrioritized(List.of()));
101     }
102 
103     @Test
testIsPrioritized_Single()104     public void testIsPrioritized_Single() {
105         assertFalse(isPrioritized(List.of(createResolveInfo(PACKAGE1, getAppId(1), 0))));
106         assertFalse(isPrioritized(List.of(createResolveInfo(PACKAGE1, getAppId(1), -10))));
107         assertFalse(isPrioritized(List.of(createResolveInfo(PACKAGE1, getAppId(1), 10))));
108 
109         assertArrayEquals(new int[] {-1},
110                 calculateBlockedUntilBeyondCount(List.of(
111                         createResolveInfo(PACKAGE1, getAppId(1), 0)), false));
112         assertArrayEquals(new int[] {-1},
113                 calculateBlockedUntilBeyondCount(List.of(
114                         createResolveInfo(PACKAGE1, getAppId(1), -10)), false));
115         assertArrayEquals(new int[] {-1},
116                 calculateBlockedUntilBeyondCount(List.of(
117                         createResolveInfo(PACKAGE1, getAppId(1), 10)), false));
118     }
119 
120     @Test
testIsPrioritized_No()121     public void testIsPrioritized_No() {
122         assertFalse(isPrioritized(List.of(
123                 createResolveInfo(PACKAGE1, getAppId(1), 0),
124                 createResolveInfo(PACKAGE2, getAppId(2), 0),
125                 createResolveInfo(PACKAGE3, getAppId(3), 0))));
126         assertFalse(isPrioritized(List.of(
127                 createResolveInfo(PACKAGE1, getAppId(1), 10),
128                 createResolveInfo(PACKAGE2, getAppId(2), 10),
129                 createResolveInfo(PACKAGE3, getAppId(3), 10))));
130 
131         assertArrayEquals(new int[] {-1,-1,-1},
132                 calculateBlockedUntilBeyondCount(List.of(
133                         createResolveInfo(PACKAGE1, getAppId(1), 0),
134                         createResolveInfo(PACKAGE2, getAppId(2), 0),
135                         createResolveInfo(PACKAGE3, getAppId(3), 0)), false));
136         assertArrayEquals(new int[] {-1,-1,-1},
137                 calculateBlockedUntilBeyondCount(List.of(
138                         createResolveInfo(PACKAGE1, getAppId(1), 10),
139                         createResolveInfo(PACKAGE2, getAppId(2), 10),
140                         createResolveInfo(PACKAGE3, getAppId(3), 10)), false));
141     }
142 
143     @Test
testIsPrioritized_Yes()144     public void testIsPrioritized_Yes() {
145         assertTrue(isPrioritized(List.of(
146                 createResolveInfo(PACKAGE1, getAppId(1), 10),
147                 createResolveInfo(PACKAGE2, getAppId(2), 0),
148                 createResolveInfo(PACKAGE3, getAppId(3), -10))));
149         assertTrue(isPrioritized(List.of(
150                 createResolveInfo(PACKAGE1, getAppId(1), 10),
151                 createResolveInfo(PACKAGE2, getAppId(2), 0),
152                 createResolveInfo(PACKAGE3, getAppId(3), 0))));
153 
154         assertArrayEquals(new int[] {0,1,2},
155                 calculateBlockedUntilBeyondCount(List.of(
156                         createResolveInfo(PACKAGE1, getAppId(1), 10),
157                         createResolveInfo(PACKAGE2, getAppId(2), 0),
158                         createResolveInfo(PACKAGE3, getAppId(3), -10)), false));
159         assertArrayEquals(new int[] {0,0,2,3,3},
160                 calculateBlockedUntilBeyondCount(List.of(
161                         createResolveInfo(PACKAGE1, getAppId(1), 20),
162                         createResolveInfo(PACKAGE2, getAppId(2), 20),
163                         createResolveInfo(PACKAGE3, getAppId(3), 10),
164                         createResolveInfo(PACKAGE3, getAppId(3), 0),
165                         createResolveInfo(PACKAGE3, getAppId(3), 0)), false));
166     }
167 
168     @Test
testSetDeliveryState_Single()169     public void testSetDeliveryState_Single() {
170         final BroadcastRecord r = createBroadcastRecord(
171                 new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED), List.of(
172                         createResolveInfoWithPriority(0)));
173         assertEquals(DELIVERY_PENDING, r.getDeliveryState(0));
174         assertBlocked(r, false);
175         assertTerminalDeferredBeyond(r, 0, 0, 0);
176 
177         r.setDeliveryState(0, DELIVERY_DEFERRED, TAG);
178         assertEquals(DELIVERY_DEFERRED, r.getDeliveryState(0));
179         assertBlocked(r, false);
180         assertTerminalDeferredBeyond(r, 0, 1, 1);
181 
182         // Identical state change has no effect
183         r.setDeliveryState(0, DELIVERY_DEFERRED, TAG);
184         assertEquals(DELIVERY_DEFERRED, r.getDeliveryState(0));
185         assertBlocked(r, false);
186         assertTerminalDeferredBeyond(r, 0, 1, 1);
187 
188         // Moving to terminal state updates counters
189         r.setDeliveryState(0, DELIVERY_DELIVERED, TAG);
190         assertEquals(DELIVERY_DELIVERED, r.getDeliveryState(0));
191         assertBlocked(r, false);
192         assertTerminalDeferredBeyond(r, 1, 0, 1);
193 
194         // Trying to change terminal state has no effect
195         r.setDeliveryState(0, DELIVERY_TIMEOUT, TAG);
196         assertEquals(DELIVERY_DELIVERED, r.getDeliveryState(0));
197         assertBlocked(r, false);
198         assertTerminalDeferredBeyond(r, 1, 0, 1);
199     }
200 
201     @Test
testSetDeliveryState_Unordered()202     public void testSetDeliveryState_Unordered() {
203         final BroadcastRecord r = createBroadcastRecord(
204                 new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED), List.of(
205                         createResolveInfoWithPriority(0),
206                         createResolveInfoWithPriority(0),
207                         createResolveInfoWithPriority(0)));
208         assertBlocked(r, false, false, false);
209         assertTerminalDeferredBeyond(r, 0, 0, 0);
210 
211         // Even though we finish a middle item in the tranche, we're not
212         // "beyond" it because there is still unfinished work before it
213         r.setDeliveryState(1, DELIVERY_DELIVERED, TAG);
214         assertBlocked(r, false, false, false);
215         assertTerminalDeferredBeyond(r, 1, 0, 0);
216 
217         r.setDeliveryState(0, DELIVERY_DELIVERED, TAG);
218         assertBlocked(r, false, false, false);
219         assertTerminalDeferredBeyond(r, 2, 0, 2);
220 
221         r.setDeliveryState(2, DELIVERY_DELIVERED, TAG);
222         assertBlocked(r, false, false, false);
223         assertTerminalDeferredBeyond(r, 3, 0, 3);
224     }
225 
226     @Test
testSetDeliveryState_Ordered()227     public void testSetDeliveryState_Ordered() {
228         final BroadcastRecord r = createOrderedBroadcastRecord(
229                 new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED), List.of(
230                         createResolveInfoWithPriority(0),
231                         createResolveInfoWithPriority(0),
232                         createResolveInfoWithPriority(0)));
233         assertBlocked(r, false, true, true);
234         assertTerminalDeferredBeyond(r, 0, 0, 0);
235 
236         r.setDeliveryState(0, DELIVERY_DELIVERED, TAG);
237         assertBlocked(r, false, false, true);
238         assertTerminalDeferredBeyond(r, 1, 0, 1);
239 
240         r.setDeliveryState(1, DELIVERY_DELIVERED, TAG);
241         assertBlocked(r, false, false, false);
242         assertTerminalDeferredBeyond(r, 2, 0, 2);
243 
244         r.setDeliveryState(2, DELIVERY_DELIVERED, TAG);
245         assertBlocked(r, false, false, false);
246         assertTerminalDeferredBeyond(r, 3, 0, 3);
247     }
248 
249     @Test
testSetDeliveryState_DeferUntilActive()250     public void testSetDeliveryState_DeferUntilActive() {
251         final BroadcastRecord r = createBroadcastRecord(
252                 new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED), List.of(
253                         createResolveInfoWithPriority(10),
254                         createResolveInfoWithPriority(10),
255                         createResolveInfoWithPriority(10),
256                         createResolveInfoWithPriority(0),
257                         createResolveInfoWithPriority(0),
258                         createResolveInfoWithPriority(0),
259                         createResolveInfoWithPriority(-10),
260                         createResolveInfoWithPriority(-10),
261                         createResolveInfoWithPriority(-10)));
262         assertBlocked(r, false, false, false, true, true, true, true, true, true);
263         assertTerminalDeferredBeyond(r, 0, 0, 0);
264 
265         r.setDeliveryState(0, DELIVERY_PENDING, TAG);
266         r.setDeliveryState(1, DELIVERY_DEFERRED, TAG);
267         r.setDeliveryState(2, DELIVERY_PENDING, TAG);
268         r.setDeliveryState(3, DELIVERY_DEFERRED, TAG);
269         r.setDeliveryState(4, DELIVERY_DEFERRED, TAG);
270         r.setDeliveryState(5, DELIVERY_DEFERRED, TAG);
271         r.setDeliveryState(6, DELIVERY_DEFERRED, TAG);
272         r.setDeliveryState(7, DELIVERY_PENDING, TAG);
273         r.setDeliveryState(8, DELIVERY_DEFERRED, TAG);
274 
275         // Verify deferred counts ratchet up, but we're not "beyond" the first
276         // still-pending receiver
277         assertBlocked(r, false, false, false, true, true, true, true, true, true);
278         assertTerminalDeferredBeyond(r, 0, 6, 0);
279 
280         // We're still not "beyond" the first still-pending receiver, even when
281         // we finish a receiver later in the first tranche
282         r.setDeliveryState(2, DELIVERY_DELIVERED, TAG);
283         assertBlocked(r, false, false, false, true, true, true, true, true, true);
284         assertTerminalDeferredBeyond(r, 1, 6, 0);
285 
286         // Completing that last item in first tranche means we now unblock the
287         // second tranche, and since it's entirely deferred, the third traunche
288         // is unblocked too
289         r.setDeliveryState(0, DELIVERY_DELIVERED, TAG);
290         assertBlocked(r, false, false, false, false, false, false, false, false, false);
291         assertTerminalDeferredBeyond(r, 2, 6, 7);
292 
293         // Moving a deferred item in an earlier tranche back to being pending
294         // doesn't change the fact that we've already moved beyond it
295         r.setDeliveryState(1, DELIVERY_PENDING, TAG);
296         assertBlocked(r, false, false, false, false, false, false, false, false, false);
297         assertTerminalDeferredBeyond(r, 2, 5, 7);
298         r.setDeliveryState(1, DELIVERY_DELIVERED, TAG);
299         assertBlocked(r, false, false, false, false, false, false, false, false, false);
300         assertTerminalDeferredBeyond(r, 3, 5, 7);
301 
302         // Completing middle pending item is enough to fast-forward to end
303         r.setDeliveryState(7, DELIVERY_DELIVERED, TAG);
304         assertBlocked(r, false, false, false, false, false, false, false, false, false);
305         assertTerminalDeferredBeyond(r, 4, 5, 9);
306 
307         // Moving everyone else directly into a finished state updates all the
308         // terminal counters
309         r.setDeliveryState(3, DELIVERY_SKIPPED, TAG);
310         r.setDeliveryState(4, DELIVERY_SKIPPED, TAG);
311         r.setDeliveryState(5, DELIVERY_SKIPPED, TAG);
312         r.setDeliveryState(6, DELIVERY_SKIPPED, TAG);
313         r.setDeliveryState(8, DELIVERY_SKIPPED, TAG);
314         assertBlocked(r, false, false, false, false, false, false, false, false, false);
315         assertTerminalDeferredBeyond(r, 9, 0, 9);
316     }
317 
318     @Test
testGetReceiverIntent_Simple()319     public void testGetReceiverIntent_Simple() {
320         final Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
321         final BroadcastRecord r = createBroadcastRecord(
322                 List.of(createResolveInfo(PACKAGE1, getAppId(1))), UserHandle.USER_ALL, intent);
323         final Intent actual = r.getReceiverIntent(r.receivers.get(0));
324         assertEquals(PACKAGE1, actual.getComponent().getPackageName());
325         assertNull(r.intent.getComponent());
326     }
327 
328     @Test
testGetReceiverIntent_Filtered_Partial()329     public void testGetReceiverIntent_Filtered_Partial() {
330         final Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
331         intent.putExtra(Intent.EXTRA_INDEX, 42);
332         final BroadcastRecord r = createBroadcastRecord(
333                 List.of(createResolveInfo(PACKAGE1, getAppId(1))), UserHandle.USER_ALL, intent,
334                 (uid, extras) -> Bundle.EMPTY,
335                 null /* options */);
336         final Intent actual = r.getReceiverIntent(r.receivers.get(0));
337         assertEquals(PACKAGE1, actual.getComponent().getPackageName());
338         assertEquals(-1, actual.getIntExtra(Intent.EXTRA_INDEX, -1));
339         assertNull(r.intent.getComponent());
340         assertEquals(42, r.intent.getIntExtra(Intent.EXTRA_INDEX, -1));
341     }
342 
343     @Test
testGetReceiverIntent_Filtered_Complete()344     public void testGetReceiverIntent_Filtered_Complete() {
345         final Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
346         intent.putExtra(Intent.EXTRA_INDEX, 42);
347         final BroadcastRecord r = createBroadcastRecord(
348                 List.of(createResolveInfo(PACKAGE1, getAppId(1))), UserHandle.USER_ALL, intent,
349                 (uid, extras) -> null,
350                 null /* options */);
351         final Intent actual = r.getReceiverIntent(r.receivers.get(0));
352         assertNull(actual);
353         assertNull(r.intent.getComponent());
354         assertEquals(42, r.intent.getIntExtra(Intent.EXTRA_INDEX, -1));
355     }
356 
357     @Test
testIsReceiverEquals()358     public void testIsReceiverEquals() {
359         final ResolveInfo info = createResolveInfo(PACKAGE1, getAppId(1));
360         assertTrue(isReceiverEquals(info, info));
361         assertTrue(isReceiverEquals(info, createResolveInfo(PACKAGE1, getAppId(1))));
362         assertFalse(isReceiverEquals(info, createResolveInfo(PACKAGE2, getAppId(2))));
363     }
364 
365     @Test
testCalculateUrgent()366     public void testCalculateUrgent() {
367         final Intent intent = new Intent();
368         final Intent intentForeground = new Intent()
369                 .setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
370 
371         assertFalse(calculateUrgent(intent, null));
372         assertTrue(calculateUrgent(intentForeground, null));
373 
374         {
375             final BroadcastOptions opts = BroadcastOptions.makeBasic();
376             assertFalse(calculateUrgent(intent, opts));
377         }
378         {
379             final BroadcastOptions opts = BroadcastOptions.makeBasic();
380             opts.setInteractive(true);
381             assertTrue(calculateUrgent(intent, opts));
382         }
383         {
384             final BroadcastOptions opts = BroadcastOptions.makeBasic();
385             opts.setAlarmBroadcast(true);
386             assertTrue(calculateUrgent(intent, opts));
387         }
388     }
389 
390     @Test
testCalculateDeferUntilActive_App()391     public void testCalculateDeferUntilActive_App() {
392         // Verify non-urgent behavior
393         assertFalse(calculateDeferUntilActive(APP_UID, null, null, false, false));
394         assertFalse(calculateDeferUntilActive(APP_UID, OPT_DEFAULT, null, false, false));
395         assertFalse(calculateDeferUntilActive(APP_UID, OPT_NONE, null, false, false));
396         assertTrue(calculateDeferUntilActive(APP_UID, OPT_UNTIL_ACTIVE, null, false, false));
397 
398         // Verify urgent behavior
399         assertFalse(calculateDeferUntilActive(APP_UID, null, null, false, true));
400         assertFalse(calculateDeferUntilActive(APP_UID, OPT_DEFAULT, null, false, true));
401         assertFalse(calculateDeferUntilActive(APP_UID, OPT_NONE, null, false, true));
402         assertTrue(calculateDeferUntilActive(APP_UID, OPT_UNTIL_ACTIVE, null, false, true));
403     }
404 
405     @Test
testCalculateDeferUntilActive_System()406     public void testCalculateDeferUntilActive_System() {
407         BroadcastRecord.CORE_DEFER_UNTIL_ACTIVE = true;
408 
409         // Verify non-urgent behavior
410         assertTrue(calculateDeferUntilActive(SYSTEM_UID, null, null, false, false));
411         assertTrue(calculateDeferUntilActive(SYSTEM_UID, OPT_DEFAULT, null, false, false));
412         assertFalse(calculateDeferUntilActive(SYSTEM_UID, OPT_NONE, null, false, false));
413         assertTrue(calculateDeferUntilActive(SYSTEM_UID, OPT_UNTIL_ACTIVE, null, false, false));
414 
415         // Verify urgent behavior
416         assertFalse(calculateDeferUntilActive(SYSTEM_UID, null, null, false, true));
417         assertFalse(calculateDeferUntilActive(SYSTEM_UID, OPT_DEFAULT, null, false, true));
418         assertFalse(calculateDeferUntilActive(SYSTEM_UID, OPT_NONE, null, false, true));
419         assertTrue(calculateDeferUntilActive(SYSTEM_UID, OPT_UNTIL_ACTIVE, null, false, true));
420     }
421 
422     @Test
testCalculateDeferUntilActive_Overrides()423     public void testCalculateDeferUntilActive_Overrides() {
424         final IIntentReceiver resultTo = new IIntentReceiver.Default();
425 
426         // Ordered broadcasts never deferred; requested option is ignored
427         assertFalse(calculateDeferUntilActive(APP_UID, OPT_UNTIL_ACTIVE, null, true, false));
428         assertFalse(calculateDeferUntilActive(APP_UID, OPT_UNTIL_ACTIVE, resultTo, true, false));
429 
430         // Unordered with result is always deferred; requested option is ignored
431         assertTrue(calculateDeferUntilActive(APP_UID, OPT_NONE, resultTo, false, false));
432     }
433 
434     @Test
testCleanupDisabledPackageReceivers()435     public void testCleanupDisabledPackageReceivers() {
436         final int user0 = UserHandle.USER_SYSTEM;
437         final int user1 = user0 + 1;
438         final String pkgToCleanup = "pkg.a";
439         final String pkgOther = "pkg.b";
440 
441         // Receivers contain multiple-user (contains [pkg.a@u0, pkg.a@u1, pkg.b@u0, pkg.b@u1]).
442         final List<ResolveInfo> receiversM = createReceiverInfos(
443                 new String[] { pkgToCleanup, pkgOther },
444                 new int[] { user0, user1 });
445         // Receivers only contain one user (contains [pkg.a@u0, pkg.b@u0]).
446         final List<ResolveInfo> receiversU0 = excludeReceivers(
447                 receiversM, null /* packageName */, user1);
448 
449         // With given package:
450         // Send to all users, cleanup a package of all users.
451         final BroadcastRecord recordAllAll = createBroadcastRecord(receiversM, UserHandle.USER_ALL,
452                 new Intent());
453         cleanupDisabledPackageReceivers(recordAllAll, pkgToCleanup, UserHandle.USER_ALL);
454         assertNull(verifyRemaining(recordAllAll, excludeReceivers(receiversM, pkgToCleanup, -1)));
455 
456         // Send to all users, cleanup a package of one user.
457         final BroadcastRecord recordAllOne = createBroadcastRecord(receiversM, UserHandle.USER_ALL,
458                 new Intent());
459         cleanupDisabledPackageReceivers(recordAllOne, pkgToCleanup, user0);
460         assertNull(verifyRemaining(recordAllOne,
461                 excludeReceivers(receiversM, pkgToCleanup, user0)));
462 
463         // Send to one user, cleanup a package of all users.
464         final BroadcastRecord recordOneAll = createBroadcastRecord(receiversU0, user0,
465                 new Intent());
466         cleanupDisabledPackageReceivers(recordOneAll, pkgToCleanup, UserHandle.USER_ALL);
467         assertNull(verifyRemaining(recordOneAll, excludeReceivers(receiversU0, pkgToCleanup, -1)));
468 
469         // Send to one user, cleanup a package one user.
470         final BroadcastRecord recordOneOne = createBroadcastRecord(receiversU0, user0,
471                 new Intent());
472         cleanupDisabledPackageReceivers(recordOneOne, pkgToCleanup, user0);
473         assertNull(verifyRemaining(recordOneOne, excludeReceivers(receiversU0, pkgToCleanup, -1)));
474 
475         // Without given package (e.g. stop user):
476         // Send to all users, cleanup one user.
477         final BroadcastRecord recordAllM = createBroadcastRecord(receiversM, UserHandle.USER_ALL,
478                 new Intent());
479         cleanupDisabledPackageReceivers(recordAllM, null /* packageName */, user1);
480         assertNull(verifyRemaining(recordAllM,
481                 excludeReceivers(receiversM, null /* packageName */, user1)));
482 
483         // Send to one user, cleanup one user.
484         final BroadcastRecord recordU0 = createBroadcastRecord(receiversU0, user0, new Intent());
485         cleanupDisabledPackageReceivers(recordU0, null /* packageName */, user0);
486         assertNull(verifyRemaining(recordU0, Collections.emptyList()));
487     }
488 
489     @Test
testMatchesDeliveryGroup()490     public void testMatchesDeliveryGroup() {
491         final List<ResolveInfo> receivers = List.of(createResolveInfo(PACKAGE1, getAppId(1)));
492 
493         final Intent intent1 = new Intent(Intent.ACTION_SERVICE_STATE);
494         intent1.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 0);
495         intent1.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, 1);
496         final BroadcastOptions options1 = BroadcastOptions.makeBasic();
497         final BroadcastRecord record1 = createBroadcastRecord(receivers, UserHandle.USER_ALL,
498                 intent1, options1);
499 
500         final Intent intent2 = new Intent(Intent.ACTION_SERVICE_STATE);
501         intent2.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 0);
502         intent2.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, 2);
503         final BroadcastOptions options2 = BroadcastOptions.makeBasic();
504         final BroadcastRecord record2 = createBroadcastRecord(receivers, UserHandle.USER_ALL,
505                 intent2, options2);
506 
507         assertTrue(record2.matchesDeliveryGroup(record1));
508     }
509 
510     @Test
testMatchesDeliveryGroup_withMatchingKey()511     public void testMatchesDeliveryGroup_withMatchingKey() {
512         final List<ResolveInfo> receivers = List.of(createResolveInfo(PACKAGE1, getAppId(1)));
513 
514         final Intent intent1 = new Intent(Intent.ACTION_SERVICE_STATE);
515         intent1.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 0);
516         intent1.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, 1);
517         final BroadcastOptions options1 = BroadcastOptions.makeBasic();
518         options1.setDeliveryGroupMatchingKey(Intent.ACTION_SERVICE_STATE, "key1");
519         final BroadcastRecord record1 = createBroadcastRecord(receivers, UserHandle.USER_ALL,
520                 intent1, options1);
521 
522         final Intent intent2 = new Intent(Intent.ACTION_SERVICE_STATE);
523         intent2.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 0);
524         intent2.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, 2);
525         final BroadcastOptions options2 = BroadcastOptions.makeBasic();
526         options2.setDeliveryGroupMatchingKey(Intent.ACTION_SERVICE_STATE, "key2");
527         final BroadcastRecord record2 = createBroadcastRecord(receivers, UserHandle.USER_ALL,
528                 intent2, options2);
529 
530         final Intent intent3 = new Intent(Intent.ACTION_SERVICE_STATE);
531         intent3.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 1);
532         intent3.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, 3);
533         final BroadcastOptions options3 = BroadcastOptions.makeBasic();
534         options3.setDeliveryGroupMatchingKey(Intent.ACTION_SERVICE_STATE, "key1");
535         final BroadcastRecord record3 = createBroadcastRecord(receivers, UserHandle.USER_ALL,
536                 intent3, options3);
537 
538         // record2 and record1 have different matching keys, so their delivery groups
539         // shouldn't match
540         assertFalse(record2.matchesDeliveryGroup(record1));
541         // record3 and record2 have different matching keys, so their delivery groups
542         // shouldn't match
543         assertFalse(record3.matchesDeliveryGroup(record2));
544         // record3 and record1 have same matching keys, so their delivery groups should match even
545         // if the intent has different extras.
546         assertTrue(record3.matchesDeliveryGroup(record1));
547     }
548 
549     @Test
testMatchesDeliveryGroup_withMatchingFilter()550     public void testMatchesDeliveryGroup_withMatchingFilter() {
551         final List<ResolveInfo> receivers = List.of(createResolveInfo(PACKAGE1, getAppId(1)));
552 
553         final Intent intent1 = new Intent(Intent.ACTION_SERVICE_STATE);
554         intent1.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 0);
555         intent1.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, 1);
556         intent1.putExtra(Intent.EXTRA_REASON, "reason1");
557         final IntentFilter filter1 = new IntentFilter(Intent.ACTION_SERVICE_STATE);
558         final PersistableBundle bundle1 = new PersistableBundle();
559         bundle1.putInt(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 0);
560         bundle1.putInt(SubscriptionManager.EXTRA_SLOT_INDEX, 1);
561         filter1.setExtras(bundle1);
562         final BroadcastOptions options1 = BroadcastOptions.makeBasic();
563         options1.setDeliveryGroupMatchingFilter(filter1);
564         final BroadcastRecord record1 = createBroadcastRecord(receivers, UserHandle.USER_ALL,
565                 intent1, options1);
566 
567         final Intent intent2 = new Intent(Intent.ACTION_SERVICE_STATE);
568         intent2.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 0);
569         intent2.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, 2);
570         intent2.putExtra(Intent.EXTRA_REASON, "reason2");
571         final IntentFilter filter2 = new IntentFilter(Intent.ACTION_SERVICE_STATE);
572         final PersistableBundle bundle2 = new PersistableBundle();
573         bundle2.putInt(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 0);
574         bundle2.putInt(SubscriptionManager.EXTRA_SLOT_INDEX, 2);
575         filter2.setExtras(bundle2);
576         final BroadcastOptions options2 = BroadcastOptions.makeBasic();
577         options2.setDeliveryGroupMatchingFilter(filter2);
578         final BroadcastRecord record2 = createBroadcastRecord(receivers, UserHandle.USER_ALL,
579                 intent2, options2);
580 
581         final Intent intent3 = new Intent(Intent.ACTION_SERVICE_STATE);
582         intent3.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 1);
583         intent3.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, 3);
584         intent3.putExtra(Intent.EXTRA_REASON, "reason3");
585         final IntentFilter filter3 = new IntentFilter(Intent.ACTION_SERVICE_STATE);
586         final PersistableBundle bundle3 = new PersistableBundle();
587         bundle3.putInt(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 0);
588         bundle3.putInt(SubscriptionManager.EXTRA_SLOT_INDEX, 1);
589         filter3.setExtras(bundle3);
590         final BroadcastOptions options3 = BroadcastOptions.makeBasic();
591         options3.setDeliveryGroupMatchingFilter(filter3);
592         final BroadcastRecord record3 = createBroadcastRecord(receivers, UserHandle.USER_ALL,
593                 intent3, options3);
594 
595         // record2's matchingFilter doesn't match record1's intent, so their delivery groups
596         // shouldn't match
597         assertFalse(record2.matchesDeliveryGroup(record1));
598         // record3's matchingFilter doesn't match record2's intent, so their delivery groups
599         // shouldn't match
600         assertFalse(record3.matchesDeliveryGroup(record2));
601         // record3's matchingFilter matches record1's intent, so their delivery groups should match.
602         assertTrue(record3.matchesDeliveryGroup(record1));
603     }
604 
cleanupDisabledPackageReceivers(BroadcastRecord record, String packageName, int userId)605     private static void cleanupDisabledPackageReceivers(BroadcastRecord record,
606             String packageName, int userId) {
607         record.cleanupDisabledPackageReceiversLocked(packageName, null /* filterByClasses */,
608                 userId, true /* doit */);
609     }
610 
verifyRemaining(BroadcastRecord record, List<ResolveInfo> expectedRemainingReceivers)611     private static String verifyRemaining(BroadcastRecord record,
612             List<ResolveInfo> expectedRemainingReceivers) {
613         final StringBuilder errorMsg = new StringBuilder();
614 
615         for (final Object receiver : record.receivers) {
616             final ResolveInfo resolveInfo = (ResolveInfo) receiver;
617             final ApplicationInfo appInfo = resolveInfo.activityInfo.applicationInfo;
618 
619             boolean foundExpected = false;
620             for (final ResolveInfo expectedReceiver : expectedRemainingReceivers) {
621                 final ApplicationInfo expectedAppInfo =
622                         expectedReceiver.activityInfo.applicationInfo;
623                 if (appInfo.packageName.equals(expectedAppInfo.packageName)
624                         && UserHandle.getUserId(appInfo.uid) == UserHandle
625                                 .getUserId(expectedAppInfo.uid)) {
626                     foundExpected = true;
627                     break;
628                 }
629             }
630             if (!foundExpected) {
631                 errorMsg.append(appInfo.packageName).append("@")
632                         .append('u').append(UserHandle.getUserId(appInfo.uid)).append(' ');
633             }
634         }
635 
636         return errorMsg.length() == 0 ? null
637                 : errorMsg.insert(0, "Contains unexpected receiver: ").toString();
638     }
639 
createResolveInfoWithPriority(int priority)640     private static ResolveInfo createResolveInfoWithPriority(int priority) {
641         return createResolveInfo(PACKAGE1, getAppId(1), priority);
642     }
643 
createResolveInfo(String packageName, int uid)644     private static ResolveInfo createResolveInfo(String packageName, int uid) {
645         return createResolveInfo(packageName, uid, 0);
646     }
647 
createResolveInfo(String packageName, int uid, int priority)648     private static ResolveInfo createResolveInfo(String packageName, int uid, int priority) {
649         final ResolveInfo resolveInfo = new ResolveInfo();
650         final ActivityInfo activityInfo = new ActivityInfo();
651         final ApplicationInfo appInfo = new ApplicationInfo();
652         appInfo.packageName = packageName;
653         appInfo.uid = uid;
654         activityInfo.applicationInfo = appInfo;
655         activityInfo.packageName = packageName;
656         activityInfo.name = packageName + ".MyReceiver";
657         resolveInfo.activityInfo = activityInfo;
658         resolveInfo.priority = priority;
659         return resolveInfo;
660     }
661 
662     /**
663      * Generate (packages.length * userIds.length) receivers.
664      */
createReceiverInfos(String[] packages, int[] userIds)665     private static List<ResolveInfo> createReceiverInfos(String[] packages, int[] userIds) {
666         final List<ResolveInfo> receivers = new ArrayList<>();
667         for (int i = 0; i < packages.length; i++) {
668             for (final int userId : userIds) {
669                 receivers.add(createResolveInfo(packages[i],
670                         UserHandle.getUid(userId, getAppId(i))));
671             }
672         }
673         return receivers;
674     }
675 
676     /**
677      * Create a new list which filters out item if package name or user id is matched.
678      * Null package name or user id < 0 will be considered as don't care.
679      */
excludeReceivers(List<ResolveInfo> receivers, String packageName, int userId)680     private static List<ResolveInfo> excludeReceivers(List<ResolveInfo> receivers,
681             String packageName, int userId) {
682         final List<ResolveInfo> excludedList = new ArrayList<>();
683         for (final ResolveInfo receiver : receivers) {
684             if ((packageName != null
685                     && !packageName.equals(receiver.activityInfo.applicationInfo.packageName))
686                     || (userId > -1 && userId != UserHandle
687                             .getUserId(receiver.activityInfo.applicationInfo.uid))) {
688                 excludedList.add(receiver);
689             }
690         }
691         return excludedList;
692     }
693 
createBroadcastRecord(Intent intent, List<ResolveInfo> receivers)694     private BroadcastRecord createBroadcastRecord(Intent intent,
695             List<ResolveInfo> receivers) {
696         return createBroadcastRecord(receivers, USER0, intent, null /* filterExtrasForReceiver */,
697                 null /* options */, false);
698     }
699 
createOrderedBroadcastRecord(Intent intent, List<ResolveInfo> receivers)700     private BroadcastRecord createOrderedBroadcastRecord(Intent intent,
701             List<ResolveInfo> receivers) {
702         return createBroadcastRecord(receivers, USER0, intent, null /* filterExtrasForReceiver */,
703                 null /* options */, true);
704     }
705 
createBroadcastRecord(List<ResolveInfo> receivers, int userId, Intent intent)706     private BroadcastRecord createBroadcastRecord(List<ResolveInfo> receivers, int userId,
707             Intent intent) {
708         return createBroadcastRecord(receivers, userId, intent, null /* filterExtrasForReceiver */,
709                 null /* options */, false);
710     }
711 
createBroadcastRecord(List<ResolveInfo> receivers, int userId, Intent intent, BroadcastOptions options)712     private BroadcastRecord createBroadcastRecord(List<ResolveInfo> receivers, int userId,
713             Intent intent, BroadcastOptions options) {
714         return createBroadcastRecord(receivers, userId, intent, null /* filterExtrasForReceiver */,
715                 options, false);
716     }
717 
createBroadcastRecord(List<ResolveInfo> receivers, int userId, Intent intent, BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver, BroadcastOptions options)718     private BroadcastRecord createBroadcastRecord(List<ResolveInfo> receivers, int userId,
719             Intent intent, BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver,
720             BroadcastOptions options) {
721         return createBroadcastRecord(receivers, userId, intent, filterExtrasForReceiver,
722                 options, false);
723     }
724 
createBroadcastRecord(List<ResolveInfo> receivers, int userId, Intent intent, BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver, BroadcastOptions options, boolean ordered)725     private BroadcastRecord createBroadcastRecord(List<ResolveInfo> receivers, int userId,
726             Intent intent, BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver,
727             BroadcastOptions options, boolean ordered) {
728         return new BroadcastRecord(
729                 mQueue /* queue */,
730                 intent,
731                 mProcess /* callerApp */,
732                 PACKAGE1 /* callerPackage */,
733                 null /* callerFeatureId */,
734                 0 /* callingPid */,
735                 0 /* callingUid */,
736                 false /* callerInstantApp */,
737                 null /* resolvedType */,
738                 null /* requiredPermissions */,
739                 null /* excludedPermissions */,
740                 null /* excludedPackages */,
741                 0 /* appOp */,
742                 options,
743                 new ArrayList<>(receivers), // Make a copy to not affect the original list.
744                 null /* resultToApp */,
745                 null /* resultTo */,
746                 0 /* resultCode */,
747                 null /* resultData */,
748                 null /* resultExtras */,
749                 ordered /* serialized */,
750                 false /* sticky */,
751                 false /* initialSticky */,
752                 userId,
753                 BackgroundStartPrivileges.NONE,
754                 false /* timeoutExempt */,
755                 filterExtrasForReceiver,
756                 PROCESS_STATE_UNKNOWN);
757     }
758 
getAppId(int i)759     private static int getAppId(int i) {
760         return Process.FIRST_APPLICATION_UID + i;
761     }
762 
isPrioritized(List<Object> receivers)763     private static boolean isPrioritized(List<Object> receivers) {
764         return BroadcastRecord.isPrioritized(
765                 calculateBlockedUntilBeyondCount(receivers, false), false);
766     }
767 
assertBlocked(BroadcastRecord r, boolean... blocked)768     private static void assertBlocked(BroadcastRecord r, boolean... blocked) {
769         assertEquals(r.receivers.size(), blocked.length);
770         for (int i = 0; i < blocked.length; i++) {
771             assertEquals("blocked " + i, blocked[i], r.isBlocked(i));
772         }
773     }
774 
assertTerminalDeferredBeyond(BroadcastRecord r, int expectedTerminalCount, int expectedDeferredCount, int expectedBeyondCount)775     private static void assertTerminalDeferredBeyond(BroadcastRecord r,
776             int expectedTerminalCount, int expectedDeferredCount, int expectedBeyondCount) {
777         assertEquals("terminal", expectedTerminalCount, r.terminalCount);
778         assertEquals("deferred", expectedDeferredCount, r.deferredCount);
779         assertEquals("beyond", expectedBeyondCount, r.beyondCount);
780     }
781 }
782