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

Commit d2b6a86e authored by chelseahao's avatar chelseahao
Browse files

Fix NPE.

Test: atest -c com.android.systemui.qs.tiles.dialog.bluetooth
Bug: b/307786285
Change-Id: Ia31f2f716c072b727b7ddfe507df46e543592369
parent cf01f294
Loading
Loading
Loading
Loading
+19 −22
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@ import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.View
import androidx.annotation.VisibleForTesting
import com.android.internal.jank.InteractionJankMonitor
import com.android.internal.logging.UiEventLogger
import com.android.systemui.animation.DialogCuj
@@ -40,6 +39,8 @@ import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.channels.produce
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
@@ -63,26 +64,25 @@ constructor(

    private var job: Job? = null

    @VisibleForTesting internal var dialog: BluetoothTileDialog? = null

    /**
     * Shows the dialog.
     *
     * @param context The context in which the dialog is displayed.
     * @param view The view from which the dialog is shown.
     */
    @kotlinx.coroutines.ExperimentalCoroutinesApi
    fun showDialog(context: Context, view: View?) {
        dismissDialog()

        var updateDeviceItemJob: Job? = null
        var updateDialogUiJob: Job? = null
        cancelJob()

        job =
            coroutineScope.launch(mainDispatcher) {
                dialog = createBluetoothTileDialog(context)
                var updateDeviceItemJob: Job?
                var updateDialogUiJob: Job? = null
                val dialog = createBluetoothTileDialog(context)

                view?.let {
                    dialogLaunchAnimator.showFromView(
                        dialog!!,
                        dialog,
                        it,
                        animateBackgroundBoundsChange = true,
                        cuj =
@@ -92,9 +92,8 @@ constructor(
                            )
                    )
                }
                    ?: dialog!!.show()
                    ?: dialog.show()

                updateDeviceItemJob?.cancel()
                updateDeviceItemJob = launch {
                    deviceItemInteractor.updateDeviceItems(context, DeviceFetchTrigger.FIRST_LOAD)
                }
@@ -102,7 +101,7 @@ constructor(
                bluetoothStateInteractor.bluetoothStateUpdate
                    .filterNotNull()
                    .onEach {
                        dialog!!.onBluetoothStateUpdated(it, getSubtitleResId(it))
                        dialog.onBluetoothStateUpdated(it, getSubtitleResId(it))
                        updateDeviceItemJob?.cancel()
                        updateDeviceItemJob = launch {
                            deviceItemInteractor.updateDeviceItems(
@@ -129,7 +128,7 @@ constructor(
                    .onEach {
                        updateDialogUiJob?.cancel()
                        updateDialogUiJob = launch {
                            dialog?.onDeviceItemUpdated(
                            dialog.onDeviceItemUpdated(
                                it.take(MAX_DEVICE_ITEM_ENTRY),
                                showSeeAll = it.size > MAX_DEVICE_ITEM_ENTRY,
                                showPairNewDevice = bluetoothStateInteractor.isBluetoothEnabled
@@ -138,15 +137,15 @@ constructor(
                    }
                    .launchIn(this)

                dialog!!
                    .bluetoothStateToggle
                dialog.bluetoothStateToggle
                    .onEach { bluetoothStateInteractor.isBluetoothEnabled = it }
                    .launchIn(this)

                dialog!!
                    .deviceItemClick
                dialog.deviceItemClick
                    .onEach { deviceItemInteractor.updateDeviceItemOnClick(it) }
                    .launchIn(this)

                produce<Unit> { awaitClose { dialog.cancel() } }
            }
    }

@@ -161,7 +160,7 @@ constructor(
                logger,
                context
            )
            .apply { SystemUIDialog.registerDismissListener(this) { dismissDialog() } }
            .apply { SystemUIDialog.registerDismissListener(this) { cancelJob() } }
    }

    override fun onDeviceItemGearClicked(deviceItem: DeviceItem, view: View) {
@@ -188,15 +187,13 @@ constructor(
        startSettingsActivity(Intent(ACTION_PAIR_NEW_DEVICE), view)
    }

    private fun dismissDialog() {
    private fun cancelJob() {
        job?.cancel()
        job = null
        dialog?.dismiss()
        dialog = null
    }

    private fun startSettingsActivity(intent: Intent, view: View) {
        dialog?.run {
        if (job?.isActive == true) {
            intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
            activityStarter.postStartActivityDismissingKeyguard(
                intent,
+24 −20
Original line number Diff line number Diff line
@@ -168,7 +168,8 @@ constructor(
        )
    }

    internal fun updateDeviceItemOnClick(deviceItem: DeviceItem) {
    internal suspend fun updateDeviceItemOnClick(deviceItem: DeviceItem) {
        withContext(backgroundDispatcher) {
            logger.logDeviceClick(deviceItem.cachedBluetoothDevice.address, deviceItem.type)

            deviceItem.cachedBluetoothDevice.apply {
@@ -183,7 +184,9 @@ constructor(
                    }
                    DeviceItemType.CONNECTED_BLUETOOTH_DEVICE -> {
                        disconnect()
                    uiEventLogger.log(BluetoothTileDialogUiEvent.CONNECTED_OTHER_DEVICE_DISCONNECT)
                        uiEventLogger.log(
                            BluetoothTileDialogUiEvent.CONNECTED_OTHER_DEVICE_DISCONNECT
                        )
                    }
                    DeviceItemType.SAVED_BLUETOOTH_DEVICE -> {
                        connect()
@@ -192,6 +195,7 @@ constructor(
                }
            }
        }
    }

    internal fun setDeviceItemFactoryListForTesting(list: List<DeviceItemFactory>) {
        deviceItemFactoryList = list
+0 −7
Original line number Diff line number Diff line
@@ -30,7 +30,6 @@ import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.nullable
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -113,9 +112,7 @@ class BluetoothTileDialogViewModelTest : SysuiTestCase() {
        testScope.runTest {
            bluetoothTileDialogViewModel.showDialog(context, null)

            assertThat(bluetoothTileDialogViewModel.dialog).isNotNull()
            verify(dialogLaunchAnimator, never()).showFromView(any(), any(), any(), any())
            assertThat(bluetoothTileDialogViewModel.dialog?.isShowing).isTrue()
            verify(uiEventLogger).log(BluetoothTileDialogUiEvent.BLUETOOTH_TILE_DIALOG_SHOWN)
        }
    }
@@ -125,7 +122,6 @@ class BluetoothTileDialogViewModelTest : SysuiTestCase() {
        testScope.runTest {
            bluetoothTileDialogViewModel.showDialog(mContext, LinearLayout(mContext))

            assertThat(bluetoothTileDialogViewModel.dialog).isNotNull()
            verify(dialogLaunchAnimator).showFromView(any(), any(), nullable(), anyBoolean())
        }
    }
@@ -136,7 +132,6 @@ class BluetoothTileDialogViewModelTest : SysuiTestCase() {
            backgroundExecutor.execute {
                bluetoothTileDialogViewModel.showDialog(mContext, LinearLayout(mContext))

                assertThat(bluetoothTileDialogViewModel.dialog).isNotNull()
                verify(dialogLaunchAnimator).showFromView(any(), any(), nullable(), anyBoolean())
            }
        }
@@ -147,7 +142,6 @@ class BluetoothTileDialogViewModelTest : SysuiTestCase() {
        testScope.runTest {
            bluetoothTileDialogViewModel.showDialog(context, null)

            assertThat(bluetoothTileDialogViewModel.dialog).isNotNull()
            verify(deviceItemInteractor).deviceItemUpdate
        }
    }
@@ -157,7 +151,6 @@ class BluetoothTileDialogViewModelTest : SysuiTestCase() {
        testScope.runTest {
            bluetoothTileDialogViewModel.showDialog(context, null)

            assertThat(bluetoothTileDialogViewModel.dialog).isNotNull()
            verify(bluetoothStateInteractor).bluetoothStateUpdate
        }
    }
+31 −19
Original line number Diff line number Diff line
@@ -220,17 +220,23 @@ class DeviceItemInteractorTest : SysuiTestCase() {

    @Test
    fun testUpdateDeviceItemOnClick_connectedMedia_setActive() {
        testScope.runTest {
            `when`(deviceItem1.type).thenReturn(DeviceItemType.AVAILABLE_MEDIA_BLUETOOTH_DEVICE)

            interactor.updateDeviceItemOnClick(deviceItem1)

            verify(cachedDevice1).setActive()
            verify(logger)
            .logDeviceClick(cachedDevice1.address, DeviceItemType.AVAILABLE_MEDIA_BLUETOOTH_DEVICE)
                .logDeviceClick(
                    cachedDevice1.address,
                    DeviceItemType.AVAILABLE_MEDIA_BLUETOOTH_DEVICE
                )
        }
    }

    @Test
    fun testUpdateDeviceItemOnClick_activeMedia_disconnect() {
        testScope.runTest {
            `when`(deviceItem1.type).thenReturn(DeviceItemType.ACTIVE_MEDIA_BLUETOOTH_DEVICE)

            interactor.updateDeviceItemOnClick(deviceItem1)
@@ -239,9 +245,11 @@ class DeviceItemInteractorTest : SysuiTestCase() {
            verify(logger)
                .logDeviceClick(cachedDevice1.address, DeviceItemType.ACTIVE_MEDIA_BLUETOOTH_DEVICE)
        }
    }

    @Test
    fun testUpdateDeviceItemOnClick_connectedOtherDevice_disconnect() {
        testScope.runTest {
            `when`(deviceItem1.type).thenReturn(DeviceItemType.CONNECTED_BLUETOOTH_DEVICE)

            interactor.updateDeviceItemOnClick(deviceItem1)
@@ -250,15 +258,19 @@ class DeviceItemInteractorTest : SysuiTestCase() {
            verify(logger)
                .logDeviceClick(cachedDevice1.address, DeviceItemType.CONNECTED_BLUETOOTH_DEVICE)
        }
    }

    @Test
    fun testUpdateDeviceItemOnClick_saved_connect() {
        testScope.runTest {
            `when`(deviceItem1.type).thenReturn(DeviceItemType.SAVED_BLUETOOTH_DEVICE)

            interactor.updateDeviceItemOnClick(deviceItem1)

            verify(cachedDevice1).connect()
        verify(logger).logDeviceClick(cachedDevice1.address, DeviceItemType.SAVED_BLUETOOTH_DEVICE)
            verify(logger)
                .logDeviceClick(cachedDevice1.address, DeviceItemType.SAVED_BLUETOOTH_DEVICE)
        }
    }

    private fun createFactory(