diff options
author | 2024-12-20 15:33:38 +0000 | |
---|---|---|
committer | 2024-12-24 11:32:30 +0100 | |
commit | d00d46e22dae09b398a452fb8ecc0321c34dcd1b (patch) | |
tree | d46dfcf99b1c5bac9da3c37c2ea195a7b1148da9 | |
parent | 5e1de3e73acb7edb10036e0da72eb65fb0f28792 (diff) |
1/n refactoring TouchpadGestureHandler
TouchpadGestureHandler is now simlpified to TouchpadEventsFilter and it's easier to use, without a need to create wrapper object which needs to be recreated for every change in recognizer
Bug: 384509663
Test: TouchpadEventsFilterTest
Flag: com.android.systemui.shared.new_touchpad_gestures_tutorial
Change-Id: Iacf6797caa4613f960c4bd1c5d39201bb03c50fe
7 files changed, 40 insertions, 62 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/EasterEggGestureRecognizerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/EasterEggGestureRecognizerTest.kt index 60388b9a10c8..3829778864f1 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/EasterEggGestureRecognizerTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/EasterEggGestureRecognizerTest.kt @@ -33,7 +33,6 @@ class EasterEggGestureRecognizerTest : SysuiTestCase() { private var triggered = false private val gestureRecognizer = EasterEggGestureRecognizer() - private val handler = TouchpadGestureHandler(gestureRecognizer) @Before fun setup() { @@ -99,7 +98,7 @@ class EasterEggGestureRecognizerTest : SysuiTestCase() { } private fun assertStateAfterEvents(events: List<MotionEvent>, wasTriggered: Boolean) { - events.forEach { handler.onMotionEvent(it) } + events.forEach { gestureRecognizer.accept(it) } assertThat(triggered).isEqualTo(wasTriggered) } 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/TouchpadEventsFilterTest.kt index 8eb79ebc3bb1..20bcb3eac8a0 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/TouchpadEventsFilterTest.kt @@ -33,12 +33,11 @@ import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) -class TouchpadGestureHandlerTest : SysuiTestCase() { +class TouchpadEventsFilterTest : SysuiTestCase() { private var gestureState: GestureState = GestureState.NotStarted private val gestureRecognizer = BackGestureRecognizer(gestureDistanceThresholdPx = SWIPE_DISTANCE.toInt()) - private val handler = TouchpadGestureHandler(gestureRecognizer) @Before fun before() { @@ -48,21 +47,21 @@ class TouchpadGestureHandlerTest : SysuiTestCase() { @Test fun handlesEventsFromTouchpad() { val event = downEvent(source = SOURCE_MOUSE, toolType = TOOL_TYPE_FINGER) - val eventHandled = handler.onMotionEvent(event) + val eventHandled = gestureRecognizer.handleTouchpadMotionEvent(event) assertThat(eventHandled).isTrue() } @Test fun ignoresEventsFromMouse() { val event = downEvent(source = SOURCE_MOUSE, toolType = TOOL_TYPE_MOUSE) - val eventHandled = handler.onMotionEvent(event) + val eventHandled = gestureRecognizer.handleTouchpadMotionEvent(event) assertThat(eventHandled).isFalse() } @Test fun ignoresEventsFromTouch() { val event = downEvent(source = SOURCE_TOUCHSCREEN, toolType = TOOL_TYPE_FINGER) - val eventHandled = handler.onMotionEvent(event) + val eventHandled = gestureRecognizer.handleTouchpadMotionEvent(event) assertThat(eventHandled).isFalse() } @@ -70,25 +69,10 @@ class TouchpadGestureHandlerTest : SysuiTestCase() { fun ignoresButtonClicksFromTouchpad() { val event = downEvent(source = SOURCE_MOUSE, toolType = TOOL_TYPE_FINGER) event.buttonState = MotionEvent.BUTTON_PRIMARY - val eventHandled = handler.onMotionEvent(event) + val eventHandled = gestureRecognizer.handleTouchpadMotionEvent(event) assertThat(eventHandled).isFalse() } private fun downEvent(source: Int, toolType: Int) = motionEvent(action = ACTION_DOWN, x = 0f, y = 0f, source = source, toolType = toolType) - - @Test - fun triggersGestureDoneForThreeFingerGesture() { - backGestureEvents().forEach { handler.onMotionEvent(it) } - - assertThat(gestureState).isEqualTo(GestureState.Finished) - } - - private fun backGestureEvents(): List<MotionEvent> { - return ThreeFingerGesture.eventsForFullGesture { - move(deltaX = SWIPE_DISTANCE / 4) - move(deltaX = SWIPE_DISTANCE / 2) - move(deltaX = SWIPE_DISTANCE) - } - } } 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/TouchpadEventsFilter.kt index f417c4c84f3c..bddeb0b25ec2 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/TouchpadEventsFilter.kt @@ -18,27 +18,27 @@ package com.android.systemui.touchpad.tutorial.ui.gesture import android.view.InputDevice import android.view.MotionEvent -import java.util.function.Consumer +import android.view.MotionEvent.ACTION_DOWN +import android.view.MotionEvent.BUTTON_PRIMARY -/** - * Allows listening to touchpadGesture and calling onDone when gesture was triggered. Can have all - * motion events passed to [onMotionEvent] and will filter touchpad events accordingly - */ -class TouchpadGestureHandler(private vararg val eventConsumers: Consumer<MotionEvent>) { +object TouchpadEventsFilter { - fun onMotionEvent(event: MotionEvent): Boolean { + fun isTouchpadAndNonClickEvent(event: MotionEvent): Boolean { // events from touchpad have SOURCE_MOUSE and not SOURCE_TOUCHPAD because of legacy reasons val isFromTouchpad = event.isFromSource(InputDevice.SOURCE_MOUSE) && event.getToolType(0) == MotionEvent.TOOL_TYPE_FINGER - val buttonClick = - event.actionMasked == MotionEvent.ACTION_DOWN && - event.isButtonPressed(MotionEvent.BUTTON_PRIMARY) - return if (isFromTouchpad && !buttonClick) { - eventConsumers.forEach { it.accept(event) } - true - } else { - false - } + val isButtonClicked = + event.actionMasked == ACTION_DOWN && event.isButtonPressed(BUTTON_PRIMARY) + return isFromTouchpad && !isButtonClicked + } +} + +fun GestureRecognizer.handleTouchpadMotionEvent(event: MotionEvent): Boolean { + return if (TouchpadEventsFilter.isTouchpadAndNonClickEvent(event)) { + this.accept(event) + true + } else { + false } } diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/BackGestureScreenViewModel.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/BackGestureScreenViewModel.kt index b5ed25b8a0da..93e8d313edcf 100644 --- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/BackGestureScreenViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/BackGestureScreenViewModel.kt @@ -26,7 +26,7 @@ import com.android.systemui.touchpad.tutorial.ui.gesture.GestureDirection import com.android.systemui.touchpad.tutorial.ui.gesture.GestureFlowAdapter import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.InProgress -import com.android.systemui.touchpad.tutorial.ui.gesture.TouchpadGestureHandler +import com.android.systemui.touchpad.tutorial.ui.gesture.handleTouchpadMotionEvent import com.android.systemui.util.kotlin.pairwiseBy import javax.inject.Inject import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -38,7 +38,7 @@ class BackGestureScreenViewModel @Inject constructor(configurationInteractor: ConfigurationInteractor) : TouchpadTutorialScreenViewModel { - private var handler: TouchpadGestureHandler? = null + private var recognizer: BackGestureRecognizer? = null private val distanceThreshold: Flow<Int> = configurationInteractor @@ -49,16 +49,15 @@ constructor(configurationInteractor: ConfigurationInteractor) : TouchpadTutorial override val gestureUiState: Flow<GestureUiState> = distanceThreshold .flatMapLatest { - val recognizer = BackGestureRecognizer(gestureDistanceThresholdPx = it) - handler = TouchpadGestureHandler(recognizer) - GestureFlowAdapter(recognizer).gestureStateAsFlow + recognizer = BackGestureRecognizer(gestureDistanceThresholdPx = it) + GestureFlowAdapter(recognizer!!).gestureStateAsFlow } .pairwiseBy(GestureState.NotStarted) { previous, current -> toGestureUiState(current, previous) } override fun handleEvent(event: MotionEvent): Boolean { - return handler?.onMotionEvent(event) ?: false + return recognizer?.handleTouchpadMotionEvent(event) ?: false } private fun toGestureUiState(current: GestureState, previous: GestureState): GestureUiState { diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/EasterEggGestureViewModel.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/EasterEggGestureViewModel.kt index 15d50a1b8b29..69cdab6108ab 100644 --- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/EasterEggGestureViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/EasterEggGestureViewModel.kt @@ -20,7 +20,7 @@ import android.view.MotionEvent import com.android.systemui.touchpad.tutorial.ui.gesture.EasterEggGestureRecognizer import com.android.systemui.touchpad.tutorial.ui.gesture.GestureFlowAdapter import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState -import com.android.systemui.touchpad.tutorial.ui.gesture.TouchpadGestureHandler +import com.android.systemui.touchpad.tutorial.ui.gesture.handleTouchpadMotionEvent import java.util.function.Consumer import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.filter @@ -30,11 +30,9 @@ import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.receiveAsFlow class EasterEggGestureViewModel( - gestureRecognizer: EasterEggGestureRecognizer = EasterEggGestureRecognizer() + private val gestureRecognizer: EasterEggGestureRecognizer = EasterEggGestureRecognizer() ) : Consumer<MotionEvent> { - private val handler = TouchpadGestureHandler(gestureRecognizer) - private val gestureDone = GestureFlowAdapter(gestureRecognizer).gestureStateAsFlow.filter { it == GestureState.Finished @@ -56,7 +54,7 @@ class EasterEggGestureViewModel( .onStart { emit(false) } override fun accept(event: MotionEvent) { - handler.onMotionEvent(event) + gestureRecognizer.handleTouchpadMotionEvent(event) } fun onEasterEggFinished() { diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/HomeGestureScreenViewModel.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/HomeGestureScreenViewModel.kt index 569cc936bd0b..9a817d810bba 100644 --- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/HomeGestureScreenViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/HomeGestureScreenViewModel.kt @@ -26,9 +26,9 @@ import com.android.systemui.touchpad.tutorial.ui.composable.toGestureUiState import com.android.systemui.touchpad.tutorial.ui.gesture.GestureFlowAdapter import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState import com.android.systemui.touchpad.tutorial.ui.gesture.HomeGestureRecognizer -import com.android.systemui.touchpad.tutorial.ui.gesture.TouchpadGestureHandler import com.android.systemui.touchpad.tutorial.ui.gesture.VelocityTracker import com.android.systemui.touchpad.tutorial.ui.gesture.VerticalVelocityTracker +import com.android.systemui.touchpad.tutorial.ui.gesture.handleTouchpadMotionEvent import javax.inject.Inject import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow @@ -45,7 +45,7 @@ constructor( val velocityTracker: VelocityTracker = VerticalVelocityTracker(), ) : TouchpadTutorialScreenViewModel { - private var handler: TouchpadGestureHandler? = null + private var recognizer: HomeGestureRecognizer? = null private val distanceThreshold: Flow<Int> = configurationInteractor @@ -62,14 +62,13 @@ constructor( distanceThreshold .combine(velocityThreshold, { distance, velocity -> distance to velocity }) .flatMapLatest { (distance, velocity) -> - val recognizer = + recognizer = HomeGestureRecognizer( gestureDistanceThresholdPx = distance, velocityThresholdPxPerMs = velocity, velocityTracker = velocityTracker, ) - handler = TouchpadGestureHandler(recognizer) - GestureFlowAdapter(recognizer).gestureStateAsFlow + GestureFlowAdapter(recognizer!!).gestureStateAsFlow } .map { toGestureUiState(it) } @@ -81,6 +80,6 @@ constructor( ) override fun handleEvent(event: MotionEvent): Boolean { - return handler?.onMotionEvent(event) ?: false + return recognizer?.handleTouchpadMotionEvent(event) ?: false } } diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/RecentAppsGestureScreenViewModel.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/RecentAppsGestureScreenViewModel.kt index 989a60878733..8215078c346d 100644 --- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/RecentAppsGestureScreenViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/RecentAppsGestureScreenViewModel.kt @@ -26,9 +26,9 @@ import com.android.systemui.touchpad.tutorial.ui.composable.toGestureUiState import com.android.systemui.touchpad.tutorial.ui.gesture.GestureFlowAdapter import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState import com.android.systemui.touchpad.tutorial.ui.gesture.RecentAppsGestureRecognizer -import com.android.systemui.touchpad.tutorial.ui.gesture.TouchpadGestureHandler import com.android.systemui.touchpad.tutorial.ui.gesture.VelocityTracker import com.android.systemui.touchpad.tutorial.ui.gesture.VerticalVelocityTracker +import com.android.systemui.touchpad.tutorial.ui.gesture.handleTouchpadMotionEvent import javax.inject.Inject import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow @@ -45,7 +45,7 @@ constructor( private val velocityTracker: VelocityTracker = VerticalVelocityTracker(), ) : TouchpadTutorialScreenViewModel { - private var handler: TouchpadGestureHandler? = null + private var recognizer: RecentAppsGestureRecognizer? = null private val distanceThreshold: Flow<Int> = configurationInteractor.onAnyConfigurationChange @@ -66,14 +66,13 @@ constructor( distanceThreshold .combine(velocityThreshold, { distance, velocity -> distance to velocity }) .flatMapLatest { (distance, velocity) -> - val recognizer = + recognizer = RecentAppsGestureRecognizer( gestureDistanceThresholdPx = distance, velocityThresholdPxPerMs = velocity, velocityTracker = velocityTracker, ) - handler = TouchpadGestureHandler(recognizer) - GestureFlowAdapter(recognizer).gestureStateAsFlow + GestureFlowAdapter(recognizer!!).gestureStateAsFlow } .map { toGestureUiState(it) } @@ -85,6 +84,6 @@ constructor( ) override fun handleEvent(event: MotionEvent): Boolean { - return handler?.onMotionEvent(event) ?: false + return recognizer?.handleTouchpadMotionEvent(event) ?: false } } |