summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Treehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com> 2025-01-22 10:50:00 -0800
committer Android (Google) Code Review <android-gerrit@google.com> 2025-01-22 10:50:00 -0800
commitd5258154fdf075e09808142d1e18cf18c063f392 (patch)
tree628dbcba34ba00a7a8ee9831278a33982fd928bf
parent33ad61da50e6898f8551c9092184e60ffe26541f (diff)
parentc93e5ebb7685768b5ad487aab42cb66b83b851b4 (diff)
Merge "[Quickswitch] tests" into main
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/SwitchAppsGestureRecognizerTest.kt85
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/SwitchAppsGestureScreenViewModelTest.kt132
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/SwitchAppsGestureRecognizer.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/SwitchAppsGestureRecognizerProvider.kt4
4 files changed, 220 insertions, 14 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/SwitchAppsGestureRecognizerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/SwitchAppsGestureRecognizerTest.kt
new file mode 100644
index 000000000000..756b79c6a868
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/SwitchAppsGestureRecognizerTest.kt
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2025 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.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 SwitchAppsGestureRecognizerTest : SysuiTestCase() {
+
+ private var gestureState: GestureState = NotStarted
+ private val gestureRecognizer =
+ SwitchAppsGestureRecognizer(gestureDistanceThresholdPx = SWIPE_DISTANCE.toInt())
+
+ @Before
+ fun before() {
+ gestureRecognizer.addGestureStateCallback { gestureState = it }
+ }
+
+ @Test
+ fun triggersProgressRelativeToDistanceWhenSwipingRight() {
+ assertProgressWhileMovingFingers(
+ deltaX = SWIPE_DISTANCE / 2,
+ expected = InProgress(progress = 0.5f),
+ )
+ assertProgressWhileMovingFingers(
+ deltaX = SWIPE_DISTANCE,
+ expected = InProgress(progress = 1f),
+ )
+ }
+
+ @Test
+ fun triggersProgressDoesNotGoBelowZero() {
+ // going in the wrong direction
+ assertProgressWhileMovingFingers(
+ deltaX = -SWIPE_DISTANCE,
+ expected = InProgress(progress = 0f),
+ )
+ }
+
+ @Test
+ fun triggersProgressDoesNotExceedOne() {
+ // going further than required distance
+ assertProgressWhileMovingFingers(
+ deltaX = SWIPE_DISTANCE * 2,
+ expected = InProgress(progress = 1f),
+ )
+ }
+
+ private fun assertProgressWhileMovingFingers(deltaX: Float, expected: InProgress) {
+ assertStateAfterEvents(
+ events = FourFingerGesture.eventsForGestureInProgress { move(deltaX = deltaX) },
+ expectedState = expected,
+ )
+ }
+
+ private fun assertStateAfterEvents(events: List<MotionEvent>, expectedState: GestureState) {
+ events.forEach { gestureRecognizer.accept(it) }
+ assertThat(gestureState).isEqualTo(expectedState)
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/SwitchAppsGestureScreenViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/SwitchAppsGestureScreenViewModelTest.kt
new file mode 100644
index 000000000000..ee339b0b7446
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/SwitchAppsGestureScreenViewModelTest.kt
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2025 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.viewmodel
+
+import android.content.res.mockResources
+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.common.ui.data.repository.fakeConfigurationRepository
+import com.android.systemui.inputdevice.tutorial.inputDeviceTutorialLogger
+import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialActionState
+import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialActionState.Error
+import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialActionState.Finished
+import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialActionState.InProgress
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.collectLastValue
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.res.R
+import com.android.systemui.testKosmos
+import com.android.systemui.touchpad.tutorial.ui.gesture.FourFingerGesture
+import com.android.systemui.touchpad.tutorial.ui.gesture.MultiFingerGesture.Companion.SWIPE_DISTANCE
+import com.android.systemui.touchpad.ui.gesture.touchpadGestureResources
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.whenever
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class SwitchAppsGestureScreenViewModelTest : SysuiTestCase() {
+
+ private val kosmos = testKosmos()
+ private val resources = kosmos.mockResources
+ private val fakeConfigRepository = kosmos.fakeConfigurationRepository
+ private val viewModel =
+ SwitchAppsGestureScreenViewModel(
+ GestureRecognizerAdapter(
+ SwitchAppsGestureRecognizerProvider(kosmos.touchpadGestureResources),
+ kosmos.inputDeviceTutorialLogger,
+ )
+ )
+
+ @Before
+ fun before() {
+ setDistanceThreshold(threshold = SWIPE_DISTANCE - 1)
+ kosmos.useUnconfinedTestDispatcher()
+ }
+
+ @Test
+ fun emitsProgressStateWithProgressAnimation() =
+ kosmos.runTest {
+ assertProgressWhileMovingFingers(
+ deltaX = SWIPE_DISTANCE,
+ expected =
+ InProgress(
+ progress = 1f,
+ startMarker = "gesture to R",
+ endMarker = "end of gesture",
+ ),
+ )
+ }
+
+ @Test
+ fun emitsFinishedStateWithSuccessAnimation() =
+ kosmos.runTest {
+ assertStateAfterEvents(
+ events = FourFingerGesture.swipeRight(),
+ expected = Finished(successAnimation = R.raw.trackpad_switch_apps_success),
+ )
+ }
+
+ @Test
+ fun emitErrorStateWhenLatestDistanceThresholdNotReached() =
+ kosmos.runTest {
+ fun performGesture() =
+ FourFingerGesture.swipeRight().forEach { viewModel.handleEvent(it) }
+ val state by collectLastValue(viewModel.tutorialState)
+ performGesture()
+ assertThat(state).isInstanceOf(Finished::class.java)
+
+ setDistanceThreshold(SWIPE_DISTANCE + 1)
+ performGesture() // now swipe distance is not enough to trigger success
+
+ assertThat(state).isInstanceOf(Error::class.java)
+ }
+
+ private fun setDistanceThreshold(threshold: Float) {
+ whenever(
+ resources.getDimensionPixelSize(
+ R.dimen.touchpad_tutorial_gestures_distance_threshold
+ )
+ )
+ .thenReturn(threshold.toInt())
+ fakeConfigRepository.onAnyConfigurationChange()
+ }
+
+ private fun Kosmos.assertProgressWhileMovingFingers(
+ deltaX: Float,
+ expected: TutorialActionState,
+ ) {
+ assertStateAfterEvents(
+ events = FourFingerGesture.eventsForGestureInProgress { move(deltaX = deltaX) },
+ expected = expected,
+ )
+ }
+
+ private fun Kosmos.assertStateAfterEvents(
+ events: List<MotionEvent>,
+ expected: TutorialActionState,
+ ) {
+ val state by collectLastValue(viewModel.tutorialState)
+ events.forEach { viewModel.handleEvent(it) }
+ assertThat(state).isEqualTo(expected)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/SwitchAppsGestureRecognizer.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/SwitchAppsGestureRecognizer.kt
index cc382d0a6148..6732287fe256 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/SwitchAppsGestureRecognizer.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/SwitchAppsGestureRecognizer.kt
@@ -18,12 +18,9 @@ package com.android.systemui.touchpad.tutorial.ui.gesture
import android.util.MathUtils
import android.view.MotionEvent
-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.InProgress
-import kotlin.math.abs
-/** Recognizes Quickswitch gesture i.e. using four fingers on touchpad, swiping right. */
+/** Recognizes Quickswitch gesture i.e. using four fingers on touchpad, swiping to right. */
class SwitchAppsGestureRecognizer(private val gestureDistanceThresholdPx: Int) : GestureRecognizer {
private val distanceTracker = DistanceTracker()
@@ -50,13 +47,7 @@ class SwitchAppsGestureRecognizer(private val gestureDistanceThresholdPx: Int) :
gestureStateChangedCallback,
gestureState,
isFinished = { it.deltaX >= gestureDistanceThresholdPx },
- progress = ::getProgress,
+ progress = { InProgress(MathUtils.saturate(it.deltaX / gestureDistanceThresholdPx)) },
)
}
-
- private fun getProgress(it: Moving): InProgress {
- val direction = if (it.deltaX > 0) RIGHT else LEFT
- val value = MathUtils.saturate(abs(it.deltaX / gestureDistanceThresholdPx))
- return InProgress(value, direction)
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/SwitchAppsGestureRecognizerProvider.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/SwitchAppsGestureRecognizerProvider.kt
index b1e163b55377..8b8606a119d4 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/SwitchAppsGestureRecognizerProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/SwitchAppsGestureRecognizerProvider.kt
@@ -18,15 +18,13 @@ package com.android.systemui.touchpad.tutorial.ui.viewmodel
import com.android.systemui.touchpad.tutorial.ui.gesture.GestureRecognizer
import com.android.systemui.touchpad.tutorial.ui.gesture.SwitchAppsGestureRecognizer
-import com.android.systemui.touchpad.tutorial.ui.gesture.VelocityTracker
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
class SwitchAppsGestureRecognizerProvider
@Inject
-constructor(val resources: TouchpadGestureResources, val velocityTracker: VelocityTracker) :
- GestureRecognizerProvider {
+constructor(val resources: TouchpadGestureResources) : GestureRecognizerProvider {
override val recognizer: Flow<GestureRecognizer> =
resources.distanceThreshold().map {