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