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

Commit 25cba56e authored by Juan Sebastian Martinez's avatar Juan Sebastian Martinez
Browse files

Using View.performHapticFeedback on Back Panel Controller when the back gesture is handled

Migration towards the new one-way API that can trigger haptic feedback from the UI thread. Calls to cancel vibrations and vibrations triggered in a separate thread (old API) have been replaced by calls to performHapticFeedback directly from the UI thread. Delaying cancellations and delayed haptics is no longer necessary. The migration is controlled by a feature flag at the moment.

Test: Tests that handled back gesture-committed and -cancelled now verify different method calls from the VibratorHelper depending on the feature flag.
Bug: 245528624
Change-Id: I5e3b8d67f26cd7002d2372f116ec2601053c4328
parent 5f4429ae
Loading
Loading
Loading
Loading
+350 −314

File changed.

Preview size limit exceeded, changes collapsed.

+68 −1
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.os.Handler
import android.os.Looper
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.view.HapticFeedbackConstants
import android.view.MotionEvent
import android.view.MotionEvent.ACTION_DOWN
import android.view.MotionEvent.ACTION_MOVE
@@ -29,6 +30,8 @@ import android.view.WindowManager
import androidx.test.filters.SmallTest
import com.android.internal.util.LatencyTracker
import com.android.systemui.SysuiTestCase
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags.ONE_WAY_HAPTICS_API_MIGRATION
import com.android.systemui.plugins.NavigationEdgeBackPlugin
import com.android.systemui.statusbar.VibratorHelper
import com.android.systemui.statusbar.policy.ConfigurationController
@@ -36,6 +39,8 @@ import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.any
import org.mockito.ArgumentMatchers.eq
import org.mockito.Mock
import org.mockito.Mockito.clearInvocations
import org.mockito.Mockito.verify
@@ -58,6 +63,7 @@ class BackPanelControllerTest : SysuiTestCase() {
    @Mock private lateinit var latencyTracker: LatencyTracker
    @Mock private lateinit var layoutParams: WindowManager.LayoutParams
    @Mock private lateinit var backCallback: NavigationEdgeBackPlugin.BackCallback
    private val featureFlags = FakeFeatureFlags()

    @Before
    fun setup() {
@@ -70,7 +76,8 @@ class BackPanelControllerTest : SysuiTestCase() {
                Handler.createAsync(Looper.myLooper()),
                vibratorHelper,
                configurationController,
                latencyTracker
                latencyTracker,
                featureFlags
            )
        mBackPanelController.setLayoutParams(layoutParams)
        mBackPanelController.setBackCallback(backCallback)
@@ -99,6 +106,7 @@ class BackPanelControllerTest : SysuiTestCase() {

    @Test
    fun handlesBackCommitted() {
        featureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, false)
        startTouch()
        // Move once to cross the touch slop
        continueTouch(START_X + touchSlop.toFloat() + 1)
@@ -121,8 +129,35 @@ class BackPanelControllerTest : SysuiTestCase() {
        verify(backCallback).triggerBack()
    }

    @Test
    fun handlesBackCommitted_withOneWayHapticsAPI() {
        featureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, true)
        startTouch()
        // Move once to cross the touch slop
        continueTouch(START_X + touchSlop.toFloat() + 1)
        // Move again to cross the back trigger threshold
        continueTouch(START_X + touchSlop + triggerThreshold + 1)
        // Wait threshold duration and hold touch past trigger threshold
        Thread.sleep((MAX_DURATION_ENTRY_BEFORE_ACTIVE_ANIMATION + 1).toLong())
        continueTouch(START_X + touchSlop + triggerThreshold + 1)

        assertThat(mBackPanelController.currentState)
            .isEqualTo(BackPanelController.GestureState.ACTIVE)
        verify(backCallback).setTriggerBack(true)
        testableLooper.moveTimeForward(100)
        testableLooper.processAllMessages()
        verify(vibratorHelper)
            .performHapticFeedback(any(), eq(HapticFeedbackConstants.GESTURE_THRESHOLD_ACTIVATE))

        finishTouchActionUp(START_X + touchSlop + triggerThreshold + 1)
        assertThat(mBackPanelController.currentState)
            .isEqualTo(BackPanelController.GestureState.COMMITTED)
        verify(backCallback).triggerBack()
    }

    @Test
    fun handlesBackCancelled() {
        featureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, false)
        startTouch()
        // Move once to cross the touch slop
        continueTouch(START_X + touchSlop.toFloat() + 1)
@@ -151,6 +186,38 @@ class BackPanelControllerTest : SysuiTestCase() {
        verify(backCallback).cancelBack()
    }

    @Test
    fun handlesBackCancelled_withOneWayHapticsAPI() {
        featureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, true)
        startTouch()
        // Move once to cross the touch slop
        continueTouch(START_X + touchSlop.toFloat() + 1)
        // Move again to cross the back trigger threshold
        continueTouch(
            START_X + touchSlop + triggerThreshold -
                mBackPanelController.params.deactivationTriggerThreshold
        )
        // Wait threshold duration and hold touch before trigger threshold
        Thread.sleep((MAX_DURATION_ENTRY_BEFORE_ACTIVE_ANIMATION + 1).toLong())
        continueTouch(
            START_X + touchSlop + triggerThreshold -
                mBackPanelController.params.deactivationTriggerThreshold
        )
        clearInvocations(backCallback)
        Thread.sleep(MIN_DURATION_ACTIVE_BEFORE_INACTIVE_ANIMATION)
        // Move in the opposite direction to cross the deactivation threshold and cancel back
        continueTouch(START_X)

        assertThat(mBackPanelController.currentState)
            .isEqualTo(BackPanelController.GestureState.INACTIVE)
        verify(backCallback).setTriggerBack(false)
        verify(vibratorHelper)
            .performHapticFeedback(any(), eq(HapticFeedbackConstants.GESTURE_THRESHOLD_DEACTIVATE))

        finishTouchActionUp(START_X)
        verify(backCallback).cancelBack()
    }

    private fun startTouch() {
        mBackPanelController.onMotionEvent(createMotionEvent(ACTION_DOWN, START_X, 0f))
    }