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

Commit 16f1cea7 authored by Chaohui Wang's avatar Chaohui Wang
Browse files

Catch crash for broadcastReceiverAsUserFlow

Because the flow can be cancelled before registerReceiverAsUser,
unregisterReceiver will throw IllegalArgumentException in this case.

Fix: 315037726
Test: manual - on AppInfoSettings
Test: unit test
Change-Id: If302c26abc4774373dd2a66b8102e689a2760ab9
parent 8209cc13
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -21,13 +21,17 @@ import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.UserHandle
import android.util.Log
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.flowOn

private const val TAG = "BroadcastReceiverAsUser"

/**
 * A [BroadcastReceiver] flow for the given [intentFilter].
 */
@@ -50,4 +54,6 @@ fun Context.broadcastReceiverAsUserFlow(
    )

    awaitClose { unregisterReceiver(broadcastReceiver) }
}.catch { e ->
    Log.e(TAG, "Error while broadcastReceiverAsUserFlow", e)
}.conflate().flowOn(Dispatchers.Default)
+14 −0
Original line number Diff line number Diff line
@@ -32,9 +32,11 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.any
import org.mockito.kotlin.doAnswer
import org.mockito.kotlin.doThrow
import org.mockito.kotlin.eq
import org.mockito.kotlin.isNull
import org.mockito.kotlin.mock
import org.mockito.kotlin.stub

@RunWith(AndroidJUnit4::class)
class BroadcastReceiverAsUserFlowTest {
@@ -83,6 +85,18 @@ class BroadcastReceiverAsUserFlowTest {
        assertThat(onReceiveIsCalled).isTrue()
    }

    @Test
    fun broadcastReceiverAsUserFlow_unregisterReceiverThrowException_noCrash() = runBlocking {
        context.stub {
            on { unregisterReceiver(any()) } doThrow IllegalArgumentException()
        }
        val flow = context.broadcastReceiverAsUserFlow(INTENT_FILTER, USER_HANDLE)

        flow.firstWithTimeoutOrNull()

        assertThat(registeredBroadcastReceiver).isNotNull()
    }

    private companion object {
        val USER_HANDLE: UserHandle = UserHandle.of(0)