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

Commit a70a2f28 authored by Michal Brzezinski's avatar Michal Brzezinski
Browse files

Refactoring recent app gesture recognition logic

Part of introducing gesture live progress tracking.
Adding VelocityTracker so we can not only track distance but also velocity.
Making RecentAppsGestureMonitor overall simpler and nicer.

Bug: 369817369
Test: All tests are passing
Flag: com.android.systemui.shared.new_touchpad_gestures_tutorial
Change-Id: Ib0b8d038acea3417c83ef4cc3a8043ff74bf9504
parent 8a22cd58
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -44,7 +44,7 @@ class RecentAppsGestureMonitorTest : SysuiTestCase() {
    }

    private var gestureState: GestureState = GestureState.NotStarted
    private val velocityTracker =
    private val velocityTracker1D =
        mock<VelocityTracker1D> {
            // by default return correct speed for the gesture - as if pointer is slowing down
            on { calculateVelocity() } doReturn SLOW
@@ -54,7 +54,7 @@ class RecentAppsGestureMonitorTest : SysuiTestCase() {
            gestureDistanceThresholdPx = SWIPE_DISTANCE.toInt(),
            gestureStateChangedCallback = { gestureState = it },
            velocityThresholdPxPerMs = THRESHOLD_VELOCITY_PX_PER_MS,
            velocityTracker = velocityTracker,
            velocityTracker = VerticalVelocityTracker(velocityTracker1D),
        )

    @Test
@@ -64,7 +64,7 @@ class RecentAppsGestureMonitorTest : SysuiTestCase() {

    @Test
    fun doesntTriggerGestureFinished_onGestureSpeedTooHigh() {
        whenever(velocityTracker.calculateVelocity()).thenReturn(FAST)
        whenever(velocityTracker1D.calculateVelocity()).thenReturn(FAST)
        assertStateAfterEvents(events = ThreeFingerGesture.swipeUp(), expectedState = NotStarted)
    }

+7 −10
Original line number Diff line number Diff line
@@ -29,10 +29,7 @@ import com.android.systemui.touchpad.tutorial.ui.gesture.RecentAppsGestureMonito
import com.android.systemui.touchpad.tutorial.ui.gesture.TouchpadGestureMonitor

@Composable
fun RecentAppsGestureTutorialScreen(
    onDoneButtonClicked: () -> Unit,
    onBack: () -> Unit,
) {
fun RecentAppsGestureTutorialScreen(onDoneButtonClicked: () -> Unit, onBack: () -> Unit) {
    val screenConfig =
        TutorialScreenConfig(
            colors = rememberScreenColors(),
@@ -41,20 +38,20 @@ fun RecentAppsGestureTutorialScreen(
                    titleResId = R.string.touchpad_recent_apps_gesture_action_title,
                    bodyResId = R.string.touchpad_recent_apps_gesture_guidance,
                    titleSuccessResId = R.string.touchpad_recent_apps_gesture_success_title,
                    bodySuccessResId = R.string.touchpad_recent_apps_gesture_success_body
                    bodySuccessResId = R.string.touchpad_recent_apps_gesture_success_body,
                ),
            animations =
                TutorialScreenConfig.Animations(
                    educationResId = R.raw.trackpad_recent_apps_edu,
                    successResId = R.raw.trackpad_recent_apps_success
                )
                    successResId = R.raw.trackpad_recent_apps_success,
                ),
        )
    val gestureMonitorProvider =
        object : GestureMonitorProvider {
            @Composable
            override fun rememberGestureMonitor(
                resources: Resources,
                gestureStateChangedCallback: (GestureState) -> Unit
                gestureStateChangedCallback: (GestureState) -> Unit,
            ): TouchpadGestureMonitor {
                val distanceThresholdPx =
                    resources.getDimensionPixelSize(
@@ -65,8 +62,8 @@ fun RecentAppsGestureTutorialScreen(
                return remember(distanceThresholdPx, velocityThresholdPxPerMs) {
                    RecentAppsGestureMonitor(
                        distanceThresholdPx,
                        velocityThresholdPxPerMs,
                        gestureStateChangedCallback,
                        velocityThresholdPxPerMs
                    )
                }
            }
@@ -83,7 +80,7 @@ private fun rememberScreenColors(): TutorialScreenConfig.Colors {
        rememberLottieDynamicProperties(
            rememberColorFilterProperty(".secondaryFixedDim", secondaryFixedDim),
            rememberColorFilterProperty(".onSecondaryFixed", onSecondaryFixed),
            rememberColorFilterProperty(".onSecondaryFixedVariant", onSecondaryFixedVariant)
            rememberColorFilterProperty(".onSecondaryFixedVariant", onSecondaryFixedVariant),
        )
    val screenColors =
        remember(dynamicProperties) {
+3 −3
Original line number Diff line number Diff line
@@ -28,10 +28,10 @@ class BackGestureMonitor(

    override fun processTouchpadEvent(event: MotionEvent) {
        if (!isThreeFingerTouchpadSwipe(event)) return
        val distanceState = distanceTracker.processEvent(event)
        updateGestureStateBasedOnDistance(
        val gestureState = distanceTracker.processEvent(event)
        updateGestureState(
            gestureStateChangedCallback,
            distanceState,
            gestureState,
            isFinished = { abs(it.deltaX) >= gestureDistanceThresholdPx },
            progress = { 0f },
        )
+4 −4
Original line number Diff line number Diff line
@@ -38,10 +38,10 @@ class DistanceTracker(var startX: Float = 0f, var startY: Float = 0f) {
    }
}

sealed interface DistanceGestureState
sealed class DistanceGestureState(val deltaX: Float, val deltaY: Float)

class Started(val deltaX: Float, val deltaY: Float) : DistanceGestureState
class Started(deltaX: Float, deltaY: Float) : DistanceGestureState(deltaX, deltaY)

class Moving(val deltaX: Float, val deltaY: Float) : DistanceGestureState
class Moving(deltaX: Float, deltaY: Float) : DistanceGestureState(deltaX, deltaY)

class Finished(val deltaX: Float, val deltaY: Float) : DistanceGestureState
class Finished(deltaX: Float, deltaY: Float) : DistanceGestureState(deltaX, deltaY)
+2 −5
Original line number Diff line number Diff line
@@ -16,11 +16,8 @@

package com.android.systemui.touchpad.tutorial.ui.gesture

/**
 * Helper function for gesture recognizers to have common state triggering logic based on distance
 * only.
 */
inline fun updateGestureStateBasedOnDistance(
/** Helper function for gesture recognizers to have common state triggering logic */
inline fun updateGestureState(
    gestureStateChangedCallback: (GestureState) -> Unit,
    gestureState: DistanceGestureState?,
    isFinished: (Finished) -> Boolean,
Loading