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

Commit 5a1c921f authored by Anton Potapov's avatar Anton Potapov Committed by Android (Google) Code Review
Browse files

Merge "Several tweaks to smoothen tile creation experience" into main

parents 6af8b58b ed2a7758
Loading
Loading
Loading
Loading
+13 −9
Original line number Diff line number Diff line
@@ -39,7 +39,6 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -47,6 +46,8 @@ import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.cancellable
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOn
@@ -57,6 +58,7 @@ import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch

/**
 * Provides a hassle-free way to implement new tiles according to current System UI architecture
@@ -83,10 +85,8 @@ class QSTileViewModelImpl<DATA_TYPE>(

    private val users: MutableStateFlow<UserHandle> =
        MutableStateFlow(userRepository.getSelectedUserInfo().userHandle)
    private val userInputs: MutableSharedFlow<QSTileUserAction> =
        MutableSharedFlow(replay = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST)
    private val forceUpdates: MutableSharedFlow<Unit> =
        MutableSharedFlow(replay = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST)
    private val userInputs: MutableSharedFlow<QSTileUserAction> = MutableSharedFlow()
    private val forceUpdates: MutableSharedFlow<Unit> = MutableSharedFlow()
    private val spec
        get() = config.tileSpec

@@ -130,7 +130,7 @@ class QSTileViewModelImpl<DATA_TYPE>(
            tileData.replayCache.isNotEmpty(),
            state.replayCache.isNotEmpty()
        )
        userInputs.tryEmit(userAction)
        tileScope.launch { userInputs.emit(userAction) }
    }

    override fun destroy() {
@@ -151,11 +151,16 @@ class QSTileViewModelImpl<DATA_TYPE>(
                            emit(DataUpdateTrigger.InitialRequest)
                            qsTileLogger.logInitialRequest(spec)
                        }
                        .shareIn(tileScope, SharingStarted.WhileSubscribed())
                tileDataInteractor()
                    .tileData(user, updateTriggers)
                    // combine makes sure updateTriggers is always listened even if
                    // tileDataInteractor#tileData doesn't flatMapLatest on it
                    .combine(updateTriggers) { data, _ -> data }
                    .cancellable()
                    .flowOn(backgroundDispatcher)
            }
            .distinctUntilChanged()
            .shareIn(
                tileScope,
                SharingStarted.WhileSubscribed(),
@@ -171,8 +176,8 @@ class QSTileViewModelImpl<DATA_TYPE>(
     *
     * Subscribing to the result flow twice will result in doubling all actions, logs and analytics.
     */
    private fun userInputFlow(user: UserHandle): Flow<DataUpdateTrigger> {
        return userInputs
    private fun userInputFlow(user: UserHandle): Flow<DataUpdateTrigger> =
        userInputs
            .filterFalseActions()
            .filterByPolicy(user)
            .throttle(CLICK_THROTTLE_DURATION, systemClock)
@@ -187,7 +192,6 @@ class QSTileViewModelImpl<DATA_TYPE>(
            }
            .onEach { userActionInteractor().handleInput(it.input) }
            .flowOn(backgroundDispatcher)
    }

    private fun Flow<QSTileUserAction>.filterByPolicy(user: UserHandle): Flow<QSTileUserAction> =
        config.policy.let { policy ->
+6 −6
Original line number Diff line number Diff line
@@ -36,9 +36,9 @@ data class QSTileConfig(
 */
sealed interface QSTileUIConfig {

    val tileIconRes: Int
    val iconRes: Int
        @DrawableRes get
    val tileLabelRes: Int
    val labelRes: Int
        @StringRes get

    /**
@@ -46,16 +46,16 @@ sealed interface QSTileUIConfig {
     * of [Resource]. Returns [Resources.ID_NULL] for each field.
     */
    data object Empty : QSTileUIConfig {
        override val tileIconRes: Int
        override val iconRes: Int
            get() = Resources.ID_NULL
        override val tileLabelRes: Int
        override val labelRes: Int
            get() = Resources.ID_NULL
    }

    /** Config containing actual icon and label resources. */
    data class Resource(
        @StringRes override val tileIconRes: Int,
        @StringRes override val tileLabelRes: Int,
        @DrawableRes override val iconRes: Int,
        @StringRes override val labelRes: Int,
    ) : QSTileUIConfig
}

+12 −3
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.systemui.qs.tiles.viewmodel

import android.content.Context
import android.service.quicksettings.Tile
import com.android.systemui.common.shared.model.Icon

@@ -41,11 +42,19 @@ data class QSTileState(

    companion object {

        fun build(
            context: Context,
            config: QSTileUIConfig,
            build: Builder.() -> Unit
        ): QSTileState =
            build(
                { Icon.Resource(config.iconRes, null) },
                context.getString(config.labelRes),
                build,
            )

        fun build(icon: () -> Icon, label: CharSequence, build: Builder.() -> Unit): QSTileState =
            Builder(icon, label).apply(build).build()

        fun build(icon: Icon, label: CharSequence, build: Builder.() -> Unit): QSTileState =
            build({ icon }, label, build)
    }

    enum class ActivationState(val legacyState: Int) {
+1 −1
Original line number Diff line number Diff line
@@ -192,7 +192,7 @@ constructor(
        with(qsTileViewModel.config.uiConfig) {
            when (this) {
                is QSTileUIConfig.Empty -> qsTileViewModel.currentState?.label ?: ""
                is QSTileUIConfig.Resource -> context.getString(tileLabelRes)
                is QSTileUIConfig.Resource -> context.getString(labelRes)
            }
        }

+2 −2
Original line number Diff line number Diff line
@@ -117,7 +117,7 @@ class QSTileLoggerTest : SysuiTestCase() {
        underTest.logUserActionPipeline(
            TileSpec.create("test_spec"),
            QSTileUserAction.Click(null),
            QSTileState.build(Icon.Resource(0, ContentDescription.Resource(0)), "") {},
            QSTileState.build({ Icon.Resource(0, ContentDescription.Resource(0)) }, "") {},
            "test_data",
        )

@@ -143,7 +143,7 @@ class QSTileLoggerTest : SysuiTestCase() {
    fun testLogStateUpdate() {
        underTest.logStateUpdate(
            TileSpec.create("test_spec"),
            QSTileState.build(Icon.Resource(0, ContentDescription.Resource(0)), "") {},
            QSTileState.build({ Icon.Resource(0, ContentDescription.Resource(0)) }, "") {},
            "test_data",
        )

Loading