blob: 3357c5863d462b6bcd0330f58e0aaa7847fbfc54 [file] [log] [blame]
/*
* 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.Looper
import android.os.PatternMatcher
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.dump.DumpManager
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.time.FakeSystemClock
import junit.framework.Assert.assertSame
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.mockito.Mockito.mock
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
import java.util.concurrent.Executor
@RunWith(AndroidTestingRunner::class)
@TestableLooper.RunWithLooper
@SmallTest
class BroadcastDispatcherTest : SysuiTestCase() {
companion object {
val user0 = UserHandle.of(0)
val user1 = UserHandle.of(1)
fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture()
const val TEST_ACTION = "TEST_ACTION"
const val TEST_SCHEME = "TEST_SCHEME"
const val TEST_PATH = "TEST_PATH"
const val TEST_TYPE = "test/type"
}
@Mock
private lateinit var mockContext: Context
@Mock
private lateinit var mockUBRUser0: UserBroadcastDispatcher
@Mock
private lateinit var mockUBRUser1: UserBroadcastDispatcher
@Mock
private lateinit var broadcastReceiver: BroadcastReceiver
@Mock
private lateinit var broadcastReceiverOther: BroadcastReceiver
@Mock
private lateinit var intentFilter: IntentFilter
@Mock
private lateinit var intentFilterOther: IntentFilter
@Mock
private lateinit var mockHandler: Handler
private lateinit var executor: Executor
@Captor
private lateinit var argumentCaptor: ArgumentCaptor<ReceiverData>
private lateinit var testableLooper: TestableLooper
private lateinit var broadcastDispatcher: BroadcastDispatcher
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
testableLooper = TestableLooper.get(this)
executor = FakeExecutor(FakeSystemClock())
broadcastDispatcher = TestBroadcastDispatcher(
mockContext,
Handler(testableLooper.looper),
testableLooper.looper,
mock(DumpManager::class.java),
mapOf(0 to mockUBRUser0, 1 to mockUBRUser1))
// These should be valid filters
`when`(intentFilter.countActions()).thenReturn(1)
`when`(intentFilterOther.countActions()).thenReturn(1)
setUserMock(mockContext, user0)
}
@Test
fun testAddingReceiverToCorrectUBR() {
broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
mockHandler, user0)
broadcastDispatcher.registerReceiverWithHandler(
broadcastReceiverOther, intentFilterOther, mockHandler, user1)
testableLooper.processAllMessages()
verify(mockUBRUser0).registerReceiver(capture(argumentCaptor))
assertSame(broadcastReceiver, argumentCaptor.value.receiver)
assertSame(intentFilter, argumentCaptor.value.filter)
verify(mockUBRUser1).registerReceiver(capture(argumentCaptor))
assertSame(broadcastReceiverOther, argumentCaptor.value.receiver)
assertSame(intentFilterOther, argumentCaptor.value.filter)
}
@Test
fun testAddingReceiverToCorrectUBR_executor() {
broadcastDispatcher.registerReceiver(broadcastReceiver, intentFilter, executor, user0)
broadcastDispatcher.registerReceiver(
broadcastReceiverOther, intentFilterOther, executor, user1)
testableLooper.processAllMessages()
verify(mockUBRUser0).registerReceiver(capture(argumentCaptor))
assertSame(broadcastReceiver, argumentCaptor.value.receiver)
assertSame(intentFilter, argumentCaptor.value.filter)
verify(mockUBRUser1).registerReceiver(capture(argumentCaptor))
assertSame(broadcastReceiverOther, argumentCaptor.value.receiver)
assertSame(intentFilterOther, argumentCaptor.value.filter)
}
@Test
fun testRemovingReceiversRemovesFromAllUBR() {
broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
mockHandler, user0)
broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
mockHandler, user1)
broadcastDispatcher.unregisterReceiver(broadcastReceiver)
testableLooper.processAllMessages()
verify(mockUBRUser0).unregisterReceiver(broadcastReceiver)
verify(mockUBRUser1).unregisterReceiver(broadcastReceiver)
}
@Test
fun testRemoveReceiverFromUser() {
broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
mockHandler, user0)
broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
mockHandler, user1)
broadcastDispatcher.unregisterReceiverForUser(broadcastReceiver, user0)
testableLooper.processAllMessages()
verify(mockUBRUser0).unregisterReceiver(broadcastReceiver)
verify(mockUBRUser1, never()).unregisterReceiver(broadcastReceiver)
}
@Test
fun testRegisterCurrentAsActualUser() {
setUserMock(mockContext, user1)
broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
mockHandler, UserHandle.CURRENT)
testableLooper.processAllMessages()
verify(mockUBRUser1).registerReceiver(capture(argumentCaptor))
assertSame(broadcastReceiver, argumentCaptor.value.receiver)
}
@Test(expected = IllegalArgumentException::class)
fun testFilterMustContainActions() {
val testFilter = IntentFilter()
broadcastDispatcher.registerReceiver(broadcastReceiver, testFilter)
}
@Test(expected = IllegalArgumentException::class)
fun testFilterMustNotContainDataScheme() {
val testFilter = IntentFilter(TEST_ACTION).apply {
addDataScheme(TEST_SCHEME)
}
broadcastDispatcher.registerReceiver(broadcastReceiver, testFilter)
}
@Test(expected = IllegalArgumentException::class)
fun testFilterMustNotContainDataAuthority() {
val testFilter = IntentFilter(TEST_ACTION).apply {
addDataAuthority(mock(IntentFilter.AuthorityEntry::class.java))
}
broadcastDispatcher.registerReceiver(broadcastReceiver, testFilter)
}
@Test(expected = IllegalArgumentException::class)
fun testFilterMustNotContainDataPath() {
val testFilter = IntentFilter(TEST_ACTION).apply {
addDataPath(TEST_PATH, PatternMatcher.PATTERN_LITERAL)
}
broadcastDispatcher.registerReceiver(broadcastReceiver, testFilter)
}
@Test(expected = IllegalArgumentException::class)
fun testFilterMustNotContainDataType() {
val testFilter = IntentFilter(TEST_ACTION).apply {
addDataType(TEST_TYPE)
}
broadcastDispatcher.registerReceiver(broadcastReceiver, testFilter)
}
@Test(expected = IllegalArgumentException::class)
fun testFilterMustNotSetPriority() {
val testFilter = IntentFilter(TEST_ACTION).apply {
priority = IntentFilter.SYSTEM_HIGH_PRIORITY
}
broadcastDispatcher.registerReceiver(broadcastReceiver, testFilter)
}
private fun setUserMock(mockContext: Context, user: UserHandle) {
`when`(mockContext.user).thenReturn(user)
`when`(mockContext.userId).thenReturn(user.identifier)
}
private class TestBroadcastDispatcher(
context: Context,
mainHandler: Handler,
bgLooper: Looper,
dumpManager: DumpManager,
var mockUBRMap: Map<Int, UserBroadcastDispatcher>
) : BroadcastDispatcher(context, mainHandler, bgLooper, dumpManager) {
override fun createUBRForUser(userId: Int): UserBroadcastDispatcher {
return mockUBRMap.getOrDefault(userId, mock(UserBroadcastDispatcher::class.java))
}
}
}