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

Commit 82e95bfc authored by Juan Sebastian Martinez's avatar Juan Sebastian Martinez Committed by Android (Google) Code Review
Browse files

Merge "Fixing multiple coroutine launches and binder calls on state changes." into main

parents b2408a25 837cd669
Loading
Loading
Loading
Loading
+31 −19
Original line number Diff line number Diff line
@@ -20,9 +20,14 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.qs.tileimpl.QSTileViewImpl
import kotlinx.coroutines.DisposableHandle
import kotlinx.coroutines.launch

object QSLongPressEffectViewBinder {
class QSLongPressEffectViewBinder {

    private var handle: DisposableHandle? = null
    val isBound: Boolean
        get() = handle != null

    fun bind(
        tile: QSTileViewImpl,
@@ -30,6 +35,7 @@ object QSLongPressEffectViewBinder {
    ) {
        if (effect == null) return

        handle =
            tile.repeatWhenAttached {
                repeatOnLifecycle(Lifecycle.State.STARTED) {
                    effect.scope = this
@@ -50,7 +56,8 @@ object QSLongPressEffectViewBinder {
                            action?.let {
                                when (it) {
                                    QSLongPressEffect.ActionType.CLICK -> tile.performClick()
                                QSLongPressEffect.ActionType.LONG_PRESS -> tile.performLongClick()
                                    QSLongPressEffect.ActionType.LONG_PRESS ->
                                        tile.performLongClick()
                                }
                                effect.clearActionType()
                            }
@@ -59,4 +66,9 @@ object QSLongPressEffectViewBinder {
                }
            }
    }

    fun dispose() {
        handle?.dispose()
        handle = null
    }
}
+7 −1
Original line number Diff line number Diff line
@@ -181,11 +181,14 @@ open class QSTileViewImpl @JvmOverloads constructor(

    /** Visuo-haptic long-press effects */
    private var longPressEffect: QSLongPressEffect? = null
    private val longPressEffectViewBinder = QSLongPressEffectViewBinder()
    private var initialLongPressProperties: QSLongPressProperties? = null
    private var finalLongPressProperties: QSLongPressProperties? = null
    private val colorEvaluator = ArgbEvaluator.getInstance()
    val hasLongPressEffect: Boolean
        get() = longPressEffect != null
    @VisibleForTesting val isLongPressEffectBound: Boolean
        get() = longPressEffectViewBinder.isBound

    init {
        val typedValue = TypedValue()
@@ -616,11 +619,14 @@ open class QSTileViewImpl @JvmOverloads constructor(
                // set the valid long-press effect as the touch listener
                showRippleEffect = false
                setOnTouchListener(longPressEffect)
                QSLongPressEffectViewBinder.bind(this, longPressEffect)
                if (!longPressEffectViewBinder.isBound) {
                    longPressEffectViewBinder.bind(this, longPressEffect)
                }
            } else {
                // Long-press effects might have been enabled before but the new state does not
                // handle a long-press. In this case, we go back to the behaviour of a regular tile
                // and clean-up the resources
                longPressEffectViewBinder.dispose()
                showRippleEffect = isClickable
                setOnTouchListener(null)
                longPressEffect = null
+30 −0
Original line number Diff line number Diff line
@@ -410,6 +410,36 @@ class QSTileViewImplTest : SysuiTestCase() {
        assertThat(tileView.hasLongPressEffect).isTrue()
    }

    @Test
    @EnableFlags(FLAG_QUICK_SETTINGS_VISUAL_HAPTICS_LONGPRESS)
    fun onStateChange_fromLongPress_to_noLongPress_unBoundsTile() {
        // GIVEN a state that no longer handles long-press
        val state = QSTile.State()
        state.handlesLongClick = false

        // WHEN the state changes
        tileView.changeState(state)

        // THEN the view binder no longer binds the view to the long-press effect
        assertThat(tileView.isLongPressEffectBound).isFalse()
    }

    @Test
    @EnableFlags(FLAG_QUICK_SETTINGS_VISUAL_HAPTICS_LONGPRESS)
    fun onStateChange_fromNoLongPress_to_longPress_bindsTile() {
        // GIVEN that the tile has changed to a state that does not handle long-press
        val state = QSTile.State()
        state.handlesLongClick = false
        tileView.changeState(state)

        // WHEN the state changes back to handling long-press
        state.handlesLongClick = true
        tileView.changeState(state)

        // THEN the view is bounded to the long-press effect
        assertThat(tileView.isLongPressEffectBound).isTrue()
    }

    class FakeTileView(
        context: Context,
        collapsed: Boolean