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

Commit 3da365b1 authored by Chelsea Hao's avatar Chelsea Hao Committed by Android (Google) Code Review
Browse files

Merge "Apply a min duration limit for smoother animation." into main

parents 718e4628 5562f8ae
Loading
Loading
Loading
Loading
+36 −6
Original line number Diff line number Diff line
@@ -32,13 +32,18 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.android.internal.logging.UiEventLogger
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.res.R
import com.android.systemui.statusbar.phone.SystemUIDialog
import com.android.systemui.util.time.SystemClock
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.isActive
import kotlinx.coroutines.withContext

/** Dialog for showing active, connected and saved bluetooth devices. */
@SysUISingleton
@@ -47,6 +52,7 @@ constructor(
    private val bluetoothToggleInitialValue: Boolean,
    private val subtitleResIdInitialValue: Int,
    private val bluetoothTileDialogCallback: BluetoothTileDialogCallback,
    @Main private val mainDispatcher: CoroutineDispatcher,
    private val systemClock: SystemClock,
    private val uiEventLogger: UiEventLogger,
    private val logger: BluetoothTileDialogLogger,
@@ -65,6 +71,10 @@ constructor(

    private val deviceItemAdapter: Adapter = Adapter(bluetoothTileDialogCallback)

    private var lastUiUpdateMs: Long = -1

    private var lastItemRow: Int = -1

    private lateinit var toggleView: Switch
    private lateinit var subtitleTextView: TextView
    private lateinit var doneButton: View
@@ -103,16 +113,31 @@ constructor(
        }
    }

    internal fun onDeviceItemUpdated(
    override fun start() {
        lastUiUpdateMs = systemClock.elapsedRealtime()
    }

    internal suspend fun onDeviceItemUpdated(
        deviceItem: List<DeviceItem>,
        showSeeAll: Boolean,
        showPairNewDevice: Boolean
    ) {
        withContext(mainDispatcher) {
            val start = systemClock.elapsedRealtime()
            val itemRow = deviceItem.size + showSeeAll.toInt() + showPairNewDevice.toInt()
            // Add a slight delay for smoother dialog height change
            if (itemRow != lastItemRow) {
                delay(MIN_HEIGHT_CHANGE_INTERVAL_MS - (start - lastUiUpdateMs))
            }
            if (isActive) {
                deviceItemAdapter.refreshDeviceItemList(deviceItem) {
                    seeAllViewGroup.visibility = if (showSeeAll) VISIBLE else GONE
                    pairNewDeviceViewGroup.visibility = if (showPairNewDevice) VISIBLE else GONE
            logger.logDeviceUiUpdate(systemClock.elapsedRealtime() - start)
                    lastUiUpdateMs = systemClock.elapsedRealtime()
                    lastItemRow = itemRow
                    logger.logDeviceUiUpdate(lastUiUpdateMs - start)
                }
            }
        }
    }

@@ -230,6 +255,7 @@ constructor(
    }

    internal companion object {
        const val MIN_HEIGHT_CHANGE_INTERVAL_MS = 800L
        const val MAX_DEVICE_ITEM_ENTRY = 3
        const val ACTION_BLUETOOTH_DEVICE_DETAILS =
            "com.android.settings.BLUETOOTH_DEVICE_DETAIL_SETTINGS"
@@ -238,5 +264,9 @@ constructor(
        const val ACTION_PAIR_NEW_DEVICE = "android.settings.BLUETOOTH_PAIRING_SETTINGS"
        const val DISABLED_ALPHA = 0.3f
        const val ENABLED_ALPHA = 1f

        private fun Boolean.toInt(): Int {
            return if (this) 1 else 0
        }
    }
}
+11 −9
Original line number Diff line number Diff line
@@ -40,7 +40,6 @@ import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
@@ -76,6 +75,7 @@ constructor(
        dismissDialog()

        var updateDeviceItemJob: Job? = null
        var updateDialogUiJob: Job? = null

        job =
            coroutineScope.launch(mainDispatcher) {
@@ -93,10 +93,9 @@ constructor(
                    )
                }
                    ?: dialog!!.show()

                updateDeviceItemJob?.cancel()
                updateDeviceItemJob = launch {
                    // Add a slight delay for smoother dialog bounds change
                    delay(FIRST_LOAD_DELAY_MS)
                    deviceItemInteractor.updateDeviceItems(context, DeviceFetchTrigger.FIRST_LOAD)
                }

@@ -128,12 +127,15 @@ constructor(

                deviceItemInteractor.deviceItemUpdate
                    .onEach {
                        dialog!!.onDeviceItemUpdated(
                        updateDialogUiJob?.cancel()
                        updateDialogUiJob = launch {
                            dialog?.onDeviceItemUpdated(
                                it.take(MAX_DEVICE_ITEM_ENTRY),
                                showSeeAll = it.size > MAX_DEVICE_ITEM_ENTRY,
                                showPairNewDevice = bluetoothStateInteractor.isBluetoothEnabled
                            )
                        }
                    }
                    .launchIn(this)

                dialog!!
@@ -153,6 +155,7 @@ constructor(
                bluetoothStateInteractor.isBluetoothEnabled,
                getSubtitleResId(bluetoothStateInteractor.isBluetoothEnabled),
                this@BluetoothTileDialogViewModel,
                mainDispatcher,
                systemClock,
                uiEventLogger,
                logger,
@@ -205,7 +208,6 @@ constructor(

    companion object {
        private const val INTERACTION_JANK_TAG = "bluetooth_tile_dialog"
        private const val FIRST_LOAD_DELAY_MS = 500L
        private fun getSubtitleResId(isBluetoothEnabled: Boolean) =
            if (isBluetoothEnabled) R.string.quick_settings_bluetooth_tile_subtitle
            else R.string.bt_is_off
+69 −47
Original line number Diff line number Diff line
@@ -32,6 +32,11 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.res.R
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.test.TestCoroutineScheduler
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@@ -67,17 +72,24 @@ class BluetoothTileDialogTest : SysuiTestCase() {

    private val fakeSystemClock = FakeSystemClock()

    private lateinit var scheduler: TestCoroutineScheduler
    private lateinit var dispatcher: CoroutineDispatcher
    private lateinit var testScope: TestScope
    private lateinit var icon: Pair<Drawable, String>
    private lateinit var bluetoothTileDialog: BluetoothTileDialog
    private lateinit var deviceItem: DeviceItem

    @Before
    fun setUp() {
        scheduler = TestCoroutineScheduler()
        dispatcher = UnconfinedTestDispatcher(scheduler)
        testScope = TestScope(dispatcher)
        bluetoothTileDialog =
            BluetoothTileDialog(
                ENABLED,
                subtitleResId,
                bluetoothTileDialogCallback,
                dispatcher,
                fakeSystemClock,
                uiEventLogger,
                logger,
@@ -111,17 +123,20 @@ class BluetoothTileDialogTest : SysuiTestCase() {

    @Test
    fun testShowDialog_displayBluetoothDevice() {
        testScope.runTest {
            bluetoothTileDialog =
                BluetoothTileDialog(
                    ENABLED,
                    subtitleResId,
                    bluetoothTileDialogCallback,
                    dispatcher,
                    fakeSystemClock,
                    uiEventLogger,
                    logger,
                    mContext
                )
            bluetoothTileDialog.show()
            fakeSystemClock.setElapsedRealtime(Long.MAX_VALUE)
            bluetoothTileDialog.onDeviceItemUpdated(
                listOf(deviceItem),
                showSeeAll = false,
@@ -135,6 +150,7 @@ class BluetoothTileDialogTest : SysuiTestCase() {
            assertThat(adapter.getItem(0).connectionSummary).isEqualTo(DEVICE_CONNECTION_SUMMARY)
            assertThat(adapter.getItem(0).iconWithDescription).isEqualTo(icon)
        }
    }

    @Test
    fun testDeviceItemViewHolder_cachedDeviceNotBusy() {
@@ -147,6 +163,7 @@ class BluetoothTileDialogTest : SysuiTestCase() {
                    ENABLED,
                    subtitleResId,
                    bluetoothTileDialogCallback,
                    dispatcher,
                    fakeSystemClock,
                    uiEventLogger,
                    logger,
@@ -173,6 +190,7 @@ class BluetoothTileDialogTest : SysuiTestCase() {
                    ENABLED,
                    subtitleResId,
                    bluetoothTileDialogCallback,
                    dispatcher,
                    fakeSystemClock,
                    uiEventLogger,
                    logger,
@@ -190,17 +208,20 @@ class BluetoothTileDialogTest : SysuiTestCase() {

    @Test
    fun testOnDeviceUpdated_hideSeeAll_showPairNew() {
        testScope.runTest {
            bluetoothTileDialog =
                BluetoothTileDialog(
                    ENABLED,
                    subtitleResId,
                    bluetoothTileDialogCallback,
                    dispatcher,
                    fakeSystemClock,
                    uiEventLogger,
                    logger,
                    mContext
                )
            bluetoothTileDialog.show()
            fakeSystemClock.setElapsedRealtime(Long.MAX_VALUE)
            bluetoothTileDialog.onDeviceItemUpdated(
                listOf(deviceItem),
                showSeeAll = false,
@@ -220,3 +241,4 @@ class BluetoothTileDialogTest : SysuiTestCase() {
            assertThat(adapter.itemCount).isEqualTo(1)
        }
    }
}