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

Commit 83e45698 authored by Juan Sebastian Martinez's avatar Juan Sebastian Martinez
Browse files

Adding support for slider haptic feedback on different axes.

The axis used to calculate velocity is now configurable via the
SliderHapticFeedbackConfig data class. This allows sliders in different
orientations to incorporate haptic feedback. For example, the vertical
volume sliders.

Test: atest SystemUITests:SliderHaptickFeedbackProviderTest
Flag: NONE
Bug: 316953430
Change-Id: Ie559ad32389120526a9c756cf63da8428dfb8c08
parent 7799b5d9
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.systemui.haptics.slider

import android.view.MotionEvent
import androidx.annotation.FloatRange

/** Configuration parameters of a [SliderHapticFeedbackProvider] */
@@ -38,6 +39,8 @@ data class SliderHapticFeedbackConfig(
    val numberOfLowTicks: Int = 5,
    /** Maximum velocity allowed for vibration scaling. This is not expected to change. */
    val maxVelocityToScale: Float = 2000f, /* In pixels/sec */
    /** Axis to use when computing velocity. Must be the same as the slider's axis of movement */
    val velocityAxis: Int = MotionEvent.AXIS_X,
    /** Vibration scale at the upper bookend of the slider */
    @FloatRange(from = 0.0, to = 1.0) val upperBookendScale: Float = 1f,
    /** Vibration scale at the lower bookend of the slider */
+12 −6
Original line number Diff line number Diff line
@@ -162,27 +162,33 @@ class SliderHapticFeedbackProvider(

    override fun onLowerBookend() {
        if (!hasVibratedAtLowerBookend) {
            velocityTracker.computeCurrentVelocity(UNITS_SECOND, config.maxVelocityToScale)
            vibrateOnEdgeCollision(abs(velocityTracker.xVelocity))
            vibrateOnEdgeCollision(abs(getTrackedVelocity()))
            hasVibratedAtLowerBookend = true
        }
    }

    override fun onUpperBookend() {
        if (!hasVibratedAtUpperBookend) {
            velocityTracker.computeCurrentVelocity(UNITS_SECOND, config.maxVelocityToScale)
            vibrateOnEdgeCollision(abs(velocityTracker.xVelocity))
            vibrateOnEdgeCollision(abs(getTrackedVelocity()))
            hasVibratedAtUpperBookend = true
        }
    }

    override fun onProgress(@FloatRange(from = 0.0, to = 1.0) progress: Float) {
        velocityTracker.computeCurrentVelocity(UNITS_SECOND, config.maxVelocityToScale)
        vibrateDragTexture(abs(velocityTracker.xVelocity), progress)
        vibrateDragTexture(abs(getTrackedVelocity()), progress)
        hasVibratedAtUpperBookend = false
        hasVibratedAtLowerBookend = false
    }

    private fun getTrackedVelocity(): Float {
        velocityTracker.computeCurrentVelocity(UNITS_SECOND, config.maxVelocityToScale)
        return if (velocityTracker.isAxisSupported(config.velocityAxis)) {
            velocityTracker.getAxisVelocity(config.velocityAxis)
        } else {
            0f
        }
    }

    override fun onProgressJump(@FloatRange(from = 0.0, to = 1.0) progress: Float) {}

    override fun onSelectAndArrow(@FloatRange(from = 0.0, to = 1.0) progress: Float) {}
+3 −4
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@ package com.android.systemui.haptics.slider
import android.os.VibrationAttributes
import android.os.VibrationEffect
import android.view.VelocityTracker
import android.view.animation.AccelerateInterpolator
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -51,8 +50,6 @@ class SliderHapticFeedbackProviderTest : SysuiTestCase() {
    private val lowTickDuration = 12 // Mocked duration of a low tick
    private val dragTextureThresholdMillis =
        lowTickDuration * config.numberOfLowTicks + config.deltaMillisForDragInterval
    private val progressInterpolator = AccelerateInterpolator(config.progressInterpolatorFactor)
    private val velocityInterpolator = AccelerateInterpolator(config.velocityInterpolatorFactor)
    private lateinit var sliderHapticFeedbackProvider: SliderHapticFeedbackProvider

    @Before
@@ -60,7 +57,9 @@ class SliderHapticFeedbackProviderTest : SysuiTestCase() {
        MockitoAnnotations.initMocks(this)
        whenever(vibratorHelper.getPrimitiveDurations(any()))
            .thenReturn(intArrayOf(lowTickDuration))
        whenever(velocityTracker.xVelocity).thenReturn(config.maxVelocityToScale)
        whenever(velocityTracker.isAxisSupported(config.velocityAxis)).thenReturn(true)
        whenever(velocityTracker.getAxisVelocity(config.velocityAxis))
            .thenReturn(config.maxVelocityToScale)
        sliderHapticFeedbackProvider =
            SliderHapticFeedbackProvider(vibratorHelper, velocityTracker, config, clock)
    }