From 63a913d7928afb99320f2f2dd6fc968b48d595a4 Mon Sep 17 00:00:00 2001 From: Michal Brzezinski Date: Fri, 11 Oct 2024 11:44:35 +0100 Subject: Renaming TouchpadGestureMonitor to GestureRecognizer And other changes are just consequence of that: renaming all its subclasses, field names etc Bug: 369817369 Test: All tests are passing Flag: com.android.systemui.shared.new_touchpad_gestures_tutorial Change-Id: I48e278e43d83258b5f6e26062747d9fe0b9ca9b5 --- .../tutorial/ui/gesture/BackGestureMonitorTest.kt | 91 ----------------- .../ui/gesture/BackGestureRecognizerTest.kt | 91 +++++++++++++++++ .../tutorial/ui/gesture/EasterEggGestureTest.kt | 2 +- .../tutorial/ui/gesture/HomeGestureMonitorTest.kt | 87 ---------------- .../ui/gesture/HomeGestureRecognizerTest.kt | 87 ++++++++++++++++ .../ui/gesture/RecentAppsGestureMonitorTest.kt | 113 --------------------- .../ui/gesture/RecentAppsGestureRecognizerTest.kt | 113 +++++++++++++++++++++ .../ui/gesture/TouchpadGestureHandlerTest.kt | 8 +- .../ui/composable/BackGestureTutorialScreen.kt | 12 +-- .../ui/composable/GestureTutorialScreen.kt | 30 +++--- .../ui/composable/HomeGestureTutorialScreen.kt | 12 +-- .../composable/RecentAppsGestureTutorialScreen.kt | 19 ++-- .../tutorial/ui/gesture/BackGestureMonitor.kt | 42 -------- .../tutorial/ui/gesture/BackGestureRecognizer.kt | 42 ++++++++ .../tutorial/ui/gesture/GestureRecognizer.kt | 38 +++++++ .../tutorial/ui/gesture/HomeGestureMonitor.kt | 41 -------- .../tutorial/ui/gesture/HomeGestureRecognizer.kt | 41 ++++++++ .../ui/gesture/RecentAppsGestureMonitor.kt | 55 ---------- .../ui/gesture/RecentAppsGestureRecognizer.kt | 55 ++++++++++ .../tutorial/ui/gesture/TouchpadGestureHandler.kt | 4 +- .../tutorial/ui/gesture/TouchpadGestureMonitor.kt | 38 ------- 21 files changed, 510 insertions(+), 511 deletions(-) delete mode 100644 packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureMonitorTest.kt create mode 100644 packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureRecognizerTest.kt delete mode 100644 packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureMonitorTest.kt create mode 100644 packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureRecognizerTest.kt delete mode 100644 packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureMonitorTest.kt create mode 100644 packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureRecognizerTest.kt delete mode 100644 packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureMonitor.kt create mode 100644 packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureRecognizer.kt create mode 100644 packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/GestureRecognizer.kt delete mode 100644 packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureMonitor.kt create mode 100644 packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureRecognizer.kt delete mode 100644 packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureMonitor.kt create mode 100644 packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureRecognizer.kt delete mode 100644 packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGestureMonitor.kt diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureMonitorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureMonitorTest.kt deleted file mode 100644 index cd18925eb44f..000000000000 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureMonitorTest.kt +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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.ext.junit.runners.AndroidJUnit4 -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.google.common.truth.Truth.assertThat -import org.junit.Before -import org.junit.Test -import org.junit.runner.RunWith - -@SmallTest -@RunWith(AndroidJUnit4::class) -class BackGestureMonitorTest : SysuiTestCase() { - - private var gestureState: GestureState = NotStarted - private val gestureMonitor = - BackGestureMonitor(gestureDistanceThresholdPx = SWIPE_DISTANCE.toInt()) - - @Before - fun before() { - gestureMonitor.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 doesntTriggerGestureFinished_onGestureDistanceTooShort() { - assertStateAfterEvents( - events = ThreeFingerGesture.swipeLeft(distancePx = SWIPE_DISTANCE / 2), - expectedState = NotStarted, - ) - } - - @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, expectedState: GestureState) { - events.forEach { gestureMonitor.accept(it) } - assertThat(gestureState).isEqualTo(expectedState) - } -} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureRecognizerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureRecognizerTest.kt new file mode 100644 index 000000000000..40c3f221e2df --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureRecognizerTest.kt @@ -0,0 +1,91 @@ +/* + * 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.ext.junit.runners.AndroidJUnit4 +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.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith + +@SmallTest +@RunWith(AndroidJUnit4::class) +class BackGestureRecognizerTest : SysuiTestCase() { + + private var gestureState: GestureState = NotStarted + private val gestureRecognizer = + BackGestureRecognizer(gestureDistanceThresholdPx = SWIPE_DISTANCE.toInt()) + + @Before + fun before() { + 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 doesntTriggerGestureFinished_onGestureDistanceTooShort() { + assertStateAfterEvents( + events = ThreeFingerGesture.swipeLeft(distancePx = SWIPE_DISTANCE / 2), + expectedState = NotStarted, + ) + } + + @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, expectedState: GestureState) { + events.forEach { gestureRecognizer.accept(it) } + assertThat(gestureState).isEqualTo(expectedState) + } +} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/EasterEggGestureTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/EasterEggGestureTest.kt index 3f1633a8972f..8406d3b99bac 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/EasterEggGestureTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/EasterEggGestureTest.kt @@ -36,7 +36,7 @@ class EasterEggGestureTest : SysuiTestCase() { private var triggered = false private val handler = TouchpadGestureHandler( - BackGestureMonitor(gestureDistanceThresholdPx = SWIPE_DISTANCE.toInt()), + BackGestureRecognizer(gestureDistanceThresholdPx = SWIPE_DISTANCE.toInt()), EasterEggGestureMonitor(callback = { triggered = true }), ) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureMonitorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureMonitorTest.kt deleted file mode 100644 index edf0e5698bf0..000000000000 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureMonitorTest.kt +++ /dev/null @@ -1,87 +0,0 @@ -/* - * 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.ext.junit.runners.AndroidJUnit4 -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.google.common.truth.Truth.assertThat -import org.junit.Before -import org.junit.Test -import org.junit.runner.RunWith - -@SmallTest -@RunWith(AndroidJUnit4::class) -class HomeGestureMonitorTest : SysuiTestCase() { - - private var gestureState: GestureState = GestureState.NotStarted - private val gestureMonitor = - HomeGestureMonitor(gestureDistanceThresholdPx = SWIPE_DISTANCE.toInt()) - - @Before - fun before() { - gestureMonitor.addGestureStateCallback { gestureState = it } - } - - @Test - fun triggersGestureFinishedForThreeFingerGestureUp() { - assertStateAfterEvents(events = ThreeFingerGesture.swipeUp(), expectedState = Finished) - } - - @Test - fun triggersGestureProgressForThreeFingerGestureStarted() { - assertStateAfterEvents( - events = ThreeFingerGesture.startEvents(x = 0f, y = 0f), - expectedState = InProgress(), - ) - } - - @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, expectedState: GestureState) { - events.forEach { gestureMonitor.accept(it) } - assertThat(gestureState).isEqualTo(expectedState) - } -} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureRecognizerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureRecognizerTest.kt new file mode 100644 index 000000000000..043b77577978 --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureRecognizerTest.kt @@ -0,0 +1,87 @@ +/* + * 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.ext.junit.runners.AndroidJUnit4 +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.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith + +@SmallTest +@RunWith(AndroidJUnit4::class) +class HomeGestureRecognizerTest : SysuiTestCase() { + + private var gestureState: GestureState = GestureState.NotStarted + private val gestureRecognizer = + HomeGestureRecognizer(gestureDistanceThresholdPx = SWIPE_DISTANCE.toInt()) + + @Before + fun before() { + gestureRecognizer.addGestureStateCallback { gestureState = it } + } + + @Test + fun triggersGestureFinishedForThreeFingerGestureUp() { + assertStateAfterEvents(events = ThreeFingerGesture.swipeUp(), expectedState = Finished) + } + + @Test + fun triggersGestureProgressForThreeFingerGestureStarted() { + assertStateAfterEvents( + events = ThreeFingerGesture.startEvents(x = 0f, y = 0f), + expectedState = InProgress(), + ) + } + + @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, expectedState: GestureState) { + events.forEach { gestureRecognizer.accept(it) } + assertThat(gestureState).isEqualTo(expectedState) + } +} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureMonitorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureMonitorTest.kt deleted file mode 100644 index f68e7732d04e..000000000000 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureMonitorTest.kt +++ /dev/null @@ -1,113 +0,0 @@ -/* - * 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.compose.ui.input.pointer.util.VelocityTracker1D -import androidx.test.ext.junit.runners.AndroidJUnit4 -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.google.common.truth.Truth.assertThat -import org.junit.Before -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.kotlin.doReturn -import org.mockito.kotlin.mock -import org.mockito.kotlin.whenever - -@SmallTest -@RunWith(AndroidJUnit4::class) -class RecentAppsGestureMonitorTest : SysuiTestCase() { - - companion object { - const val THRESHOLD_VELOCITY_PX_PER_MS = 0.1f - // multiply by 1000 to get px/ms instead of px/s which is unit used by velocity tracker - const val SLOW = THRESHOLD_VELOCITY_PX_PER_MS * 1000 - 1 - const val FAST = THRESHOLD_VELOCITY_PX_PER_MS * 1000 + 1 - } - - private var gestureState: GestureState = GestureState.NotStarted - private val velocityTracker1D = - mock { - // by default return correct speed for the gesture - as if pointer is slowing down - on { calculateVelocity() } doReturn SLOW - } - private val gestureMonitor = - RecentAppsGestureMonitor( - gestureDistanceThresholdPx = SWIPE_DISTANCE.toInt(), - velocityThresholdPxPerMs = THRESHOLD_VELOCITY_PX_PER_MS, - velocityTracker = VerticalVelocityTracker(velocityTracker1D), - ) - - @Before - fun before() { - gestureMonitor.addGestureStateCallback { gestureState = it } - } - - @Test - fun triggersGestureFinishedForThreeFingerGestureUp() { - assertStateAfterEvents(events = ThreeFingerGesture.swipeUp(), expectedState = Finished) - } - - @Test - fun doesntTriggerGestureFinished_onGestureSpeedTooHigh() { - whenever(velocityTracker1D.calculateVelocity()).thenReturn(FAST) - assertStateAfterEvents(events = ThreeFingerGesture.swipeUp(), expectedState = NotStarted) - } - - @Test - fun triggersGestureProgressForThreeFingerGestureStarted() { - assertStateAfterEvents( - events = ThreeFingerGesture.startEvents(x = 0f, y = 0f), - expectedState = InProgress(), - ) - } - - @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, expectedState: GestureState) { - events.forEach { gestureMonitor.accept(it) } - assertThat(gestureState).isEqualTo(expectedState) - } -} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureRecognizerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureRecognizerTest.kt new file mode 100644 index 000000000000..7095a91a4e5d --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureRecognizerTest.kt @@ -0,0 +1,113 @@ +/* + * 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.compose.ui.input.pointer.util.VelocityTracker1D +import androidx.test.ext.junit.runners.AndroidJUnit4 +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.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.kotlin.doReturn +import org.mockito.kotlin.mock +import org.mockito.kotlin.whenever + +@SmallTest +@RunWith(AndroidJUnit4::class) +class RecentAppsGestureRecognizerTest : SysuiTestCase() { + + companion object { + const val THRESHOLD_VELOCITY_PX_PER_MS = 0.1f + // multiply by 1000 to get px/ms instead of px/s which is unit used by velocity tracker + const val SLOW = THRESHOLD_VELOCITY_PX_PER_MS * 1000 - 1 + const val FAST = THRESHOLD_VELOCITY_PX_PER_MS * 1000 + 1 + } + + private var gestureState: GestureState = GestureState.NotStarted + private val velocityTracker1D = + mock { + // by default return correct speed for the gesture - as if pointer is slowing down + on { calculateVelocity() } doReturn SLOW + } + private val gestureRecognizer = + RecentAppsGestureRecognizer( + gestureDistanceThresholdPx = SWIPE_DISTANCE.toInt(), + velocityThresholdPxPerMs = THRESHOLD_VELOCITY_PX_PER_MS, + velocityTracker = VerticalVelocityTracker(velocityTracker1D), + ) + + @Before + fun before() { + gestureRecognizer.addGestureStateCallback { gestureState = it } + } + + @Test + fun triggersGestureFinishedForThreeFingerGestureUp() { + assertStateAfterEvents(events = ThreeFingerGesture.swipeUp(), expectedState = Finished) + } + + @Test + fun doesntTriggerGestureFinished_onGestureSpeedTooHigh() { + whenever(velocityTracker1D.calculateVelocity()).thenReturn(FAST) + assertStateAfterEvents(events = ThreeFingerGesture.swipeUp(), expectedState = NotStarted) + } + + @Test + fun triggersGestureProgressForThreeFingerGestureStarted() { + assertStateAfterEvents( + events = ThreeFingerGesture.startEvents(x = 0f, y = 0f), + expectedState = InProgress(), + ) + } + + @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, expectedState: GestureState) { + events.forEach { gestureRecognizer.accept(it) } + assertThat(gestureState).isEqualTo(expectedState) + } +} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGestureHandlerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGestureHandlerTest.kt index 9f7ea679b822..a867eb38b44c 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGestureHandlerTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGestureHandlerTest.kt @@ -36,13 +36,13 @@ import org.junit.runner.RunWith class TouchpadGestureHandlerTest : SysuiTestCase() { private var gestureState: GestureState = GestureState.NotStarted - private val gestureMonitor = - BackGestureMonitor(gestureDistanceThresholdPx = SWIPE_DISTANCE.toInt()) - private val handler = TouchpadGestureHandler(gestureMonitor, EasterEggGestureMonitor {}) + private val gestureRecognizer = + BackGestureRecognizer(gestureDistanceThresholdPx = SWIPE_DISTANCE.toInt()) + private val handler = TouchpadGestureHandler(gestureRecognizer, EasterEggGestureMonitor {}) @Before fun before() { - gestureMonitor.addGestureStateCallback { gestureState = it } + gestureRecognizer.addGestureStateCallback { gestureState = it } } @Test diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt index a3c757a6ce9c..0cb3a6e60041 100644 --- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt +++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt @@ -23,7 +23,7 @@ import com.android.compose.theme.LocalAndroidColorScheme import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialScreenConfig import com.android.systemui.inputdevice.tutorial.ui.composable.rememberColorFilterProperty import com.android.systemui.res.R -import com.android.systemui.touchpad.tutorial.ui.gesture.BackGestureMonitor +import com.android.systemui.touchpad.tutorial.ui.gesture.BackGestureRecognizer @Composable fun BackGestureTutorialScreen(onDoneButtonClicked: () -> Unit, onBack: () -> Unit) { @@ -43,15 +43,15 @@ fun BackGestureTutorialScreen(onDoneButtonClicked: () -> Unit, onBack: () -> Uni successResId = R.raw.trackpad_back_success, ), ) - val gestureMonitorProvider = - DistanceBasedGestureMonitorProvider( - monitorFactory = { distanceThresholdPx, gestureStateCallback -> - BackGestureMonitor(distanceThresholdPx).also { + val gestureRecognizerProvider = + DistanceBasedGestureRecognizerProvider( + recognizerFactory = { distanceThresholdPx, gestureStateCallback -> + BackGestureRecognizer(distanceThresholdPx).also { it.addGestureStateCallback(gestureStateCallback) } } ) - GestureTutorialScreen(screenConfig, gestureMonitorProvider, onDoneButtonClicked, onBack) + GestureTutorialScreen(screenConfig, gestureRecognizerProvider, onDoneButtonClicked, onBack) } @Composable diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/GestureTutorialScreen.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/GestureTutorialScreen.kt index 72389cd45fe0..75c66f234bdc 100644 --- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/GestureTutorialScreen.kt +++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/GestureTutorialScreen.kt @@ -37,39 +37,39 @@ import com.android.systemui.inputdevice.tutorial.ui.composable.ActionTutorialCon import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialActionState import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialScreenConfig import com.android.systemui.touchpad.tutorial.ui.gesture.EasterEggGestureMonitor +import com.android.systemui.touchpad.tutorial.ui.gesture.GestureRecognizer import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState 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.TouchpadGestureHandler -import com.android.systemui.touchpad.tutorial.ui.gesture.TouchpadGestureMonitor -interface GestureMonitorProvider { +interface GestureRecognizerProvider { @Composable - fun rememberGestureMonitor( + fun rememberGestureRecognizer( resources: Resources, gestureStateChangedCallback: (GestureState) -> Unit, - ): TouchpadGestureMonitor + ): GestureRecognizer } typealias gestureStateCallback = (GestureState) -> Unit -class DistanceBasedGestureMonitorProvider( - val monitorFactory: (Int, gestureStateCallback) -> TouchpadGestureMonitor -) : GestureMonitorProvider { +class DistanceBasedGestureRecognizerProvider( + val recognizerFactory: (Int, gestureStateCallback) -> GestureRecognizer +) : GestureRecognizerProvider { @Composable - override fun rememberGestureMonitor( + override fun rememberGestureRecognizer( resources: Resources, gestureStateChangedCallback: (GestureState) -> Unit, - ): TouchpadGestureMonitor { + ): GestureRecognizer { val distanceThresholdPx = resources.getDimensionPixelSize( com.android.internal.R.dimen.system_gestures_distance_threshold ) return remember(distanceThresholdPx) { - monitorFactory(distanceThresholdPx, gestureStateChangedCallback) + recognizerFactory(distanceThresholdPx, gestureStateChangedCallback) } } } @@ -77,7 +77,7 @@ class DistanceBasedGestureMonitorProvider( fun GestureState.toTutorialActionState(): TutorialActionState { return when (this) { NotStarted -> TutorialActionState.NotStarted - is InProgress -> TutorialActionState.InProgress() + is InProgress -> TutorialActionState.InProgress(progress) Finished -> TutorialActionState.Finished } } @@ -85,21 +85,21 @@ fun GestureState.toTutorialActionState(): TutorialActionState { @Composable fun GestureTutorialScreen( screenConfig: TutorialScreenConfig, - gestureMonitorProvider: GestureMonitorProvider, + gestureRecognizerProvider: GestureRecognizerProvider, onDoneButtonClicked: () -> Unit, onBack: () -> Unit, ) { BackHandler(onBack = onBack) var gestureState: GestureState by remember { mutableStateOf(NotStarted) } var easterEggTriggered by remember { mutableStateOf(false) } - val gestureMonitor = - gestureMonitorProvider.rememberGestureMonitor( + val gestureRecognizer = + gestureRecognizerProvider.rememberGestureRecognizer( resources = LocalContext.current.resources, gestureStateChangedCallback = { gestureState = it }, ) val easterEggMonitor = EasterEggGestureMonitor { easterEggTriggered = true } val gestureHandler = - remember(gestureMonitor) { TouchpadGestureHandler(gestureMonitor, easterEggMonitor) } + remember(gestureRecognizer) { TouchpadGestureHandler(gestureRecognizer, easterEggMonitor) } TouchpadGesturesHandlingBox( gestureHandler, gestureState, diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/HomeGestureTutorialScreen.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/HomeGestureTutorialScreen.kt index a55fa442cd96..69ec59878b14 100644 --- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/HomeGestureTutorialScreen.kt +++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/HomeGestureTutorialScreen.kt @@ -23,7 +23,7 @@ import com.android.compose.theme.LocalAndroidColorScheme import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialScreenConfig import com.android.systemui.inputdevice.tutorial.ui.composable.rememberColorFilterProperty import com.android.systemui.res.R -import com.android.systemui.touchpad.tutorial.ui.gesture.HomeGestureMonitor +import com.android.systemui.touchpad.tutorial.ui.gesture.HomeGestureRecognizer @Composable fun HomeGestureTutorialScreen(onDoneButtonClicked: () -> Unit, onBack: () -> Unit) { @@ -43,15 +43,15 @@ fun HomeGestureTutorialScreen(onDoneButtonClicked: () -> Unit, onBack: () -> Uni successResId = R.raw.trackpad_home_success, ), ) - val gestureMonitorProvider = - DistanceBasedGestureMonitorProvider( - monitorFactory = { distanceThresholdPx, gestureStateCallback -> - HomeGestureMonitor(distanceThresholdPx).also { + val gestureRecognizerProvider = + DistanceBasedGestureRecognizerProvider( + recognizerFactory = { distanceThresholdPx, gestureStateCallback -> + HomeGestureRecognizer(distanceThresholdPx).also { it.addGestureStateCallback(gestureStateCallback) } } ) - GestureTutorialScreen(screenConfig, gestureMonitorProvider, onDoneButtonClicked, onBack) + GestureTutorialScreen(screenConfig, gestureRecognizerProvider, onDoneButtonClicked, onBack) } @Composable diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/RecentAppsGestureTutorialScreen.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/RecentAppsGestureTutorialScreen.kt index 6ee15aa952f4..3097a18b33d6 100644 --- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/RecentAppsGestureTutorialScreen.kt +++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/RecentAppsGestureTutorialScreen.kt @@ -24,9 +24,9 @@ import com.android.compose.theme.LocalAndroidColorScheme import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialScreenConfig import com.android.systemui.inputdevice.tutorial.ui.composable.rememberColorFilterProperty import com.android.systemui.res.R +import com.android.systemui.touchpad.tutorial.ui.gesture.GestureRecognizer import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState -import com.android.systemui.touchpad.tutorial.ui.gesture.RecentAppsGestureMonitor -import com.android.systemui.touchpad.tutorial.ui.gesture.TouchpadGestureMonitor +import com.android.systemui.touchpad.tutorial.ui.gesture.RecentAppsGestureRecognizer @Composable fun RecentAppsGestureTutorialScreen(onDoneButtonClicked: () -> Unit, onBack: () -> Unit) { @@ -46,13 +46,13 @@ fun RecentAppsGestureTutorialScreen(onDoneButtonClicked: () -> Unit, onBack: () successResId = R.raw.trackpad_recent_apps_success, ), ) - val gestureMonitorProvider = - object : GestureMonitorProvider { + val gestureRecognizerProvider = + object : GestureRecognizerProvider { @Composable - override fun rememberGestureMonitor( + override fun rememberGestureRecognizer( resources: Resources, gestureStateChangedCallback: (GestureState) -> Unit, - ): TouchpadGestureMonitor { + ): GestureRecognizer { val distanceThresholdPx = resources.getDimensionPixelSize( com.android.internal.R.dimen.system_gestures_distance_threshold @@ -60,13 +60,12 @@ fun RecentAppsGestureTutorialScreen(onDoneButtonClicked: () -> Unit, onBack: () val velocityThresholdPxPerMs = resources.getDimension(R.dimen.touchpad_recent_apps_gesture_velocity_threshold) return remember(distanceThresholdPx, velocityThresholdPxPerMs) { - RecentAppsGestureMonitor(distanceThresholdPx, velocityThresholdPxPerMs).also { - it.addGestureStateCallback(gestureStateChangedCallback) - } + RecentAppsGestureRecognizer(distanceThresholdPx, velocityThresholdPxPerMs) + .also { it.addGestureStateCallback(gestureStateChangedCallback) } } } } - GestureTutorialScreen(screenConfig, gestureMonitorProvider, onDoneButtonClicked, onBack) + GestureTutorialScreen(screenConfig, gestureRecognizerProvider, onDoneButtonClicked, onBack) } @Composable diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureMonitor.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureMonitor.kt deleted file mode 100644 index 490f04d55802..000000000000 --- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureMonitor.kt +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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 kotlin.math.abs - -/** Monitors for touchpad back gesture, that is three fingers swiping left or right */ -class BackGestureMonitor(private val gestureDistanceThresholdPx: Int) : TouchpadGestureMonitor { - - private val distanceTracker = DistanceTracker() - private var gestureStateChangedCallback: (GestureState) -> Unit = {} - - override fun addGestureStateCallback(callback: (GestureState) -> Unit) { - gestureStateChangedCallback = callback - } - - override fun accept(event: MotionEvent) { - if (!isThreeFingerTouchpadSwipe(event)) return - val gestureState = distanceTracker.processEvent(event) - updateGestureState( - gestureStateChangedCallback, - gestureState, - isFinished = { abs(it.deltaX) >= gestureDistanceThresholdPx }, - progress = { 0f }, - ) - } -} diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureRecognizer.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureRecognizer.kt new file mode 100644 index 000000000000..56e97a357d67 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureRecognizer.kt @@ -0,0 +1,42 @@ +/* + * 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 kotlin.math.abs + +/** Recognizes touchpad back gesture, that is three fingers swiping left or right */ +class BackGestureRecognizer(private val gestureDistanceThresholdPx: Int) : GestureRecognizer { + + private val distanceTracker = DistanceTracker() + private var gestureStateChangedCallback: (GestureState) -> Unit = {} + + override fun addGestureStateCallback(callback: (GestureState) -> Unit) { + gestureStateChangedCallback = callback + } + + override fun accept(event: MotionEvent) { + if (!isThreeFingerTouchpadSwipe(event)) return + val gestureState = distanceTracker.processEvent(event) + updateGestureState( + gestureStateChangedCallback, + gestureState, + isFinished = { abs(it.deltaX) >= gestureDistanceThresholdPx }, + progress = { 0f }, + ) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/GestureRecognizer.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/GestureRecognizer.kt new file mode 100644 index 000000000000..d146268304a6 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/GestureRecognizer.kt @@ -0,0 +1,38 @@ +/* + * 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 java.util.function.Consumer + +/** Based on passed [MotionEvent]s recognizes different states of gesture and notifies callback. */ +interface GestureRecognizer : Consumer { + fun addGestureStateCallback(callback: (GestureState) -> Unit) +} + +fun isThreeFingerTouchpadSwipe(event: MotionEvent) = isNFingerTouchpadSwipe(event, fingerCount = 3) + +fun isFourFingerTouchpadSwipe(event: MotionEvent) = isNFingerTouchpadSwipe(event, fingerCount = 4) + +private fun isNFingerTouchpadSwipe(event: MotionEvent, fingerCount: Int): Boolean { + return event.classification == MotionEvent.CLASSIFICATION_MULTI_FINGER_SWIPE && + event.getAxisValue(MotionEvent.AXIS_GESTURE_SWIPE_FINGER_COUNT) == fingerCount.toFloat() +} + +fun isTwoFingerSwipe(event: MotionEvent): Boolean { + return event.classification == MotionEvent.CLASSIFICATION_TWO_FINGER_SWIPE +} diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureMonitor.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureMonitor.kt deleted file mode 100644 index 83d4f566257b..000000000000 --- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureMonitor.kt +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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 - -/** Monitors for touchpad home gesture, that is three fingers swiping up */ -class HomeGestureMonitor(private val gestureDistanceThresholdPx: Int) : TouchpadGestureMonitor { - - private val distanceTracker = DistanceTracker() - private var gestureStateChangedCallback: (GestureState) -> Unit = {} - - override fun addGestureStateCallback(callback: (GestureState) -> Unit) { - gestureStateChangedCallback = callback - } - - override fun accept(event: MotionEvent) { - if (!isThreeFingerTouchpadSwipe(event)) return - val gestureState = distanceTracker.processEvent(event) - updateGestureState( - gestureStateChangedCallback, - gestureState, - isFinished = { -it.deltaY >= gestureDistanceThresholdPx }, - progress = { 0f }, - ) - } -} diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureRecognizer.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureRecognizer.kt new file mode 100644 index 000000000000..3db9d7ccc8f7 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureRecognizer.kt @@ -0,0 +1,41 @@ +/* + * 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 + +/** Recognizes touchpad home gesture, that is three fingers swiping up */ +class HomeGestureRecognizer(private val gestureDistanceThresholdPx: Int) : GestureRecognizer { + + private val distanceTracker = DistanceTracker() + private var gestureStateChangedCallback: (GestureState) -> Unit = {} + + override fun addGestureStateCallback(callback: (GestureState) -> Unit) { + gestureStateChangedCallback = callback + } + + override fun accept(event: MotionEvent) { + if (!isThreeFingerTouchpadSwipe(event)) return + val gestureState = distanceTracker.processEvent(event) + updateGestureState( + gestureStateChangedCallback, + gestureState, + isFinished = { -it.deltaY >= gestureDistanceThresholdPx }, + progress = { 0f }, + ) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureMonitor.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureMonitor.kt deleted file mode 100644 index 1731bb85fba4..000000000000 --- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureMonitor.kt +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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 kotlin.math.abs - -/** - * Monitors recent apps gesture completion. That is - using three fingers on touchpad - swipe up - * over some distance threshold and then slow down gesture before fingers are lifted. Implementation - * is based on [com.android.quickstep.util.TriggerSwipeUpTouchTracker] - */ -class RecentAppsGestureMonitor( - private val gestureDistanceThresholdPx: Int, - private val velocityThresholdPxPerMs: Float, - private val distanceTracker: DistanceTracker = DistanceTracker(), - private val velocityTracker: VerticalVelocityTracker = VerticalVelocityTracker(), -) : TouchpadGestureMonitor { - - private var gestureStateChangedCallback: (GestureState) -> Unit = {} - - override fun addGestureStateCallback(callback: (GestureState) -> Unit) { - gestureStateChangedCallback = callback - } - - override fun accept(event: MotionEvent) { - if (!isThreeFingerTouchpadSwipe(event)) return - val gestureState = distanceTracker.processEvent(event) - velocityTracker.accept(event) - - updateGestureState( - gestureStateChangedCallback, - gestureState, - isFinished = { state -> - -state.deltaY >= gestureDistanceThresholdPx && - abs(velocityTracker.calculateVelocity().value) <= velocityThresholdPxPerMs - }, - progress = { 0f }, - ) - } -} diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureRecognizer.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureRecognizer.kt new file mode 100644 index 000000000000..a194ad6a8016 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/RecentAppsGestureRecognizer.kt @@ -0,0 +1,55 @@ +/* + * 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 kotlin.math.abs + +/** + * Recognizes apps gesture completion. That is - using three fingers on touchpad - swipe up over + * some distance threshold and then slow down gesture before fingers are lifted. Implementation is + * based on [com.android.quickstep.util.TriggerSwipeUpTouchTracker] + */ +class RecentAppsGestureRecognizer( + private val gestureDistanceThresholdPx: Int, + private val velocityThresholdPxPerMs: Float, + private val distanceTracker: DistanceTracker = DistanceTracker(), + private val velocityTracker: VerticalVelocityTracker = VerticalVelocityTracker(), +) : GestureRecognizer { + + private var gestureStateChangedCallback: (GestureState) -> Unit = {} + + override fun addGestureStateCallback(callback: (GestureState) -> Unit) { + gestureStateChangedCallback = callback + } + + override fun accept(event: MotionEvent) { + if (!isThreeFingerTouchpadSwipe(event)) return + val gestureState = distanceTracker.processEvent(event) + velocityTracker.accept(event) + + updateGestureState( + gestureStateChangedCallback, + gestureState, + isFinished = { state -> + -state.deltaY >= gestureDistanceThresholdPx && + abs(velocityTracker.calculateVelocity().value) <= velocityThresholdPxPerMs + }, + progress = { 0f }, + ) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGestureHandler.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGestureHandler.kt index 4b82ba1c0dda..21e2917cf01b 100644 --- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGestureHandler.kt +++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGestureHandler.kt @@ -25,7 +25,7 @@ import java.util.function.Consumer * motion events passed to [onMotionEvent] and will filter touchpad events accordingly */ class TouchpadGestureHandler( - private val gestureMonitor: Consumer, + private val gestureRecognizer: Consumer, private val easterEggGestureMonitor: EasterEggGestureMonitor, ) { @@ -41,7 +41,7 @@ class TouchpadGestureHandler( if (isTwoFingerSwipe(event)) { easterEggGestureMonitor.processTouchpadEvent(event) } else { - gestureMonitor.accept(event) + gestureRecognizer.accept(event) } true } else { diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGestureMonitor.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGestureMonitor.kt deleted file mode 100644 index 9216821272ff..000000000000 --- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGestureMonitor.kt +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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 java.util.function.Consumer - -/** Monitor for touchpad gestures that can notify callback when [GestureState] changes. */ -interface TouchpadGestureMonitor : Consumer { - fun addGestureStateCallback(callback: (GestureState) -> Unit) -} - -fun isThreeFingerTouchpadSwipe(event: MotionEvent) = isNFingerTouchpadSwipe(event, fingerCount = 3) - -fun isFourFingerTouchpadSwipe(event: MotionEvent) = isNFingerTouchpadSwipe(event, fingerCount = 4) - -private fun isNFingerTouchpadSwipe(event: MotionEvent, fingerCount: Int): Boolean { - return event.classification == MotionEvent.CLASSIFICATION_MULTI_FINGER_SWIPE && - event.getAxisValue(MotionEvent.AXIS_GESTURE_SWIPE_FINGER_COUNT) == fingerCount.toFloat() -} - -fun isTwoFingerSwipe(event: MotionEvent): Boolean { - return event.classification == MotionEvent.CLASSIFICATION_TWO_FINGER_SWIPE -} -- cgit v1.2.3-59-g8ed1b