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

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

Merge "Allowing clicks that can occur during the long-press effect." into main

parents 30bea73d d0814293
Loading
Loading
Loading
Loading
+40 −18
Original line number Diff line number Diff line
@@ -144,7 +144,7 @@ class QSLongPressEffectTest : SysuiTestCase() {
            longPressEffect.handleActionUp()

            // THEN the effect reverses
            assertEffectReverses()
            assertEffectReverses(QSLongPressEffect.State.RUNNING_BACKWARDS_FROM_UP)
        }

    @Test
@@ -171,18 +171,17 @@ class QSLongPressEffectTest : SysuiTestCase() {
            longPressEffect.handleActionCancel()

            // THEN the effect gets reversed
            assertEffectReverses()
            assertEffectReverses(QSLongPressEffect.State.RUNNING_BACKWARDS_FROM_CANCEL)
        }

    @Test
    fun onAnimationComplete_keyguardDismissible_effectEndsWithPrepare() =
    fun onAnimationComplete_keyguardDismissible_effectCompletes() =
        testWhileInState(QSLongPressEffect.State.RUNNING_FORWARD) {
            // GIVEN that the animation completes
            longPressEffect.handleAnimationComplete()

            // THEN the long-press effect completes and the view is called to prepare
            // THEN the long-press effect completes
            assertEffectCompleted()
            verify(callback, times(1)).onPrepareForLaunch()
        }

    @Test
@@ -199,6 +198,26 @@ class QSLongPressEffectTest : SysuiTestCase() {
            verify(callback, times(1)).onResetProperties()
        }

    @Test
    fun onAnimationComplete_whenRunningBackwardsFromUp_endsWithFinishedReversing() =
        testWhileInState(QSLongPressEffect.State.RUNNING_BACKWARDS_FROM_UP) {
            // GIVEN that the animation completes
            longPressEffect.handleAnimationComplete()

            // THEN the callback for finished reversing is used.
            verify(callback, times(1)).onEffectFinishedReversing()
        }

    @Test
    fun onAnimationComplete_whenRunningBackwardsFromCancel_endsInIdle() =
        testWhileInState(QSLongPressEffect.State.RUNNING_BACKWARDS_FROM_CANCEL) {
            // GIVEN that the animation completes
            longPressEffect.handleAnimationComplete()

            // THEN the effect ends in the idle state.
            assertThat(longPressEffect.state).isEqualTo(QSLongPressEffect.State.IDLE)
        }

    @Test
    fun onActionDown_whileRunningBackwards_cancels() =
        testWhileInState(QSLongPressEffect.State.RUNNING_FORWARD) {
@@ -223,11 +242,8 @@ class QSLongPressEffectTest : SysuiTestCase() {
        }

    @Test
    fun onAnimationComplete_whileRunningBackwards_goesToIdle() =
        testWhileInState(QSLongPressEffect.State.RUNNING_BACKWARDS) {
            // GIVEN an action cancel occurs and the effect gets reversed
            longPressEffect.handleActionCancel()

    fun onAnimationComplete_whileRunningBackwardsFromCancel_goesToIdle() =
        testWhileInState(QSLongPressEffect.State.RUNNING_BACKWARDS_FROM_CANCEL) {
            // GIVEN that the animation completes
            longPressEffect.handleAnimationComplete()

@@ -307,12 +323,16 @@ class QSLongPressEffectTest : SysuiTestCase() {
    /**
     * Asserts that the effect did not start by checking that:
     * 1. No haptics are played
     * 2. The internal state is not [QSLongPressEffect.State.RUNNING_BACKWARDS] or
     *    [QSLongPressEffect.State.RUNNING_FORWARD]
     * 2. The internal state is not [QSLongPressEffect.State.RUNNING_BACKWARDS_FROM_UP] or
     *    [QSLongPressEffect.State.RUNNING_FORWARD] or
     *    [QSLongPressEffect.State.RUNNING_BACKWARDS_FROM_CANCEL]
     */
    private fun assertEffectDidNotStart() {
        assertThat(longPressEffect.state).isNotEqualTo(QSLongPressEffect.State.RUNNING_FORWARD)
        assertThat(longPressEffect.state).isNotEqualTo(QSLongPressEffect.State.RUNNING_BACKWARDS)
        assertThat(longPressEffect.state)
            .isNotEqualTo(QSLongPressEffect.State.RUNNING_BACKWARDS_FROM_UP)
        assertThat(longPressEffect.state)
            .isNotEqualTo(QSLongPressEffect.State.RUNNING_BACKWARDS_FROM_CANCEL)
        assertThat(vibratorHelper.totalVibrations).isEqualTo(0)
    }

@@ -330,12 +350,14 @@ class QSLongPressEffectTest : SysuiTestCase() {
    }

    /**
     * Assert that the effect gets reverted by checking that:
     * 1. The internal state is [QSLongPressEffect.State.RUNNING_BACKWARDS]
     * 2. An action to reverse the animator is emitted
     * Assert that the effect gets reverted by checking that the callback to reverse the animator is
     * used, and that the state is given reversing state.
     *
     * @param[reversingState] Either [QSLongPressEffect.State.RUNNING_BACKWARDS_FROM_CANCEL] or
     *   [QSLongPressEffect.State.RUNNING_BACKWARDS_FROM_UP]
     */
    private fun assertEffectReverses() {
        assertThat(longPressEffect.state).isEqualTo(QSLongPressEffect.State.RUNNING_BACKWARDS)
    private fun assertEffectReverses(reversingState: QSLongPressEffect.State) {
        assertThat(longPressEffect.state).isEqualTo(reversingState)
        verify(callback, times(1)).onReverseAnimator()
    }
}
+29 −21
Original line number Diff line number Diff line
@@ -97,14 +97,15 @@ constructor(
            State.IDLE -> {
                setState(State.TIMEOUT_WAIT)
            }
            State.RUNNING_BACKWARDS -> callback?.onCancelAnimator()
            State.RUNNING_BACKWARDS_FROM_UP,
            State.RUNNING_BACKWARDS_FROM_CANCEL -> callback?.onCancelAnimator()
            else -> {}
        }
    }

    fun handleActionUp() {
        if (state == State.RUNNING_FORWARD) {
            setState(State.RUNNING_BACKWARDS)
            setState(State.RUNNING_BACKWARDS_FROM_UP)
            callback?.onReverseAnimator()
        }
    }
@@ -113,7 +114,7 @@ constructor(
        when (state) {
            State.TIMEOUT_WAIT -> setState(State.IDLE)
            State.RUNNING_FORWARD -> {
                setState(State.RUNNING_BACKWARDS)
                setState(State.RUNNING_BACKWARDS_FROM_CANCEL)
                callback?.onReverseAnimator()
            }
            else -> {}
@@ -127,20 +128,24 @@ constructor(

    /** This function is called both when an animator completes or gets cancelled */
    fun handleAnimationComplete() {
        if (state == State.RUNNING_FORWARD) {
        when (state) {
            State.RUNNING_FORWARD -> {
                setState(State.IDLE)
                vibrate(snapEffect)
                if (keyguardStateController.isUnlocked) {
                callback?.onPrepareForLaunch()
                    qsTile?.longClick(expandable)
                } else {
                    callback?.onResetProperties()
                    qsTile?.longClick(expandable)
                }
            }
        if (state != State.TIMEOUT_WAIT) {
            // This will happen if the animator did not finish by being cancelled
            State.RUNNING_BACKWARDS_FROM_UP -> {
                setState(State.IDLE)
                callback?.onEffectFinishedReversing()
                qsTile?.click(expandable)
            }
            State.RUNNING_BACKWARDS_FROM_CANCEL -> setState(State.IDLE)
            else -> {}
        }
    }

@@ -191,20 +196,23 @@ constructor(

    enum class State {
        IDLE, /* The effect is idle waiting for touch input */
        TIMEOUT_WAIT, /* The effect is waiting for a [PRESSED_TIMEOUT] period */
        TIMEOUT_WAIT, /* The effect is waiting for a tap timeout period */
        RUNNING_FORWARD, /* The effect is running normally */
        RUNNING_BACKWARDS, /* The effect was interrupted and is now running backwards */
        /* The effect was interrupted by an ACTION_UP and is now running backwards */
        RUNNING_BACKWARDS_FROM_UP,
        /* The effect was interrupted by an ACTION_CANCEL and is now running backwards */
        RUNNING_BACKWARDS_FROM_CANCEL,
    }

    /** Callbacks to notify view and animator actions */
    interface Callback {

        /** Prepare for an activity launch */
        fun onPrepareForLaunch()

        /** Reset the tile visual properties */
        fun onResetProperties()

        /** Event where the effect completed by being reversed */
        fun onEffectFinishedReversing()

        /** Start the effect animator */
        fun onStartAnimator()

+15 −4
Original line number Diff line number Diff line
@@ -350,6 +350,10 @@ constructor(

        initialLongPressProperties?.width = width
        finalLongPressProperties?.width = LONG_PRESS_EFFECT_WIDTH_SCALE * width

        val deltaW = (LONG_PRESS_EFFECT_WIDTH_SCALE - 1f) * width
        paddingForLaunch.left = -deltaW.toInt() / 2
        paddingForLaunch.right = deltaW.toInt() / 2
    }

    private fun maybeUpdateLongPressEffectHeight(height: Float) {
@@ -357,6 +361,10 @@ constructor(

        initialLongPressProperties?.height = height
        finalLongPressProperties?.height = LONG_PRESS_EFFECT_HEIGHT_SCALE * height

        val deltaH = (LONG_PRESS_EFFECT_HEIGHT_SCALE - 1f) * height
        paddingForLaunch.top = -deltaH.toInt() / 2
        paddingForLaunch.bottom = deltaH.toInt() / 2
    }

    override fun onFocusChanged(gainFocus: Boolean, direction: Int, previouslyFocusedRect: Rect?) {
@@ -432,14 +440,16 @@ constructor(
        longPressEffect?.callback =
            object : QSLongPressEffect.Callback {

                override fun onPrepareForLaunch() {
                    prepareForLaunch()
                }

                override fun onResetProperties() {
                    resetLongPressEffectProperties()
                }

                override fun onEffectFinishedReversing() {
                    // The long-press effect properties finished at the same starting point.
                    // This is the same as if the properties were reset
                    haveLongPressPropertiesBeenReset = true
                }

                override fun onStartAnimator() {
                    if (longPressEffectAnimator?.isRunning != true) {
                        longPressEffectAnimator =
@@ -1043,6 +1053,7 @@ constructor(
                getOverlayColorForState(Tile.STATE_ACTIVE),
                Utils.getColorAttrDefaultColor(context, R.attr.onShadeActive),
            )
        prepareForLaunch()
    }

    private fun changeCornerRadius(radius: Float) {