| /* |
| * Copyright (C) 2019 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License |
| */ |
| |
| package com.android.systemui.broadcast |
| |
| import android.content.BroadcastReceiver |
| import android.content.Context |
| import android.content.IntentFilter |
| import android.os.Handler |
| import android.os.UserHandle |
| import android.test.suitebuilder.annotation.SmallTest |
| import android.testing.AndroidTestingRunner |
| import android.testing.TestableLooper |
| import com.android.systemui.SysuiTestCase |
| import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger |
| import com.android.systemui.util.concurrency.FakeExecutor |
| import com.android.systemui.util.time.FakeSystemClock |
| import junit.framework.Assert.assertFalse |
| import junit.framework.Assert.assertNotNull |
| import junit.framework.Assert.assertNotSame |
| import org.junit.Before |
| import org.junit.Test |
| import org.junit.runner.RunWith |
| import org.mockito.ArgumentCaptor |
| import org.mockito.Mock |
| import org.mockito.Mockito |
| import org.mockito.Mockito.mock |
| import org.mockito.Mockito.nullable |
| import org.mockito.Mockito.verify |
| import org.mockito.MockitoAnnotations |
| import java.util.concurrent.Executor |
| |
| @RunWith(AndroidTestingRunner::class) |
| @TestableLooper.RunWithLooper |
| @SmallTest |
| class UserBroadcastDispatcherTest : SysuiTestCase() { |
| |
| companion object { |
| private const val ACTION_1 = "com.android.systemui.tests.ACTION_1" |
| private const val ACTION_2 = "com.android.systemui.tests.ACTION_2" |
| private const val USER_ID = 0 |
| private const val FLAG = 3 |
| private val USER_HANDLE = UserHandle.of(USER_ID) |
| |
| fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture() |
| fun <T> any(): T = Mockito.any() |
| fun <T> eq(v: T) = Mockito.eq(v) ?: v |
| } |
| |
| @Mock |
| private lateinit var broadcastReceiver: BroadcastReceiver |
| @Mock |
| private lateinit var broadcastReceiverOther: BroadcastReceiver |
| @Mock |
| private lateinit var mockContext: Context |
| @Mock |
| private lateinit var logger: BroadcastDispatcherLogger |
| @Mock |
| private lateinit var removalPendingStore: PendingRemovalStore |
| |
| private lateinit var testableLooper: TestableLooper |
| private lateinit var userBroadcastDispatcher: UserBroadcastDispatcher |
| private lateinit var intentFilter: IntentFilter |
| private lateinit var intentFilterOther: IntentFilter |
| private lateinit var handler: Handler |
| private lateinit var fakeExecutor: FakeExecutor |
| |
| @Before |
| fun setUp() { |
| MockitoAnnotations.initMocks(this) |
| testableLooper = TestableLooper.get(this) |
| handler = Handler(testableLooper.looper) |
| fakeExecutor = FakeExecutor(FakeSystemClock()) |
| |
| userBroadcastDispatcher = object : UserBroadcastDispatcher( |
| mockContext, |
| USER_ID, |
| testableLooper.looper, |
| mock(Executor::class.java), |
| logger, |
| removalPendingStore |
| ) { |
| override fun createActionReceiver( |
| action: String, |
| permission: String?, |
| flags: Int |
| ): ActionReceiver { |
| return mock(ActionReceiver::class.java) |
| } |
| } |
| } |
| |
| @Test |
| fun testSingleReceiverRegistered() { |
| intentFilter = IntentFilter(ACTION_1) |
| val receiverData = ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE) |
| |
| userBroadcastDispatcher.registerReceiver(receiverData, FLAG) |
| testableLooper.processAllMessages() |
| |
| val actionReceiver = userBroadcastDispatcher.getActionReceiver(ACTION_1, FLAG) |
| assertNotNull(actionReceiver) |
| verify(actionReceiver)?.addReceiverData(receiverData) |
| } |
| |
| @Test |
| fun testDifferentActionReceiversForDifferentFlags() { |
| intentFilter = IntentFilter(ACTION_1) |
| val receiverData = ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE) |
| |
| val flag1 = 0 |
| val flag2 = 1 |
| |
| userBroadcastDispatcher.registerReceiver(receiverData, flag1) |
| userBroadcastDispatcher.registerReceiver(receiverData, flag2) |
| testableLooper.processAllMessages() |
| |
| assertNotSame( |
| userBroadcastDispatcher.getActionReceiver(ACTION_1, flag1), |
| userBroadcastDispatcher.getActionReceiver(ACTION_1, flag2) |
| ) |
| } |
| |
| @Test |
| fun testDifferentActionReceiversForDifferentPermissions() { |
| intentFilter = IntentFilter(ACTION_1) |
| val receiverData1 = |
| ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE, "PERMISSION1") |
| val receiverData2 = |
| ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE, "PERMISSION2") |
| |
| userBroadcastDispatcher.registerReceiver(receiverData1, 0) |
| userBroadcastDispatcher.registerReceiver(receiverData2, 0) |
| testableLooper.processAllMessages() |
| |
| assertNotSame( |
| userBroadcastDispatcher.getActionReceiver(ACTION_1, 0, "PERMISSION1"), |
| userBroadcastDispatcher.getActionReceiver(ACTION_1, 0, "PERMISSION2") |
| ) |
| } |
| |
| @Test |
| fun testSingleReceiverRegistered_logging() { |
| intentFilter = IntentFilter(ACTION_1) |
| |
| userBroadcastDispatcher.registerReceiver( |
| ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE), FLAG) |
| testableLooper.processAllMessages() |
| |
| verify(logger).logReceiverRegistered(USER_HANDLE.identifier, broadcastReceiver, FLAG) |
| } |
| |
| @Test |
| fun testSingleReceiverUnregistered() { |
| intentFilter = IntentFilter(ACTION_1) |
| |
| userBroadcastDispatcher.registerReceiver( |
| ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE), FLAG) |
| testableLooper.processAllMessages() |
| |
| userBroadcastDispatcher.unregisterReceiver(broadcastReceiver) |
| testableLooper.processAllMessages() |
| |
| val actionReceiver = userBroadcastDispatcher.getActionReceiver(ACTION_1, FLAG) |
| assertNotNull(actionReceiver) |
| verify(actionReceiver)?.removeReceiver(broadcastReceiver) |
| } |
| |
| @Test |
| fun testSingleReceiverUnregistered_logger() { |
| intentFilter = IntentFilter(ACTION_1) |
| |
| userBroadcastDispatcher.registerReceiver( |
| ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE), FLAG) |
| testableLooper.processAllMessages() |
| |
| userBroadcastDispatcher.unregisterReceiver(broadcastReceiver) |
| testableLooper.processAllMessages() |
| |
| verify(logger).logReceiverUnregistered(USER_HANDLE.identifier, broadcastReceiver) |
| } |
| |
| @Test |
| fun testRemoveReceiverReferences() { |
| intentFilter = IntentFilter(ACTION_1) |
| userBroadcastDispatcher.registerReceiver( |
| ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE), FLAG) |
| |
| intentFilterOther = IntentFilter(ACTION_1) |
| intentFilterOther.addAction(ACTION_2) |
| userBroadcastDispatcher.registerReceiver( |
| ReceiverData( |
| broadcastReceiverOther, |
| intentFilterOther, |
| fakeExecutor, |
| USER_HANDLE |
| ), FLAG |
| ) |
| |
| userBroadcastDispatcher.unregisterReceiver(broadcastReceiver) |
| testableLooper.processAllMessages() |
| fakeExecutor.runAllReady() |
| |
| assertFalse(userBroadcastDispatcher.isReceiverReferenceHeld(broadcastReceiver)) |
| } |
| |
| @Test |
| fun testCreateActionReceiver_registerWithFlag() { |
| val uBR = UserBroadcastDispatcher( |
| mockContext, |
| USER_ID, |
| testableLooper.looper, |
| fakeExecutor, |
| logger, |
| removalPendingStore |
| ) |
| uBR.registerReceiver( |
| ReceiverData( |
| broadcastReceiver, |
| IntentFilter(ACTION_1), |
| fakeExecutor, |
| USER_HANDLE |
| ), |
| FLAG |
| ) |
| |
| testableLooper.processAllMessages() |
| fakeExecutor.runAllReady() |
| |
| verify(mockContext).registerReceiverAsUser( |
| any(), any(), any(), nullable(String::class.java), any(), eq(FLAG)) |
| } |
| |
| @Test |
| fun testCreateActionReceiver_registerWithPermission() { |
| val permission = "CUSTOM_PERMISSION" |
| val uBR = UserBroadcastDispatcher( |
| mockContext, |
| USER_ID, |
| testableLooper.looper, |
| fakeExecutor, |
| logger, |
| removalPendingStore |
| ) |
| uBR.registerReceiver( |
| ReceiverData( |
| broadcastReceiver, |
| IntentFilter(ACTION_1), |
| fakeExecutor, |
| USER_HANDLE, |
| permission |
| ), |
| FLAG |
| ) |
| |
| testableLooper.processAllMessages() |
| fakeExecutor.runAllReady() |
| |
| verify(mockContext).registerReceiverAsUser( |
| any(), any(), any(), eq(permission), any(), eq(FLAG)) |
| } |
| |
| private fun UserBroadcastDispatcher.getActionReceiver( |
| action: String, |
| flags: Int, |
| permission: String? = null |
| ): ActionReceiver? { |
| return actionsToActionsReceivers.get( |
| UserBroadcastDispatcher.ReceiverProperties( |
| action, |
| flags, |
| permission |
| ) |
| ) |
| } |
| } |