1 /* <lambda>null2 * Copyright (C) 2019 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.systemui.broadcast 18 19 import android.content.BroadcastReceiver 20 import android.content.Context 21 import android.content.Intent 22 import android.content.IntentFilter 23 import android.os.Handler 24 import android.os.Looper 25 import android.os.PatternMatcher 26 import android.os.UserHandle 27 import android.testing.AndroidTestingRunner 28 import android.testing.TestableLooper 29 import androidx.test.filters.SmallTest 30 import com.android.systemui.SysuiTestCase 31 import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger 32 import com.android.systemui.dump.DumpManager 33 import com.android.systemui.settings.UserTracker 34 import com.android.systemui.util.concurrency.FakeExecutor 35 import com.android.systemui.util.mockito.eq 36 import com.android.systemui.util.mockito.mock 37 import com.android.systemui.util.time.FakeSystemClock 38 import com.google.common.truth.Truth.assertThat 39 import java.util.concurrent.Executor 40 import junit.framework.Assert.assertSame 41 import kotlinx.coroutines.flow.collect 42 import kotlinx.coroutines.launch 43 import kotlinx.coroutines.test.UnconfinedTestDispatcher 44 import kotlinx.coroutines.test.advanceUntilIdle 45 import kotlinx.coroutines.test.runTest 46 import org.junit.Before 47 import org.junit.Test 48 import org.junit.runner.RunWith 49 import org.mockito.ArgumentCaptor 50 import org.mockito.Captor 51 import org.mockito.Mock 52 import org.mockito.Mockito.anyInt 53 import org.mockito.Mockito.inOrder 54 import org.mockito.Mockito.mock 55 import org.mockito.Mockito.never 56 import org.mockito.Mockito.verify 57 import org.mockito.Mockito.`when` 58 import org.mockito.MockitoAnnotations 59 60 @RunWith(AndroidTestingRunner::class) 61 @TestableLooper.RunWithLooper 62 @SmallTest 63 class BroadcastDispatcherTest : SysuiTestCase() { 64 65 companion object { 66 val user0 = UserHandle.of(0) 67 val user1 = UserHandle.of(1) 68 const val DEFAULT_FLAG = Context.RECEIVER_EXPORTED 69 val DEFAULT_PERMISSION: String? = null 70 71 fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture() 72 73 const val TEST_ACTION = "TEST_ACTION" 74 const val TEST_SCHEME = "TEST_SCHEME" 75 const val TEST_PATH = "TEST_PATH" 76 const val TEST_TYPE = "test/type" 77 } 78 79 @Mock private lateinit var mockContext: Context 80 @Mock private lateinit var mockUBRUser0: UserBroadcastDispatcher 81 @Mock private lateinit var mockUBRUser1: UserBroadcastDispatcher 82 @Mock private lateinit var broadcastReceiver: BroadcastReceiver 83 @Mock private lateinit var broadcastReceiverOther: BroadcastReceiver 84 @Mock private lateinit var intentFilter: IntentFilter 85 @Mock private lateinit var intentFilterOther: IntentFilter 86 @Mock private lateinit var mockHandler: Handler 87 @Mock private lateinit var logger: BroadcastDispatcherLogger 88 @Mock private lateinit var userTracker: UserTracker 89 @Mock private lateinit var removalPendingStore: PendingRemovalStore 90 91 private lateinit var mainExecutor: Executor 92 93 @Captor private lateinit var argumentCaptor: ArgumentCaptor<ReceiverData> 94 95 private lateinit var testableLooper: TestableLooper 96 private lateinit var broadcastDispatcher: BroadcastDispatcher 97 98 @Before 99 fun setUp() { 100 MockitoAnnotations.initMocks(this) 101 testableLooper = TestableLooper.get(this) 102 mainExecutor = FakeExecutor(FakeSystemClock()) 103 `when`(mockContext.mainExecutor).thenReturn(mainExecutor) 104 105 broadcastDispatcher = 106 TestBroadcastDispatcher( 107 mockContext, 108 mainExecutor, 109 testableLooper.looper, 110 mock(Executor::class.java), 111 mock(DumpManager::class.java), 112 logger, 113 userTracker, 114 removalPendingStore, 115 mapOf(0 to mockUBRUser0, 1 to mockUBRUser1), 116 ) 117 118 // These should be valid filters 119 `when`(intentFilter.countActions()).thenReturn(1) 120 `when`(intentFilterOther.countActions()).thenReturn(1) 121 setUserMock(mockContext, user0) 122 } 123 124 @Test 125 fun testAddingReceiverToCorrectUBR() { 126 broadcastDispatcher.registerReceiverWithHandler( 127 broadcastReceiver, 128 intentFilter, 129 mockHandler, 130 user0, 131 ) 132 broadcastDispatcher.registerReceiverWithHandler( 133 broadcastReceiverOther, 134 intentFilterOther, 135 mockHandler, 136 user1, 137 ) 138 139 testableLooper.processAllMessages() 140 141 verify(mockUBRUser0).registerReceiver(capture(argumentCaptor), eq(DEFAULT_FLAG)) 142 143 assertSame(broadcastReceiver, argumentCaptor.value.receiver) 144 assertSame(intentFilter, argumentCaptor.value.filter) 145 146 verify(mockUBRUser1).registerReceiver(capture(argumentCaptor), eq(DEFAULT_FLAG)) 147 assertSame(broadcastReceiverOther, argumentCaptor.value.receiver) 148 assertSame(intentFilterOther, argumentCaptor.value.filter) 149 } 150 151 @Test 152 fun testAddingReceiverToCorrectUBR_executor() { 153 broadcastDispatcher.registerReceiver(broadcastReceiver, intentFilter, mainExecutor, user0) 154 broadcastDispatcher.registerReceiver( 155 broadcastReceiverOther, 156 intentFilterOther, 157 mainExecutor, 158 user1, 159 ) 160 161 testableLooper.processAllMessages() 162 163 verify(mockUBRUser0).registerReceiver(capture(argumentCaptor), eq(DEFAULT_FLAG)) 164 165 assertSame(broadcastReceiver, argumentCaptor.value.receiver) 166 assertSame(intentFilter, argumentCaptor.value.filter) 167 168 verify(mockUBRUser1).registerReceiver(capture(argumentCaptor), eq(DEFAULT_FLAG)) 169 assertSame(broadcastReceiverOther, argumentCaptor.value.receiver) 170 assertSame(intentFilterOther, argumentCaptor.value.filter) 171 } 172 173 @Test 174 fun testAddReceiverDefaultFlag_handler() { 175 broadcastDispatcher.registerReceiverWithHandler( 176 broadcastReceiver, 177 intentFilter, 178 mockHandler, 179 ) 180 testableLooper.processAllMessages() 181 182 verify(mockUBRUser0).registerReceiver(capture(argumentCaptor), eq(DEFAULT_FLAG)) 183 184 assertSame(broadcastReceiver, argumentCaptor.value.receiver) 185 assertSame(intentFilter, argumentCaptor.value.filter) 186 } 187 188 @Test 189 fun testAddReceiverCorrectFlag_handler() { 190 val flag = 3 191 192 broadcastDispatcher.registerReceiverWithHandler( 193 broadcastReceiver, 194 intentFilter, 195 mockHandler, 196 flags = flag, 197 ) 198 testableLooper.processAllMessages() 199 200 verify(mockUBRUser0).registerReceiver(capture(argumentCaptor), eq(flag)) 201 202 assertSame(broadcastReceiver, argumentCaptor.value.receiver) 203 assertSame(intentFilter, argumentCaptor.value.filter) 204 } 205 206 @Test 207 fun testAddReceiverDefaultFlag_executor() { 208 broadcastDispatcher.registerReceiver(broadcastReceiver, intentFilter) 209 testableLooper.processAllMessages() 210 211 verify(mockUBRUser0).registerReceiver(capture(argumentCaptor), eq(DEFAULT_FLAG)) 212 213 assertSame(broadcastReceiver, argumentCaptor.value.receiver) 214 assertSame(intentFilter, argumentCaptor.value.filter) 215 } 216 217 @Test 218 fun testAddReceiverCorrectPermission_executor() { 219 val flag = 3 220 val permission = "CUSTOM_PERMISSION" 221 222 broadcastDispatcher.registerReceiver( 223 broadcastReceiver, 224 intentFilter, 225 flags = flag, 226 permission = permission, 227 ) 228 testableLooper.processAllMessages() 229 230 verify(mockUBRUser0).registerReceiver(capture(argumentCaptor), eq(flag)) 231 232 assertSame(broadcastReceiver, argumentCaptor.value.receiver) 233 assertSame(intentFilter, argumentCaptor.value.filter) 234 assertSame(permission, argumentCaptor.value.permission) 235 } 236 237 @Test 238 fun testAddReceiverDefaultPermission_executor() { 239 broadcastDispatcher.registerReceiver(broadcastReceiver, intentFilter) 240 testableLooper.processAllMessages() 241 242 verify(mockUBRUser0).registerReceiver(capture(argumentCaptor), eq(DEFAULT_FLAG)) 243 244 assertSame(broadcastReceiver, argumentCaptor.value.receiver) 245 assertSame(intentFilter, argumentCaptor.value.filter) 246 assertSame(DEFAULT_PERMISSION, argumentCaptor.value.permission) 247 } 248 249 @Test 250 fun testAddReceiverCorrectFlag_executor() { 251 val flag = 3 252 253 broadcastDispatcher.registerReceiver(broadcastReceiver, intentFilter, flags = flag) 254 testableLooper.processAllMessages() 255 256 verify(mockUBRUser0).registerReceiver(capture(argumentCaptor), eq(flag)) 257 258 assertSame(broadcastReceiver, argumentCaptor.value.receiver) 259 assertSame(intentFilter, argumentCaptor.value.filter) 260 } 261 262 @Test 263 fun testRemovingReceiversRemovesFromAllUBR() { 264 broadcastDispatcher.registerReceiverWithHandler( 265 broadcastReceiver, 266 intentFilter, 267 mockHandler, 268 user0, 269 ) 270 broadcastDispatcher.registerReceiverWithHandler( 271 broadcastReceiver, 272 intentFilter, 273 mockHandler, 274 user1, 275 ) 276 277 broadcastDispatcher.unregisterReceiver(broadcastReceiver) 278 279 testableLooper.processAllMessages() 280 281 verify(mockUBRUser0).unregisterReceiver(broadcastReceiver) 282 verify(mockUBRUser1).unregisterReceiver(broadcastReceiver) 283 } 284 285 @Test 286 fun testRemoveReceiverFromUser() { 287 broadcastDispatcher.registerReceiverWithHandler( 288 broadcastReceiver, 289 intentFilter, 290 mockHandler, 291 user0, 292 ) 293 broadcastDispatcher.registerReceiverWithHandler( 294 broadcastReceiver, 295 intentFilter, 296 mockHandler, 297 user1, 298 ) 299 300 broadcastDispatcher.unregisterReceiverForUser(broadcastReceiver, user0) 301 302 testableLooper.processAllMessages() 303 304 verify(mockUBRUser0).unregisterReceiver(broadcastReceiver) 305 verify(mockUBRUser1, never()).unregisterReceiver(broadcastReceiver) 306 } 307 308 @Test 309 fun testRegisterCurrentAsActualUser() { 310 `when`(userTracker.userId).thenReturn(user1.identifier) 311 312 broadcastDispatcher.registerReceiverWithHandler( 313 broadcastReceiver, 314 intentFilter, 315 mockHandler, 316 UserHandle.CURRENT, 317 ) 318 319 testableLooper.processAllMessages() 320 321 verify(mockUBRUser1) 322 .registerReceiver(capture(argumentCaptor), eq(Context.RECEIVER_EXPORTED)) 323 assertSame(broadcastReceiver, argumentCaptor.value.receiver) 324 } 325 326 @Test(expected = IllegalArgumentException::class) 327 fun testFilterMustContainActions() { 328 val testFilter = IntentFilter() 329 broadcastDispatcher.registerReceiver(broadcastReceiver, testFilter) 330 } 331 332 @Test(expected = IllegalArgumentException::class) 333 fun testFilterMustNotContainDataScheme() { 334 val testFilter = IntentFilter(TEST_ACTION).apply { addDataScheme(TEST_SCHEME) } 335 broadcastDispatcher.registerReceiver(broadcastReceiver, testFilter) 336 } 337 338 @Test(expected = IllegalArgumentException::class) 339 fun testFilterMustNotContainDataAuthority() { 340 val testFilter = 341 IntentFilter(TEST_ACTION).apply { 342 addDataAuthority(mock(IntentFilter.AuthorityEntry::class.java)) 343 } 344 broadcastDispatcher.registerReceiver(broadcastReceiver, testFilter) 345 } 346 347 @Test(expected = IllegalArgumentException::class) 348 fun testFilterMustNotContainDataPath() { 349 val testFilter = 350 IntentFilter(TEST_ACTION).apply { 351 addDataPath(TEST_PATH, PatternMatcher.PATTERN_LITERAL) 352 } 353 broadcastDispatcher.registerReceiver(broadcastReceiver, testFilter) 354 } 355 356 @Test(expected = IllegalArgumentException::class) 357 fun testFilterMustNotContainDataType() { 358 val testFilter = IntentFilter(TEST_ACTION).apply { addDataType(TEST_TYPE) } 359 broadcastDispatcher.registerReceiver(broadcastReceiver, testFilter) 360 } 361 362 @Test(expected = IllegalArgumentException::class) 363 fun testFilterMustNotSetPriority() { 364 val testFilter = 365 IntentFilter(TEST_ACTION).apply { priority = IntentFilter.SYSTEM_HIGH_PRIORITY } 366 broadcastDispatcher.registerReceiver(broadcastReceiver, testFilter) 367 } 368 369 @Test 370 fun testTaggedReceiverForRemovalImmediately_allUsers() { 371 broadcastDispatcher.unregisterReceiver(broadcastReceiver) 372 373 verify(removalPendingStore).tagForRemoval(broadcastReceiver, UserHandle.USER_ALL) 374 verify(removalPendingStore, never()).clearPendingRemoval(eq(broadcastReceiver), anyInt()) 375 } 376 377 @Test 378 fun testTaggedReceiverForRemovalImmediately_singleUser() { 379 val user = 0 380 broadcastDispatcher.unregisterReceiverForUser(broadcastReceiver, UserHandle.of(user)) 381 382 verify(removalPendingStore).tagForRemoval(broadcastReceiver, user) 383 verify(removalPendingStore, never()).clearPendingRemoval(eq(broadcastReceiver), anyInt()) 384 } 385 386 @Test 387 fun testUnregisterReceiverClearsPendingRemovalAfterRemoving_allUsers() { 388 broadcastDispatcher.registerReceiver(broadcastReceiver, intentFilter, null, user0) 389 broadcastDispatcher.registerReceiver(broadcastReceiver, intentFilter, null, user1) 390 391 broadcastDispatcher.unregisterReceiver(broadcastReceiver) 392 393 testableLooper.processAllMessages() 394 395 val inOrderUser0 = inOrder(mockUBRUser0, removalPendingStore) 396 inOrderUser0.verify(mockUBRUser0).unregisterReceiver(broadcastReceiver) 397 inOrderUser0 398 .verify(removalPendingStore) 399 .clearPendingRemoval(broadcastReceiver, UserHandle.USER_ALL) 400 401 val inOrderUser1 = inOrder(mockUBRUser1, removalPendingStore) 402 inOrderUser1.verify(mockUBRUser1).unregisterReceiver(broadcastReceiver) 403 inOrderUser1 404 .verify(removalPendingStore) 405 .clearPendingRemoval(broadcastReceiver, UserHandle.USER_ALL) 406 } 407 408 @Test 409 fun testUnregisterReceiverclearPendingRemovalAfterRemoving_singleUser() { 410 broadcastDispatcher.registerReceiver(broadcastReceiver, intentFilter, null, user1) 411 412 broadcastDispatcher.unregisterReceiverForUser(broadcastReceiver, user1) 413 414 testableLooper.processAllMessages() 415 416 val inOrderUser1 = inOrder(mockUBRUser1, removalPendingStore) 417 inOrderUser1.verify(mockUBRUser1).unregisterReceiver(broadcastReceiver) 418 inOrderUser1 419 .verify(removalPendingStore) 420 .clearPendingRemoval(broadcastReceiver, user1.identifier) 421 } 422 423 @Test 424 fun testBroadcastFlow() = runTest(UnconfinedTestDispatcher()) { 425 val flow = 426 broadcastDispatcher.broadcastFlow(intentFilter, user1) { intent, receiver -> 427 intent to receiver 428 } 429 430 // Collect the values into collectedValues. 431 val collectedValues = mutableListOf<Pair<Intent, BroadcastReceiver>>() 432 val job = launch { flow.collect { collectedValues.add(it) } } 433 434 testableLooper.processAllMessages() 435 verify(mockUBRUser1).registerReceiver(capture(argumentCaptor), eq(DEFAULT_FLAG)) 436 val receiver = argumentCaptor.value.receiver 437 438 // Simulate fake broadcasted intents. 439 val fakeIntents = listOf<Intent>(mock(), mock(), mock()) 440 fakeIntents.forEach { receiver.onReceive(mockContext, it) } 441 442 // The intents should have been collected. 443 advanceUntilIdle() 444 445 val expectedValues = fakeIntents.map { it to receiver } 446 assertThat(collectedValues).containsExactlyElementsIn(expectedValues) 447 448 // Stop the collection. 449 job.cancel() 450 451 testableLooper.processAllMessages() 452 verify(mockUBRUser1).unregisterReceiver(receiver) 453 } 454 455 private fun setUserMock(mockContext: Context, user: UserHandle) { 456 `when`(mockContext.user).thenReturn(user) 457 `when`(mockContext.userId).thenReturn(user.identifier) 458 } 459 460 private class TestBroadcastDispatcher( 461 context: Context, 462 mainExecutor: Executor, 463 backgroundRunningLooper: Looper, 464 backgroundRunningExecutor: Executor, 465 dumpManager: DumpManager, 466 logger: BroadcastDispatcherLogger, 467 userTracker: UserTracker, 468 removalPendingStore: PendingRemovalStore, 469 var mockUBRMap: Map<Int, UserBroadcastDispatcher>, 470 ) : 471 BroadcastDispatcher( 472 context, 473 mainExecutor, 474 backgroundRunningLooper, 475 backgroundRunningExecutor, 476 dumpManager, 477 logger, 478 userTracker, 479 removalPendingStore, 480 ) { 481 override fun createUBRForUser(userId: Int): UserBroadcastDispatcher { 482 return mockUBRMap.getOrDefault(userId, mock(UserBroadcastDispatcher::class.java)) 483 } 484 } 485 } 486