summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/StateTransitionsTest.kt111
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/BackGestureScreenViewModelTest.kt30
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/HomeGestureScreenViewModelTest.kt23
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/RecentAppsGestureScreenViewModelTest.kt23
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/TouchpadTutorialScreenViewModelTest.kt117
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/GestureTutorialScreen.kt75
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/HomeGestureTutorialScreen.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/RecentAppsGestureTutorialScreen.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/BackGestureScreenViewModel.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/HomeGestureScreenViewModel.kt22
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/RecentAppsGestureScreenViewModel.kt22
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/TouchpadTutorialScreenViewModel.kt55
13 files changed, 261 insertions, 244 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/StateTransitionsTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/StateTransitionsTest.kt
deleted file mode 100644
index 2ad1124d72d4..000000000000
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/StateTransitionsTest.kt
+++ /dev/null
@@ -1,111 +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
-
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-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.inputdevice.tutorial.ui.composable.TutorialActionState.InProgressAfterError
-import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialActionState.NotStarted
-import com.android.systemui.touchpad.tutorial.ui.composable.toGestureUiState
-import com.android.systemui.touchpad.tutorial.ui.composable.toTutorialActionState
-import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState
-import com.google.common.truth.Truth.assertThat
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-class StateTransitionsTest : SysuiTestCase() {
-
- companion object {
- private const val START_MARKER = "startMarker"
- private const val END_MARKER = "endMarker"
- private const val SUCCESS_ANIMATION = 0
- }
-
- // needed to simulate caching last state as it's used to create new state
- private var lastState: TutorialActionState = NotStarted
-
- private fun GestureState.toTutorialActionState(): TutorialActionState {
- val newState =
- this.toGestureUiState(
- progressStartMarker = START_MARKER,
- progressEndMarker = END_MARKER,
- successAnimation = SUCCESS_ANIMATION,
- )
- .toTutorialActionState(lastState)
- lastState = newState
- return lastState
- }
-
- @Test
- fun gestureStateProducesEquivalentTutorialActionStateInHappyPath() {
- val happyPath =
- listOf(
- GestureState.NotStarted,
- GestureState.InProgress(0f),
- GestureState.InProgress(0.5f),
- GestureState.InProgress(1f),
- GestureState.Finished,
- )
-
- val resultingStates = mutableListOf<TutorialActionState>()
- happyPath.forEach { resultingStates.add(it.toTutorialActionState()) }
-
- assertThat(resultingStates)
- .containsExactly(
- NotStarted,
- InProgress(0f, START_MARKER, END_MARKER),
- InProgress(0.5f, START_MARKER, END_MARKER),
- InProgress(1f, START_MARKER, END_MARKER),
- Finished(SUCCESS_ANIMATION),
- )
- .inOrder()
- }
-
- @Test
- fun gestureStateProducesEquivalentTutorialActionStateInErrorPath() {
- val errorPath =
- listOf(
- GestureState.NotStarted,
- GestureState.InProgress(0f),
- GestureState.Error,
- GestureState.InProgress(0.5f),
- GestureState.InProgress(1f),
- GestureState.Finished,
- )
-
- val resultingStates = mutableListOf<TutorialActionState>()
- errorPath.forEach { resultingStates.add(it.toTutorialActionState()) }
-
- assertThat(resultingStates)
- .containsExactly(
- NotStarted,
- InProgress(0f, START_MARKER, END_MARKER),
- Error,
- InProgressAfterError(InProgress(0.5f, START_MARKER, END_MARKER)),
- InProgressAfterError(InProgress(1f, START_MARKER, END_MARKER)),
- Finished(SUCCESS_ANIMATION),
- )
- .inOrder()
- }
-}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/BackGestureScreenViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/BackGestureScreenViewModelTest.kt
index 4aec88e8497b..d752046f4791 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/BackGestureScreenViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/BackGestureScreenViewModelTest.kt
@@ -23,16 +23,16 @@ 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.composable.GestureUiState
-import com.android.systemui.touchpad.tutorial.ui.composable.GestureUiState.Error
-import com.android.systemui.touchpad.tutorial.ui.composable.GestureUiState.Finished
-import com.android.systemui.touchpad.tutorial.ui.composable.GestureUiState.InProgress
import com.android.systemui.touchpad.tutorial.ui.gesture.MultiFingerGesture.Companion.SWIPE_DISTANCE
import com.android.systemui.touchpad.tutorial.ui.gesture.ThreeFingerGesture
import com.android.systemui.touchpad.ui.gesture.touchpadGestureResources
@@ -71,8 +71,8 @@ class BackGestureScreenViewModelTest : SysuiTestCase() {
expected =
InProgress(
progress = 1f,
- progressStartMarker = "gesture to L",
- progressEndMarker = "end progress L",
+ startMarker = "gesture to L",
+ endMarker = "end progress L",
),
)
}
@@ -85,8 +85,8 @@ class BackGestureScreenViewModelTest : SysuiTestCase() {
expected =
InProgress(
progress = 1f,
- progressStartMarker = "gesture to R",
- progressEndMarker = "end progress R",
+ startMarker = "gesture to R",
+ endMarker = "end progress R",
),
)
}
@@ -114,7 +114,7 @@ class BackGestureScreenViewModelTest : SysuiTestCase() {
kosmos.runTest {
fun performBackGesture() =
ThreeFingerGesture.swipeLeft().forEach { viewModel.handleEvent(it) }
- val state by collectLastValue(viewModel.gestureUiState)
+ val state by collectLastValue(viewModel.tutorialState)
performBackGesture()
assertThat(state).isInstanceOf(Finished::class.java)
@@ -134,15 +134,21 @@ class BackGestureScreenViewModelTest : SysuiTestCase() {
fakeConfigRepository.onAnyConfigurationChange()
}
- private fun Kosmos.assertProgressWhileMovingFingers(deltaX: Float, expected: GestureUiState) {
+ private fun Kosmos.assertProgressWhileMovingFingers(
+ deltaX: Float,
+ expected: TutorialActionState,
+ ) {
assertStateAfterEvents(
events = ThreeFingerGesture.eventsForGestureInProgress { move(deltaX = deltaX) },
expected = expected,
)
}
- private fun Kosmos.assertStateAfterEvents(events: List<MotionEvent>, expected: GestureUiState) {
- val state by collectLastValue(viewModel.gestureUiState)
+ 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/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/HomeGestureScreenViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/HomeGestureScreenViewModelTest.kt
index 65a995dcd043..7862fd32ca04 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/HomeGestureScreenViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/HomeGestureScreenViewModelTest.kt
@@ -23,16 +23,16 @@ 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.composable.GestureUiState
-import com.android.systemui.touchpad.tutorial.ui.composable.GestureUiState.Error
-import com.android.systemui.touchpad.tutorial.ui.composable.GestureUiState.Finished
-import com.android.systemui.touchpad.tutorial.ui.composable.GestureUiState.InProgress
import com.android.systemui.touchpad.tutorial.ui.gesture.MultiFingerGesture.Companion.SWIPE_DISTANCE
import com.android.systemui.touchpad.tutorial.ui.gesture.ThreeFingerGesture
import com.android.systemui.touchpad.tutorial.ui.gesture.Velocity
@@ -86,8 +86,8 @@ class HomeGestureScreenViewModelTest : SysuiTestCase() {
expected =
InProgress(
progress = 1f,
- progressStartMarker = "drag with gesture",
- progressEndMarker = "release playback realtime",
+ startMarker = "drag with gesture",
+ endMarker = "release playback realtime",
),
)
}
@@ -108,7 +108,7 @@ class HomeGestureScreenViewModelTest : SysuiTestCase() {
@Test
fun gestureRecognitionTakesLatestDistanceThresholdIntoAccount() =
kosmos.runTest {
- val state by collectLastValue(viewModel.gestureUiState)
+ val state by collectLastValue(viewModel.tutorialState)
performHomeGesture()
assertThat(state).isInstanceOf(Finished::class.java)
@@ -121,7 +121,7 @@ class HomeGestureScreenViewModelTest : SysuiTestCase() {
@Test
fun gestureRecognitionTakesLatestVelocityThresholdIntoAccount() =
kosmos.runTest {
- val state by collectLastValue(viewModel.gestureUiState)
+ val state by collectLastValue(viewModel.tutorialState)
performHomeGesture()
assertThat(state).isInstanceOf(Finished::class.java)
@@ -147,8 +147,11 @@ class HomeGestureScreenViewModelTest : SysuiTestCase() {
fakeConfigRepository.onAnyConfigurationChange()
}
- private fun Kosmos.assertStateAfterEvents(events: List<MotionEvent>, expected: GestureUiState) {
- val state by collectLastValue(viewModel.gestureUiState)
+ 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/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/RecentAppsGestureScreenViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/RecentAppsGestureScreenViewModelTest.kt
index 1bc60b67095e..6180fa98b1cd 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/RecentAppsGestureScreenViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/RecentAppsGestureScreenViewModelTest.kt
@@ -23,16 +23,16 @@ 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.composable.GestureUiState
-import com.android.systemui.touchpad.tutorial.ui.composable.GestureUiState.Error
-import com.android.systemui.touchpad.tutorial.ui.composable.GestureUiState.Finished
-import com.android.systemui.touchpad.tutorial.ui.composable.GestureUiState.InProgress
import com.android.systemui.touchpad.tutorial.ui.gesture.MultiFingerGesture.Companion.SWIPE_DISTANCE
import com.android.systemui.touchpad.tutorial.ui.gesture.ThreeFingerGesture
import com.android.systemui.touchpad.tutorial.ui.gesture.Velocity
@@ -89,8 +89,8 @@ class RecentAppsGestureScreenViewModelTest : SysuiTestCase() {
expected =
InProgress(
progress = 1f,
- progressStartMarker = "drag with gesture",
- progressEndMarker = "onPause",
+ startMarker = "drag with gesture",
+ endMarker = "onPause",
),
)
}
@@ -111,7 +111,7 @@ class RecentAppsGestureScreenViewModelTest : SysuiTestCase() {
@Test
fun gestureRecognitionTakesLatestDistanceThresholdIntoAccount() =
kosmos.runTest {
- val state by collectLastValue(viewModel.gestureUiState)
+ val state by collectLastValue(viewModel.tutorialState)
performRecentAppsGesture()
assertThat(state).isInstanceOf(Finished::class.java)
@@ -124,7 +124,7 @@ class RecentAppsGestureScreenViewModelTest : SysuiTestCase() {
@Test
fun gestureRecognitionTakesLatestVelocityThresholdIntoAccount() =
kosmos.runTest {
- val state by collectLastValue(viewModel.gestureUiState)
+ val state by collectLastValue(viewModel.tutorialState)
performRecentAppsGesture()
assertThat(state).isInstanceOf(Finished::class.java)
@@ -150,8 +150,11 @@ class RecentAppsGestureScreenViewModelTest : SysuiTestCase() {
fakeConfigRepository.onAnyConfigurationChange()
}
- private fun Kosmos.assertStateAfterEvents(events: List<MotionEvent>, expected: GestureUiState) {
- val state by collectLastValue(viewModel.gestureUiState)
+ 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/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/TouchpadTutorialScreenViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/TouchpadTutorialScreenViewModelTest.kt
new file mode 100644
index 000000000000..c113dd9e1eff
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/TouchpadTutorialScreenViewModelTest.kt
@@ -0,0 +1,117 @@
+/*
+ * 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.viewmodel
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+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.inputdevice.tutorial.ui.composable.TutorialActionState.InProgressAfterError
+import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialActionState.NotStarted
+import com.android.systemui.kosmos.collectValues
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.testKosmos
+import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.asFlow
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class TouchpadTutorialScreenViewModelTest : SysuiTestCase() {
+
+ companion object {
+ private const val START_MARKER = "startMarker"
+ private const val END_MARKER = "endMarker"
+ private const val SUCCESS_ANIMATION = 0
+ }
+
+ private val kosmos = testKosmos()
+ private val animationProperties =
+ TutorialAnimationProperties(
+ progressStartMarker = START_MARKER,
+ progressEndMarker = END_MARKER,
+ successAnimation = SUCCESS_ANIMATION,
+ )
+
+ @Before
+ fun before() {
+ kosmos.useUnconfinedTestDispatcher()
+ }
+
+ @Test
+ fun gestureStateProducesEquivalentTutorialActionStateInHappyPath() =
+ kosmos.runTest {
+ val happyPath: Flow<Pair<GestureState, TutorialAnimationProperties>> =
+ listOf(
+ GestureState.NotStarted,
+ GestureState.InProgress(0f),
+ GestureState.InProgress(0.5f),
+ GestureState.InProgress(1f),
+ GestureState.Finished,
+ )
+ .map { it to animationProperties }
+ .asFlow()
+
+ val resultingStates by collectValues(happyPath.mapToTutorialState())
+
+ assertThat(resultingStates)
+ .containsExactly(
+ NotStarted,
+ InProgress(0f, START_MARKER, END_MARKER),
+ InProgress(0.5f, START_MARKER, END_MARKER),
+ InProgress(1f, START_MARKER, END_MARKER),
+ Finished(SUCCESS_ANIMATION),
+ )
+ .inOrder()
+ }
+
+ @Test
+ fun gestureStateProducesEquivalentTutorialActionStateInErrorPath() =
+ kosmos.runTest {
+ val errorPath: Flow<Pair<GestureState, TutorialAnimationProperties>> =
+ listOf(
+ GestureState.NotStarted,
+ GestureState.InProgress(0f),
+ GestureState.Error,
+ GestureState.InProgress(0.5f),
+ GestureState.InProgress(1f),
+ GestureState.Finished,
+ )
+ .map { it to animationProperties }
+ .asFlow()
+
+ val resultingStates by collectValues(errorPath.mapToTutorialState())
+
+ assertThat(resultingStates)
+ .containsExactly(
+ NotStarted,
+ InProgress(0f, START_MARKER, END_MARKER),
+ Error,
+ InProgressAfterError(InProgress(0.5f, START_MARKER, END_MARKER)),
+ InProgressAfterError(InProgress(1f, START_MARKER, END_MARKER)),
+ Finished(SUCCESS_ANIMATION),
+ )
+ .inOrder()
+ }
+}
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 ae32b7a6175c..bce55cbdcc4a 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
@@ -50,7 +50,7 @@ fun BackGestureTutorialScreen(
)
GestureTutorialScreen(
screenConfig = screenConfig,
- gestureUiStateFlow = viewModel.gestureUiState,
+ tutorialStateFlow = viewModel.tutorialState,
motionEventConsumer = {
easterEggGestureViewModel.accept(it)
viewModel.handleEvent(it)
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 73c54af595d9..284e23e5a288 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
@@ -18,7 +18,6 @@ package com.android.systemui.touchpad.tutorial.ui.composable
import android.view.MotionEvent
import androidx.activity.compose.BackHandler
-import androidx.annotation.RawRes
import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.Box
@@ -27,77 +26,21 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
-import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.pointer.pointerInteropFilter
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.systemui.inputdevice.tutorial.ui.composable.ActionTutorialContent
import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialActionState
+import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialActionState.NotStarted
import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialScreenConfig
-import com.android.systemui.touchpad.tutorial.ui.composable.GestureUiState.Finished
-import com.android.systemui.touchpad.tutorial.ui.composable.GestureUiState.NotStarted
-import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState
import kotlinx.coroutines.flow.Flow
-sealed interface GestureUiState {
- data object NotStarted : GestureUiState
-
- data class Finished(@RawRes val successAnimation: Int) : GestureUiState
-
- data class InProgress(
- val progress: Float = 0f,
- val progressStartMarker: String,
- val progressEndMarker: String,
- ) : GestureUiState
-
- data object Error : GestureUiState
-}
-
-fun GestureState.toGestureUiState(
- progressStartMarker: String,
- progressEndMarker: String,
- successAnimation: Int,
-): GestureUiState {
- return when (this) {
- GestureState.NotStarted -> NotStarted
- is GestureState.InProgress ->
- GestureUiState.InProgress(this.progress, progressStartMarker, progressEndMarker)
- is GestureState.Finished -> GestureUiState.Finished(successAnimation)
- GestureState.Error -> GestureUiState.Error
- }
-}
-
-fun GestureUiState.toTutorialActionState(previousState: TutorialActionState): TutorialActionState {
- return when (this) {
- NotStarted -> TutorialActionState.NotStarted
- is GestureUiState.InProgress -> {
- val inProgress =
- TutorialActionState.InProgress(
- progress = progress,
- startMarker = progressStartMarker,
- endMarker = progressEndMarker,
- )
- if (
- previousState is TutorialActionState.InProgressAfterError ||
- previousState is TutorialActionState.Error
- ) {
- return TutorialActionState.InProgressAfterError(inProgress)
- } else {
- return inProgress
- }
- }
- is Finished -> TutorialActionState.Finished(successAnimation)
- GestureUiState.Error -> TutorialActionState.Error
- }
-}
-
@Composable
fun GestureTutorialScreen(
screenConfig: TutorialScreenConfig,
- gestureUiStateFlow: Flow<GestureUiState>,
+ tutorialStateFlow: Flow<TutorialActionState>,
motionEventConsumer: (MotionEvent) -> Boolean,
easterEggTriggeredFlow: Flow<Boolean>,
onEasterEggFinished: () -> Unit,
@@ -106,25 +49,21 @@ fun GestureTutorialScreen(
) {
BackHandler(onBack = onBack)
val easterEggTriggered by easterEggTriggeredFlow.collectAsStateWithLifecycle(false)
- val gestureState by gestureUiStateFlow.collectAsStateWithLifecycle(NotStarted)
+ val tutorialState by tutorialStateFlow.collectAsStateWithLifecycle(NotStarted)
TouchpadGesturesHandlingBox(
motionEventConsumer,
- gestureState,
+ tutorialState,
easterEggTriggered,
onEasterEggFinished,
) {
- var lastState: TutorialActionState by remember {
- mutableStateOf(TutorialActionState.NotStarted)
- }
- lastState = gestureState.toTutorialActionState(lastState)
- ActionTutorialContent(lastState, onDoneButtonClicked, screenConfig)
+ ActionTutorialContent(tutorialState, onDoneButtonClicked, screenConfig)
}
}
@Composable
private fun TouchpadGesturesHandlingBox(
motionEventConsumer: (MotionEvent) -> Boolean,
- gestureState: GestureUiState,
+ tutorialState: TutorialActionState,
easterEggTriggered: Boolean,
onEasterEggFinished: () -> Unit,
modifier: Modifier = Modifier,
@@ -150,7 +89,7 @@ private fun TouchpadGesturesHandlingBox(
.pointerInteropFilter(
onTouchEvent = { event ->
// FINISHED is the final state so we don't need to process touches anymore
- if (gestureState is Finished) {
+ if (tutorialState is TutorialActionState.Finished) {
false
} else {
motionEventConsumer(event)
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 4f1f40dc4c05..4acdb6070200 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
@@ -49,7 +49,7 @@ fun HomeGestureTutorialScreen(
)
GestureTutorialScreen(
screenConfig = screenConfig,
- gestureUiStateFlow = viewModel.gestureUiState,
+ tutorialStateFlow = viewModel.tutorialState,
motionEventConsumer = {
easterEggGestureViewModel.accept(it)
viewModel.handleEvent(it)
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 6c9e26c4b7ea..8dd53a7fb815 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
@@ -50,7 +50,7 @@ fun RecentAppsGestureTutorialScreen(
)
GestureTutorialScreen(
screenConfig = screenConfig,
- gestureUiStateFlow = viewModel.gestureUiState,
+ tutorialStateFlow = viewModel.tutorialState,
motionEventConsumer = {
easterEggGestureViewModel.accept(it)
viewModel.handleEvent(it)
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 8e53669a7841..7a3d4d1ba88a 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
@@ -17,12 +17,12 @@
package com.android.systemui.touchpad.tutorial.ui.viewmodel
import android.view.MotionEvent
+import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialActionState
import com.android.systemui.res.R
-import com.android.systemui.touchpad.tutorial.ui.composable.GestureUiState
-import com.android.systemui.touchpad.tutorial.ui.composable.toGestureUiState
import com.android.systemui.touchpad.tutorial.ui.gesture.GestureDirection
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.GestureState.NotStarted
import com.android.systemui.touchpad.tutorial.ui.gesture.handleTouchpadMotionEvent
import com.android.systemui.util.kotlin.pairwiseBy
import kotlinx.coroutines.flow.Flow
@@ -30,21 +30,26 @@ import kotlinx.coroutines.flow.Flow
class BackGestureScreenViewModel(val gestureRecognizer: GestureRecognizerAdapter) :
TouchpadTutorialScreenViewModel {
- override val gestureUiState: Flow<GestureUiState> =
- gestureRecognizer.gestureState.pairwiseBy(GestureState.NotStarted) { previous, current ->
- toGestureUiState(current, previous)
- }
+ override val tutorialState: Flow<TutorialActionState> =
+ gestureRecognizer.gestureState
+ .pairwiseBy(NotStarted) { previous, current ->
+ current to toAnimationProperties(current, previous)
+ }
+ .mapToTutorialState()
override fun handleEvent(event: MotionEvent): Boolean {
return gestureRecognizer.handleTouchpadMotionEvent(event)
}
- private fun toGestureUiState(current: GestureState, previous: GestureState): GestureUiState {
+ private fun toAnimationProperties(
+ current: GestureState,
+ previous: GestureState,
+ ): TutorialAnimationProperties {
val (startMarker, endMarker) =
if (current is InProgress && current.direction == GestureDirection.LEFT) {
"gesture to L" to "end progress L"
} else "gesture to R" to "end progress R"
- return current.toGestureUiState(
+ return TutorialAnimationProperties(
progressStartMarker = startMarker,
progressEndMarker = endMarker,
successAnimation = successAnimation(previous),
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 9d6f568fa1b1..c75d44f01e8c 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
@@ -17,9 +17,8 @@
package com.android.systemui.touchpad.tutorial.ui.viewmodel
import android.view.MotionEvent
+import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialActionState
import com.android.systemui.res.R
-import com.android.systemui.touchpad.tutorial.ui.composable.GestureUiState
-import com.android.systemui.touchpad.tutorial.ui.composable.toGestureUiState
import com.android.systemui.touchpad.tutorial.ui.gesture.handleTouchpadMotionEvent
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
@@ -27,14 +26,17 @@ import kotlinx.coroutines.flow.map
class HomeGestureScreenViewModel(private val gestureRecognizer: GestureRecognizerAdapter) :
TouchpadTutorialScreenViewModel {
- override val gestureUiState: Flow<GestureUiState> =
- gestureRecognizer.gestureState.map {
- it.toGestureUiState(
- progressStartMarker = "drag with gesture",
- progressEndMarker = "release playback realtime",
- successAnimation = R.raw.trackpad_home_success,
- )
- }
+ override val tutorialState: Flow<TutorialActionState> =
+ gestureRecognizer.gestureState
+ .map {
+ it to
+ TutorialAnimationProperties(
+ progressStartMarker = "drag with gesture",
+ progressEndMarker = "release playback realtime",
+ successAnimation = R.raw.trackpad_home_success,
+ )
+ }
+ .mapToTutorialState()
override fun handleEvent(event: MotionEvent): Boolean {
return gestureRecognizer.handleTouchpadMotionEvent(event)
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 97528583277f..9fab5f3641a4 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
@@ -17,9 +17,8 @@
package com.android.systemui.touchpad.tutorial.ui.viewmodel
import android.view.MotionEvent
+import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialActionState
import com.android.systemui.res.R
-import com.android.systemui.touchpad.tutorial.ui.composable.GestureUiState
-import com.android.systemui.touchpad.tutorial.ui.composable.toGestureUiState
import com.android.systemui.touchpad.tutorial.ui.gesture.handleTouchpadMotionEvent
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
@@ -27,14 +26,17 @@ import kotlinx.coroutines.flow.map
class RecentAppsGestureScreenViewModel(private val gestureRecognizer: GestureRecognizerAdapter) :
TouchpadTutorialScreenViewModel {
- override val gestureUiState: Flow<GestureUiState> =
- gestureRecognizer.gestureState.map {
- it.toGestureUiState(
- progressStartMarker = "drag with gesture",
- progressEndMarker = "onPause",
- successAnimation = R.raw.trackpad_recent_apps_success,
- )
- }
+ override val tutorialState: Flow<TutorialActionState> =
+ gestureRecognizer.gestureState
+ .map {
+ it to
+ TutorialAnimationProperties(
+ progressStartMarker = "drag with gesture",
+ progressEndMarker = "onPause",
+ successAnimation = R.raw.trackpad_recent_apps_success,
+ )
+ }
+ .mapToTutorialState()
override fun handleEvent(event: MotionEvent): Boolean {
return gestureRecognizer.handleTouchpadMotionEvent(event)
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/TouchpadTutorialScreenViewModel.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/TouchpadTutorialScreenViewModel.kt
index 31e953d6643c..3b6e3c76cdeb 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/TouchpadTutorialScreenViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/TouchpadTutorialScreenViewModel.kt
@@ -17,11 +17,62 @@
package com.android.systemui.touchpad.tutorial.ui.viewmodel
import android.view.MotionEvent
-import com.android.systemui.touchpad.tutorial.ui.composable.GestureUiState
+import androidx.annotation.RawRes
+import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialActionState
+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 kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flow
interface TouchpadTutorialScreenViewModel {
- val gestureUiState: Flow<GestureUiState>
+ val tutorialState: Flow<TutorialActionState>
fun handleEvent(event: MotionEvent): Boolean
}
+
+data class TutorialAnimationProperties(
+ val progressStartMarker: String,
+ val progressEndMarker: String,
+ @RawRes val successAnimation: Int,
+)
+
+fun Flow<Pair<GestureState, TutorialAnimationProperties>>.mapToTutorialState():
+ Flow<TutorialActionState> {
+ return flow<TutorialActionState> {
+ var lastState: TutorialActionState = TutorialActionState.NotStarted
+ collect { (gestureState, animationProperties) ->
+ val newState = gestureState.toTutorialActionState(animationProperties, lastState)
+ lastState = newState
+ emit(newState)
+ }
+ }
+}
+
+fun GestureState.toTutorialActionState(
+ properties: TutorialAnimationProperties,
+ previousState: TutorialActionState,
+): TutorialActionState {
+ return when (this) {
+ NotStarted -> TutorialActionState.NotStarted
+ is InProgress -> {
+ val inProgress =
+ TutorialActionState.InProgress(
+ progress = progress,
+ startMarker = properties.progressStartMarker,
+ endMarker = properties.progressEndMarker,
+ )
+ if (
+ previousState is TutorialActionState.InProgressAfterError ||
+ previousState is TutorialActionState.Error
+ ) {
+ TutorialActionState.InProgressAfterError(inProgress)
+ } else {
+ inProgress
+ }
+ }
+ is Finished -> TutorialActionState.Finished(properties.successAnimation)
+ GestureState.Error -> TutorialActionState.Error
+ }
+}