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

Commit 3fd36128 authored by Michał Brzeziński's avatar Michał Brzeziński Committed by Android (Google) Code Review
Browse files

Merge "Extracting common tests into ThreeFingerGestureRecognizerTest" into main

parents 3a1bd119 daf75f79
Loading
Loading
Loading
Loading
+3 −46
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.touchpad.tutorial.ui.gesture.GestureDirection.LEFT
import com.android.systemui.touchpad.tutorial.ui.gesture.GestureDirection.RIGHT
import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.Finished
import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.InProgress
import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.NotStarted
import com.android.systemui.touchpad.tutorial.ui.gesture.MultiFingerGesture.Companion.SWIPE_DISTANCE
@@ -44,24 +43,6 @@ class BackGestureRecognizerTest : SysuiTestCase() {
        gestureRecognizer.addGestureStateCallback { gestureState = it }
    }

    @Test
    fun triggersGestureFinishedForThreeFingerGestureRight() {
        assertStateAfterEvents(events = ThreeFingerGesture.swipeRight(), expectedState = Finished)
    }

    @Test
    fun triggersGestureFinishedForThreeFingerGestureLeft() {
        assertStateAfterEvents(events = ThreeFingerGesture.swipeLeft(), expectedState = Finished)
    }

    @Test
    fun triggersGestureProgressForThreeFingerGestureStarted() {
        assertStateAfterEvents(
            events = ThreeFingerGesture.startEvents(x = 0f, y = 0f),
            expectedState = InProgress(),
        )
    }

    @Test
    fun triggersProgressRelativeToDistanceWhenSwipingLeft() {
        assertProgressWhileMovingFingers(
@@ -86,13 +67,6 @@ class BackGestureRecognizerTest : SysuiTestCase() {
        )
    }

    private fun assertProgressWhileMovingFingers(deltaX: Float, expected: InProgress) {
        assertStateAfterEvents(
            events = ThreeFingerGesture.eventsForGestureInProgress { move(deltaX = deltaX) },
            expectedState = expected,
        )
    }

    @Test
    fun triggeredProgressIsNoBiggerThanOne() {
        assertProgressWhileMovingFingers(
@@ -105,30 +79,13 @@ class BackGestureRecognizerTest : SysuiTestCase() {
        )
    }

    @Test
    fun doesntTriggerGestureFinished_onGestureDistanceTooShort() {
    private fun assertProgressWhileMovingFingers(deltaX: Float, expected: InProgress) {
        assertStateAfterEvents(
            events = ThreeFingerGesture.swipeLeft(distancePx = SWIPE_DISTANCE / 2),
            expectedState = NotStarted,
            events = ThreeFingerGesture.eventsForGestureInProgress { move(deltaX = deltaX) },
            expectedState = expected,
        )
    }

    @Test
    fun doesntTriggerGestureFinished_onThreeFingersSwipeInOtherDirections() {
        assertStateAfterEvents(events = ThreeFingerGesture.swipeUp(), expectedState = NotStarted)
        assertStateAfterEvents(events = ThreeFingerGesture.swipeDown(), expectedState = NotStarted)
    }

    @Test
    fun doesntTriggerGestureFinished_onTwoFingersSwipe() {
        assertStateAfterEvents(events = TwoFingerGesture.swipeRight(), expectedState = NotStarted)
    }

    @Test
    fun doesntTriggerGestureFinished_onFourFingersSwipe() {
        assertStateAfterEvents(events = FourFingerGesture.swipeRight(), expectedState = NotStarted)
    }

    private fun assertStateAfterEvents(events: List<MotionEvent>, expectedState: GestureState) {
        events.forEach { gestureRecognizer.accept(it) }
        assertThat(gestureState).isEqualTo(expectedState)
+3 −42
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.testKosmos
import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.Finished
import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.InProgress
import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.NotStarted
import com.android.systemui.touchpad.tutorial.ui.gesture.MultiFingerGesture.Companion.SWIPE_DISTANCE
@@ -56,38 +55,18 @@ class HomeGestureRecognizerTest : SysuiTestCase() {
        gestureRecognizer.addGestureStateCallback { gestureState = it }
    }

    @Test
    fun triggersGestureFinishedForThreeFingerGestureUp() {
        assertStateAfterEvents(events = ThreeFingerGesture.swipeUp(), expectedState = Finished)
    }

    @Test
    fun doesntTriggerGestureFinished_onGestureSpeedTooSlow() {
        velocityTracker.setVelocity(Velocity(SLOW))
        assertStateAfterEvents(events = ThreeFingerGesture.swipeUp(), expectedState = NotStarted)
    }

    @Test
    fun triggersGestureProgressForThreeFingerGestureStarted() {
        assertStateAfterEvents(
            events = ThreeFingerGesture.startEvents(x = 0f, y = 0f),
            expectedState = InProgress(),
        )
    }

    @Test
    fun triggersProgressRelativeToDistance() {
        assertProgressWhileMovingFingers(deltaY = -SWIPE_DISTANCE / 2, expectedProgress = 0.5f)
        assertProgressWhileMovingFingers(deltaY = -SWIPE_DISTANCE, expectedProgress = 1f)
    }

    private fun assertProgressWhileMovingFingers(deltaY: Float, expectedProgress: Float) {
        assertStateAfterEvents(
            events = ThreeFingerGesture.eventsForGestureInProgress { move(deltaY = deltaY) },
            expectedState = InProgress(progress = expectedProgress),
        )
    }

    @Test
    fun triggeredProgressIsBetweenZeroAndOne() {
        // going in the wrong direction
@@ -96,31 +75,13 @@ class HomeGestureRecognizerTest : SysuiTestCase() {
        assertProgressWhileMovingFingers(deltaY = -SWIPE_DISTANCE * 2, expectedProgress = 1f)
    }

    @Test
    fun doesntTriggerGestureFinished_onGestureDistanceTooShort() {
    private fun assertProgressWhileMovingFingers(deltaY: Float, expectedProgress: Float) {
        assertStateAfterEvents(
            events = ThreeFingerGesture.swipeUp(distancePx = SWIPE_DISTANCE / 2),
            expectedState = NotStarted,
            events = ThreeFingerGesture.eventsForGestureInProgress { move(deltaY = deltaY) },
            expectedState = InProgress(progress = expectedProgress),
        )
    }

    @Test
    fun doesntTriggerGestureFinished_onThreeFingersSwipeInOtherDirections() {
        assertStateAfterEvents(events = ThreeFingerGesture.swipeDown(), expectedState = NotStarted)
        assertStateAfterEvents(events = ThreeFingerGesture.swipeLeft(), expectedState = NotStarted)
        assertStateAfterEvents(events = ThreeFingerGesture.swipeRight(), expectedState = NotStarted)
    }

    @Test
    fun doesntTriggerGestureFinished_onTwoFingersSwipe() {
        assertStateAfterEvents(events = TwoFingerGesture.swipeUp(), expectedState = NotStarted)
    }

    @Test
    fun doesntTriggerGestureFinished_onFourFingersSwipe() {
        assertStateAfterEvents(events = FourFingerGesture.swipeUp(), expectedState = NotStarted)
    }

    private fun assertStateAfterEvents(events: List<MotionEvent>, expectedState: GestureState) {
        events.forEach { gestureRecognizer.accept(it) }
        assertThat(gestureState).isEqualTo(expectedState)
+0 −39
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.testKosmos
import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.Finished
import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.InProgress
import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.NotStarted
import com.android.systemui.touchpad.tutorial.ui.gesture.MultiFingerGesture.Companion.SWIPE_DISTANCE
@@ -57,25 +56,12 @@ class RecentAppsGestureRecognizerTest : SysuiTestCase() {
        gestureRecognizer.addGestureStateCallback { gestureState = it }
    }

    @Test
    fun triggersGestureFinishedForThreeFingerGestureUp() {
        assertStateAfterEvents(events = ThreeFingerGesture.swipeUp(), expectedState = Finished)
    }

    @Test
    fun doesntTriggerGestureFinished_onGestureSpeedTooHigh() {
        velocityTracker.setVelocity(Velocity(FAST))
        assertStateAfterEvents(events = ThreeFingerGesture.swipeUp(), expectedState = NotStarted)
    }

    @Test
    fun triggersGestureProgressForThreeFingerGestureStarted() {
        assertStateAfterEvents(
            events = ThreeFingerGesture.startEvents(x = 0f, y = 0f),
            expectedState = InProgress(progress = 0f),
        )
    }

    @Test
    fun triggersProgressRelativeToDistance() {
        assertProgressWhileMovingFingers(deltaY = -SWIPE_DISTANCE / 2, expectedProgress = 0.5f)
@@ -97,31 +83,6 @@ class RecentAppsGestureRecognizerTest : SysuiTestCase() {
        assertProgressWhileMovingFingers(deltaY = -SWIPE_DISTANCE * 2, expectedProgress = 1f)
    }

    @Test
    fun doesntTriggerGestureFinished_onGestureDistanceTooShort() {
        assertStateAfterEvents(
            events = ThreeFingerGesture.swipeUp(distancePx = SWIPE_DISTANCE / 2),
            expectedState = NotStarted,
        )
    }

    @Test
    fun doesntTriggerGestureFinished_onThreeFingersSwipeInOtherDirections() {
        assertStateAfterEvents(events = ThreeFingerGesture.swipeDown(), expectedState = NotStarted)
        assertStateAfterEvents(events = ThreeFingerGesture.swipeLeft(), expectedState = NotStarted)
        assertStateAfterEvents(events = ThreeFingerGesture.swipeRight(), expectedState = NotStarted)
    }

    @Test
    fun doesntTriggerGestureFinished_onTwoFingersSwipe() {
        assertStateAfterEvents(events = TwoFingerGesture.swipeUp(), expectedState = NotStarted)
    }

    @Test
    fun doesntTriggerGestureFinished_onFourFingersSwipe() {
        assertStateAfterEvents(events = FourFingerGesture.swipeUp(), expectedState = NotStarted)
    }

    private fun assertStateAfterEvents(events: List<MotionEvent>, expectedState: GestureState) {
        events.forEach { gestureRecognizer.accept(it) }
        assertThat(gestureState).isEqualTo(expectedState)
+153 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

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

import android.view.MotionEvent
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.Finished
import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.InProgress
import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.NotStarted
import com.android.systemui.touchpad.tutorial.ui.gesture.MultiFingerGesture.Companion.SWIPE_DISTANCE
import com.android.systemui.touchpad.tutorial.ui.gesture.RecentAppsGestureRecognizerTest.Companion.FAST
import com.android.systemui.touchpad.tutorial.ui.gesture.RecentAppsGestureRecognizerTest.Companion.SLOW
import com.android.systemui.touchpad.tutorial.ui.gesture.RecentAppsGestureRecognizerTest.Companion.THRESHOLD_VELOCITY_PX_PER_MS
import com.android.systemui.touchpad.ui.gesture.FakeVelocityTracker
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import platform.test.runner.parameterized.ParameterizedAndroidJunit4
import platform.test.runner.parameterized.Parameters

@SmallTest
@RunWith(ParameterizedAndroidJunit4::class)
class ThreeFingerGestureRecognizerTest(
    private val recognizer: GestureRecognizer,
    private val validGestures: Set<List<MotionEvent>>,
    private val tooShortGesture: List<MotionEvent>,
    @Suppress("UNUSED_PARAMETER") testSuffix: String, // here just for nicer test names
) : SysuiTestCase() {

    private var gestureState: GestureState = GestureState.NotStarted

    @Before
    fun before() {
        recognizer.addGestureStateCallback { gestureState = it }
    }

    @Test
    fun triggersGestureFinishedForValidGestures() {
        validGestures.forEach { assertStateAfterEvents(events = it, expectedState = Finished) }
    }

    @Test
    fun triggersGestureProgressForThreeFingerGestureStarted() {
        assertStateAfterEvents(
            events = ThreeFingerGesture.startEvents(x = 0f, y = 0f),
            expectedState = InProgress(progress = 0f),
        )
    }

    @Test
    fun doesntTriggerGestureFinished_onGestureDistanceTooShort() {
        assertStateAfterEvents(events = tooShortGesture, expectedState = NotStarted)
    }

    @Test
    fun doesntTriggerGestureFinished_onThreeFingersSwipeInOtherDirections() {
        val allThreeFingerGestures =
            listOf(
                ThreeFingerGesture.swipeUp(),
                ThreeFingerGesture.swipeDown(),
                ThreeFingerGesture.swipeLeft(),
                ThreeFingerGesture.swipeRight(),
            )
        val invalidGestures = allThreeFingerGestures.filter { it.differentFromAnyOf(validGestures) }
        invalidGestures.forEach { assertStateAfterEvents(events = it, expectedState = NotStarted) }
    }

    @Test
    fun doesntTriggerGestureFinished_onTwoFingersSwipe() {
        assertStateAfterEvents(events = TwoFingerGesture.swipeRight(), expectedState = NotStarted)
    }

    @Test
    fun doesntTriggerGestureFinished_onFourFingersSwipe() {
        assertStateAfterEvents(events = FourFingerGesture.swipeRight(), expectedState = NotStarted)
    }

    private fun assertStateAfterEvents(events: List<MotionEvent>, expectedState: GestureState) {
        events.forEach { recognizer.accept(it) }
        assertThat(gestureState).isEqualTo(expectedState)
    }

    companion object {
        @JvmStatic
        @Parameters(name = "{3}")
        fun gesturesToTest(): List<Array<Any>> =
            with(ThreeFingerGesture) {
                listOf(
                        GestureTestData(
                            recognizer = BackGestureRecognizer(SWIPE_DISTANCE.toInt()),
                            validGestures = setOf(swipeRight(), swipeLeft()),
                            tooShortGesture = swipeRight(SWIPE_DISTANCE / 2),
                            testSuffix = "back gesture",
                        ),
                        GestureTestData(
                            recognizer =
                                HomeGestureRecognizer(
                                    SWIPE_DISTANCE.toInt(),
                                    THRESHOLD_VELOCITY_PX_PER_MS,
                                    FakeVelocityTracker(velocity = FAST),
                                ),
                            validGestures = setOf(swipeUp()),
                            tooShortGesture = swipeUp(SWIPE_DISTANCE / 2),
                            testSuffix = "home gesture",
                        ),
                        GestureTestData(
                            recognizer =
                                RecentAppsGestureRecognizer(
                                    SWIPE_DISTANCE.toInt(),
                                    THRESHOLD_VELOCITY_PX_PER_MS,
                                    FakeVelocityTracker(velocity = SLOW),
                                ),
                            validGestures = setOf(swipeUp()),
                            tooShortGesture = swipeUp(SWIPE_DISTANCE / 2),
                            testSuffix = "recent apps gesture",
                        ),
                    )
                    .map {
                        arrayOf(it.recognizer, it.validGestures, it.tooShortGesture, it.testSuffix)
                    }
            }
    }

    class GestureTestData(
        val recognizer: GestureRecognizer,
        val validGestures: Set<List<MotionEvent>>,
        val tooShortGesture: List<MotionEvent>,
        val testSuffix: String,
    )
}

private fun List<MotionEvent>.differentFromAnyOf(validGestures: Set<List<MotionEvent>>): Boolean {
    // comparing MotionEvents is really hard so let's just compare their positions
    val positions = this.map { it.x to it.y }
    val validGesturesPositions = validGestures.map { gesture -> gesture.map { it.x to it.y } }
    return !validGesturesPositions.contains(positions)
}
+2 −2
Original line number Diff line number Diff line
@@ -20,9 +20,9 @@ import android.view.MotionEvent
import com.android.systemui.touchpad.tutorial.ui.gesture.Velocity
import com.android.systemui.touchpad.tutorial.ui.gesture.VelocityTracker

class FakeVelocityTracker : VelocityTracker {
class FakeVelocityTracker(velocity: Float = 0f) : VelocityTracker {

    private var fakeVelocity = Velocity(0f)
    private var fakeVelocity = Velocity(velocity)

    override fun calculateVelocity(): Velocity {
        return fakeVelocity