Loading packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt +18 −2 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 ( Loading @@ -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( Loading @@ -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> Loading packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt +49 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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, Loading Loading
packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt +18 −2 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 ( Loading @@ -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( Loading @@ -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> Loading
packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt +49 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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, Loading