Throw exception if IntentFilter is not valid
If the IntentFilter used with BroadcastDispatcher doesn't have at least one action or has other information that's not actions or categories, throw an exception when device is trying to register Bug: 134566046 Test: atest BroadcastDispatcherTest Change-Id: I6be844a1650f1a6d4d6ff32ddaaa32ca7832c43b
This commit is contained in:
@@ -23,6 +23,7 @@ import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.os.Message
|
||||
import android.os.UserHandle
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.util.SparseArray
|
||||
import com.android.internal.annotations.VisibleForTesting
|
||||
@@ -55,7 +56,8 @@ private const val DEBUG = false
|
||||
* a given broadcast.
|
||||
*
|
||||
* Use only for IntentFilters with actions and optionally categories. It does not support,
|
||||
* permissions, schemes or data types. Cannot be used for getting sticky broadcasts.
|
||||
* permissions, schemes, data types or data authorities.
|
||||
* Cannot be used for getting sticky broadcasts.
|
||||
*/
|
||||
@Singleton
|
||||
open class BroadcastDispatcher @Inject constructor (
|
||||
@@ -72,11 +74,14 @@ open class BroadcastDispatcher @Inject constructor (
|
||||
*
|
||||
* @param receiver A receiver to dispatch the [Intent]
|
||||
* @param filter A filter to determine what broadcasts should be dispatched to this receiver.
|
||||
* It will only take into account actions and categories for filtering.
|
||||
* It will only take into account actions and categories for filtering. It must
|
||||
* have at least one action.
|
||||
* @param handler A handler to dispatch [BroadcastReceiver.onReceive]. By default, it is the
|
||||
* main handler. Pass `null` to use the default.
|
||||
* @param user A user handle to determine which broadcast should be dispatched to this receiver.
|
||||
* By default, it is the current user.
|
||||
* @throws IllegalArgumentException if the filter has other constraints that are not actions or
|
||||
* categories or the filter has no actions.
|
||||
*/
|
||||
@JvmOverloads
|
||||
fun registerReceiver(
|
||||
@@ -85,12 +90,23 @@ open class BroadcastDispatcher @Inject constructor (
|
||||
handler: Handler? = mainHandler,
|
||||
user: UserHandle = context.user
|
||||
) {
|
||||
checkFilter(filter)
|
||||
this.handler
|
||||
.obtainMessage(MSG_ADD_RECEIVER,
|
||||
ReceiverData(receiver, filter, handler ?: mainHandler, user))
|
||||
.sendToTarget()
|
||||
}
|
||||
|
||||
private fun checkFilter(filter: IntentFilter) {
|
||||
val sb = StringBuilder()
|
||||
if (filter.countActions() == 0) sb.append("Filter must contain at least one action. ")
|
||||
if (filter.countDataAuthorities() != 0) sb.append("Filter cannot contain DataAuthorities. ")
|
||||
if (filter.countDataPaths() != 0) sb.append("Filter cannot contain DataPaths. ")
|
||||
if (filter.countDataSchemes() != 0) sb.append("Filter cannot contain DataSchemes. ")
|
||||
if (filter.countDataTypes() != 0) sb.append("Filter cannot contain DataTypes. ")
|
||||
if (!TextUtils.isEmpty(sb)) throw IllegalArgumentException(sb.toString())
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister receiver for all users.
|
||||
* <br>
|
||||
|
||||
@@ -21,6 +21,7 @@ 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
|
||||
@@ -33,6 +34,7 @@ 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
|
||||
@@ -48,6 +50,10 @@ class BroadcastDispatcherTest : SysuiTestCase() {
|
||||
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
|
||||
@@ -83,6 +89,11 @@ class BroadcastDispatcherTest : SysuiTestCase() {
|
||||
Handler(testableLooper.looper),
|
||||
testableLooper.looper,
|
||||
mapOf(0 to mockUBRUser0, 1 to mockUBRUser1))
|
||||
|
||||
// These should be valid filters
|
||||
`when`(intentFilter.countActions()).thenReturn(1)
|
||||
`when`(intentFilterOther.countActions()).thenReturn(1)
|
||||
`when`(mockContext.user).thenReturn(user0)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -129,6 +140,44 @@ class BroadcastDispatcherTest : SysuiTestCase() {
|
||||
verify(mockUBRUser1, never()).unregisterReceiver(broadcastReceiver)
|
||||
}
|
||||
|
||||
@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)
|
||||
}
|
||||
|
||||
private class TestBroadcastDispatcher(
|
||||
context: Context,
|
||||
mainHandler: Handler,
|
||||
|
||||
Reference in New Issue
Block a user