Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f451d5ae authored by Fabian Kozynski's avatar Fabian Kozynski Committed by Android (Google) Code Review
Browse files

Merge "Throw exception if IntentFilter is not valid"

parents 052a8395 cfe80459
Loading
Loading
Loading
Loading
+18 −2
Original line number Diff line number Diff line
@@ -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>
+49 −0
Original line number Diff line number Diff line
@@ -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,