summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/GestureHandler.kt5
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt191
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Scene.kt17
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt11
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeToScene.kt78
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneGestureHandlerTest.kt25
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt45
7 files changed, 56 insertions, 316 deletions
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/GestureHandler.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/GestureHandler.kt
index ae7d8f599b91..d005413fcbcf 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/GestureHandler.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/GestureHandler.kt
@@ -2,6 +2,7 @@ package com.android.compose.animation.scene
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
+import kotlinx.coroutines.CoroutineScope
interface GestureHandler {
val draggable: DraggableHandler
@@ -9,9 +10,9 @@ interface GestureHandler {
}
interface DraggableHandler {
- fun onDragStarted(startedPosition: Offset, pointersDown: Int = 1)
+ suspend fun onDragStarted(coroutineScope: CoroutineScope, startedPosition: Offset)
fun onDelta(pixels: Float)
- fun onDragStopped(velocity: Float)
+ suspend fun onDragStopped(coroutineScope: CoroutineScope, velocity: Float)
}
interface NestedScrollHandler {
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt
deleted file mode 100644
index 97d3fff48b23..000000000000
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (C) 2023 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.compose.animation.scene
-
-import androidx.compose.foundation.gestures.Orientation
-import androidx.compose.foundation.gestures.awaitEachGesture
-import androidx.compose.foundation.gestures.awaitFirstDown
-import androidx.compose.foundation.gestures.awaitHorizontalTouchSlopOrCancellation
-import androidx.compose.foundation.gestures.awaitVerticalTouchSlopOrCancellation
-import androidx.compose.foundation.gestures.horizontalDrag
-import androidx.compose.foundation.gestures.verticalDrag
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.remember
-import androidx.compose.runtime.rememberUpdatedState
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.geometry.Offset
-import androidx.compose.ui.input.pointer.PointerEventPass
-import androidx.compose.ui.input.pointer.PointerId
-import androidx.compose.ui.input.pointer.PointerInputChange
-import androidx.compose.ui.input.pointer.PointerInputScope
-import androidx.compose.ui.input.pointer.pointerInput
-import androidx.compose.ui.input.pointer.positionChange
-import androidx.compose.ui.input.pointer.util.VelocityTracker
-import androidx.compose.ui.input.pointer.util.addPointerInputChange
-import androidx.compose.ui.platform.LocalViewConfiguration
-import androidx.compose.ui.unit.Velocity
-import androidx.compose.ui.util.fastForEach
-
-/**
- * Make an element draggable in the given [orientation].
- *
- * The main difference with [multiPointerDraggable] and
- * [androidx.compose.foundation.gestures.draggable] is that [onDragStarted] also receives the number
- * of pointers that are down when the drag is started. If you don't need this information, you
- * should use `draggable` instead.
- *
- * Note that the current implementation is trivial: we wait for the touch slope on the *first* down
- * pointer, then we count the number of distinct pointers that are down right before calling
- * [onDragStarted]. This means that the drag won't start when a first pointer is down (but not
- * dragged) and a second pointer is down and dragged. This is an implementation detail that might
- * change in the future.
- */
-// TODO(b/291055080): Migrate to the Modifier.Node API.
-@Composable
-internal fun Modifier.multiPointerDraggable(
- orientation: Orientation,
- enabled: Boolean,
- startDragImmediately: Boolean,
- onDragStarted: (startedPosition: Offset, pointersDown: Int) -> Unit,
- onDragDelta: (Float) -> Unit,
- onDragStopped: (velocity: Float) -> Unit,
-): Modifier {
- val onDragStarted by rememberUpdatedState(onDragStarted)
- val onDragStopped by rememberUpdatedState(onDragStopped)
- val onDragDelta by rememberUpdatedState(onDragDelta)
- val startDragImmediately by rememberUpdatedState(startDragImmediately)
-
- val velocityTracker = remember { VelocityTracker() }
- val maxFlingVelocity =
- LocalViewConfiguration.current.maximumFlingVelocity.let { max ->
- val maxF = max.toFloat()
- Velocity(maxF, maxF)
- }
-
- return this.pointerInput(enabled, orientation, maxFlingVelocity) {
- if (!enabled) {
- return@pointerInput
- }
-
- val onDragStart: (Offset, Int) -> Unit = { startedPosition, pointersDown ->
- velocityTracker.resetTracking()
- onDragStarted(startedPosition, pointersDown)
- }
-
- val onDragCancel: () -> Unit = { onDragStopped(/* velocity= */ 0f) }
-
- val onDragEnd: () -> Unit = {
- val velocity = velocityTracker.calculateVelocity(maxFlingVelocity)
- onDragStopped(
- when (orientation) {
- Orientation.Horizontal -> velocity.x
- Orientation.Vertical -> velocity.y
- }
- )
- }
-
- val onDrag: (change: PointerInputChange, dragAmount: Float) -> Unit = { change, amount ->
- velocityTracker.addPointerInputChange(change)
- onDragDelta(amount)
- }
-
- detectDragGestures(
- orientation = orientation,
- startDragImmediately = { startDragImmediately },
- onDragStart = onDragStart,
- onDragEnd = onDragEnd,
- onDragCancel = onDragCancel,
- onDrag = onDrag,
- )
- }
-}
-
-/**
- * Detect drag gestures in the given [orientation].
- *
- * This function is a mix of [androidx.compose.foundation.gestures.awaitDownAndSlop] and
- * [androidx.compose.foundation.gestures.detectVerticalDragGestures] to add support for:
- * 1) starting the gesture immediately without requiring a drag >= touch slope;
- * 2) passing the number of pointers down to [onDragStart].
- */
-private suspend fun PointerInputScope.detectDragGestures(
- orientation: Orientation,
- startDragImmediately: () -> Boolean,
- onDragStart: (startedPosition: Offset, pointersDown: Int) -> Unit,
- onDragEnd: () -> Unit,
- onDragCancel: () -> Unit,
- onDrag: (change: PointerInputChange, dragAmount: Float) -> Unit,
-) {
- awaitEachGesture {
- val initialDown = awaitFirstDown(requireUnconsumed = false, pass = PointerEventPass.Initial)
- var overSlop = 0f
- val drag =
- if (startDragImmediately()) {
- initialDown.consume()
- initialDown
- } else {
- val down = awaitFirstDown(requireUnconsumed = false)
- val onSlopReached = { change: PointerInputChange, over: Float ->
- change.consume()
- overSlop = over
- }
-
- // TODO(b/291055080): Replace by await[Orientation]PointerSlopOrCancellation once
- // it is public.
- when (orientation) {
- Orientation.Horizontal ->
- awaitHorizontalTouchSlopOrCancellation(down.id, onSlopReached)
- Orientation.Vertical ->
- awaitVerticalTouchSlopOrCancellation(down.id, onSlopReached)
- }
- }
-
- if (drag != null) {
- // Count the number of pressed pointers.
- val pressed = mutableSetOf<PointerId>()
- currentEvent.changes.fastForEach { change ->
- if (change.pressed) {
- pressed.add(change.id)
- }
- }
-
- onDragStart(drag.position, pressed.size)
- onDrag(drag, overSlop)
-
- val successful =
- when (orientation) {
- Orientation.Horizontal ->
- horizontalDrag(drag.id) {
- onDrag(it, it.positionChange().x)
- it.consume()
- }
- Orientation.Vertical ->
- verticalDrag(drag.id) {
- onDrag(it, it.positionChange().y)
- it.consume()
- }
- }
-
- if (successful) {
- onDragEnd()
- } else {
- onDragCancel()
- }
- }
- }
-}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Scene.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Scene.kt
index 3fd6828fca6b..9c799b282571 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Scene.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Scene.kt
@@ -16,6 +16,7 @@
package com.android.compose.animation.scene
+import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
@@ -100,3 +101,19 @@ private class SceneScopeImpl(
MovableElement(layoutImpl, scene, key, modifier, content)
}
}
+
+/** The destination scene when swiping up or left from [upOrLeft]. */
+internal fun Scene.upOrLeft(orientation: Orientation): SceneKey? {
+ return when (orientation) {
+ Orientation.Vertical -> userActions[Swipe.Up]
+ Orientation.Horizontal -> userActions[Swipe.Left]
+ }
+}
+
+/** The destination scene when swiping down or right from [downOrRight]. */
+internal fun Scene.downOrRight(orientation: Orientation): SceneKey? {
+ return when (orientation) {
+ Orientation.Vertical -> userActions[Swipe.Down]
+ Orientation.Horizontal -> userActions[Swipe.Right]
+ }
+}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
index 4a1d73dbfcb1..74e66d2a9949 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
@@ -16,7 +16,6 @@
package com.android.compose.animation.scene
-import androidx.compose.foundation.gestures.Orientation
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.runtime.remember
@@ -192,9 +191,9 @@ data class Swipe(
}
}
-enum class SwipeDirection(val orientation: Orientation) {
- Up(Orientation.Vertical),
- Down(Orientation.Vertical),
- Left(Orientation.Horizontal),
- Right(Orientation.Horizontal),
+enum class SwipeDirection {
+ Up,
+ Down,
+ Left,
+ Right,
}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeToScene.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeToScene.kt
index 25b5db5c7506..2dc53ab8bf76 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeToScene.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeToScene.kt
@@ -22,6 +22,8 @@ import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.spring
import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.foundation.gestures.draggable
+import androidx.compose.foundation.gestures.rememberDraggableState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
@@ -53,7 +55,7 @@ internal fun Modifier.swipeToScene(
/** Whether swipe should be enabled in the given [orientation]. */
fun Scene.shouldEnableSwipes(orientation: Orientation): Boolean =
- userActions.keys.any { it is Swipe && it.direction.orientation == orientation }
+ upOrLeft(orientation) != null || downOrRight(orientation) != null
val currentScene = gestureHandler.currentScene
val canSwipe = currentScene.shouldEnableSwipes(orientation)
@@ -66,7 +68,8 @@ internal fun Modifier.swipeToScene(
)
return nestedScroll(connection = gestureHandler.nestedScroll.connection)
- .multiPointerDraggable(
+ .draggable(
+ state = rememberDraggableState(onDelta = gestureHandler.draggable::onDelta),
orientation = orientation,
enabled = gestureHandler.isDrivingTransition || canSwipe,
// Immediately start the drag if this our [transition] is currently animating to a scene
@@ -77,7 +80,6 @@ internal fun Modifier.swipeToScene(
gestureHandler.isAnimatingOffset &&
!canOppositeSwipe,
onDragStarted = gestureHandler.draggable::onDragStarted,
- onDragDelta = gestureHandler.draggable::onDelta,
onDragStopped = gestureHandler.draggable::onDragStopped,
)
}
@@ -157,7 +159,7 @@ class SceneGestureHandler(
internal var gestureWithPriority: Any? = null
- internal fun onDragStarted(pointersDown: Int) {
+ internal fun onDragStarted() {
if (isDrivingTransition) {
// This [transition] was already driving the animation: simply take over it.
// Stop animating and start from where the current offset.
@@ -197,26 +199,6 @@ class SceneGestureHandler(
Orientation.Vertical -> layoutImpl.size.height
}.toFloat()
- swipeTransition.actionUpOrLeft =
- Swipe(
- direction =
- when (orientation) {
- Orientation.Horizontal -> SwipeDirection.Left
- Orientation.Vertical -> SwipeDirection.Up
- },
- pointerCount = pointersDown,
- )
-
- swipeTransition.actionDownOrRight =
- Swipe(
- direction =
- when (orientation) {
- Orientation.Horizontal -> SwipeDirection.Right
- Orientation.Vertical -> SwipeDirection.Down
- },
- pointerCount = pointersDown,
- )
-
if (swipeTransition.absoluteDistance > 0f) {
transitionState = swipeTransition
}
@@ -264,15 +246,11 @@ class SceneGestureHandler(
// to the next screen or go back to the previous one.
val offset = swipeTransition.dragOffset
val absoluteDistance = swipeTransition.absoluteDistance
- if (
- offset <= -absoluteDistance &&
- fromScene.userActions[swipeTransition.actionUpOrLeft] == toScene.key
- ) {
+ if (offset <= -absoluteDistance && fromScene.upOrLeft(orientation) == toScene.key) {
swipeTransition.dragOffset += absoluteDistance
swipeTransition._fromScene = toScene
} else if (
- offset >= absoluteDistance &&
- fromScene.userActions[swipeTransition.actionDownOrRight] == toScene.key
+ offset >= absoluteDistance && fromScene.downOrRight(orientation) == toScene.key
) {
swipeTransition.dragOffset -= absoluteDistance
swipeTransition._fromScene = toScene
@@ -294,8 +272,8 @@ class SceneGestureHandler(
Orientation.Vertical -> layoutImpl.size.height
}.toFloat()
- val upOrLeft = userActions[swipeTransition.actionUpOrLeft]
- val downOrRight = userActions[swipeTransition.actionDownOrRight]
+ val upOrLeft = upOrLeft(orientation)
+ val downOrRight = downOrRight(orientation)
// Compute the target scene depending on the current offset.
return when {
@@ -538,10 +516,6 @@ class SceneGestureHandler(
var _distance by mutableFloatStateOf(0f)
val distance: Float
get() = _distance
-
- /** The [UserAction]s associated to this swipe. */
- var actionUpOrLeft: UserAction = Back
- var actionDownOrRight: UserAction = Back
}
companion object {
@@ -552,9 +526,9 @@ class SceneGestureHandler(
private class SceneDraggableHandler(
private val gestureHandler: SceneGestureHandler,
) : DraggableHandler {
- override fun onDragStarted(startedPosition: Offset, pointersDown: Int) {
+ override suspend fun onDragStarted(coroutineScope: CoroutineScope, startedPosition: Offset) {
gestureHandler.gestureWithPriority = this
- gestureHandler.onDragStarted(pointersDown)
+ gestureHandler.onDragStarted()
}
override fun onDelta(pixels: Float) {
@@ -563,7 +537,7 @@ private class SceneDraggableHandler(
}
}
- override fun onDragStopped(velocity: Float) {
+ override suspend fun onDragStopped(coroutineScope: CoroutineScope, velocity: Float) {
if (gestureHandler.gestureWithPriority == this) {
gestureHandler.gestureWithPriority = null
gestureHandler.onDragStopped(velocity = velocity, canChangeScene = true)
@@ -606,31 +580,11 @@ class SceneNestedScrollHandler(
// moving on to the next scene.
var gestureStartedOnNestedChild = false
- val actionUpOrLeft =
- Swipe(
- direction =
- when (gestureHandler.orientation) {
- Orientation.Horizontal -> SwipeDirection.Left
- Orientation.Vertical -> SwipeDirection.Up
- },
- pointerCount = 1,
- )
-
- val actionDownOrRight =
- Swipe(
- direction =
- when (gestureHandler.orientation) {
- Orientation.Horizontal -> SwipeDirection.Right
- Orientation.Vertical -> SwipeDirection.Down
- },
- pointerCount = 1,
- )
-
fun findNextScene(amount: Float): SceneKey? {
val fromScene = gestureHandler.currentScene
return when {
- amount < 0f -> fromScene.userActions[actionUpOrLeft]
- amount > 0f -> fromScene.userActions[actionDownOrRight]
+ amount < 0f -> fromScene.upOrLeft(gestureHandler.orientation)
+ amount > 0f -> fromScene.downOrRight(gestureHandler.orientation)
else -> null
}
}
@@ -671,7 +625,7 @@ class SceneNestedScrollHandler(
onStart = {
gestureHandler.gestureWithPriority = this
priorityScene = nextScene
- gestureHandler.onDragStarted(pointersDown = 1)
+ gestureHandler.onDragStarted()
},
onScroll = { offsetAvailable ->
if (gestureHandler.gestureWithPriority != this) {
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneGestureHandlerTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneGestureHandlerTest.kt
index 4b3fbdf77274..6791a85ff21c 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneGestureHandlerTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneGestureHandlerTest.kt
@@ -104,13 +104,13 @@ class SceneGestureHandlerTest {
@Test
fun onDragStarted_shouldStartATransition() = runGestureTest {
- draggable.onDragStarted(startedPosition = Offset.Zero)
+ draggable.onDragStarted(coroutineScope = coroutineScope, startedPosition = Offset.Zero)
assertScene(currentScene = SceneA, isIdle = false)
}
@Test
fun afterSceneTransitionIsStarted_interceptDragEvents() = runGestureTest {
- draggable.onDragStarted(startedPosition = Offset.Zero)
+ draggable.onDragStarted(coroutineScope = coroutineScope, startedPosition = Offset.Zero)
assertScene(currentScene = SceneA, isIdle = false)
val transition = transitionState as Transition
@@ -123,13 +123,14 @@ class SceneGestureHandlerTest {
@Test
fun onDragStoppedAfterDrag_velocityLowerThanThreshold_remainSameScene() = runGestureTest {
- draggable.onDragStarted(startedPosition = Offset.Zero)
+ draggable.onDragStarted(coroutineScope = coroutineScope, startedPosition = Offset.Zero)
assertScene(currentScene = SceneA, isIdle = false)
draggable.onDelta(pixels = deltaInPixels10)
assertScene(currentScene = SceneA, isIdle = false)
draggable.onDragStopped(
+ coroutineScope = coroutineScope,
velocity = velocityThreshold - 0.01f,
)
assertScene(currentScene = SceneA, isIdle = false)
@@ -141,13 +142,14 @@ class SceneGestureHandlerTest {
@Test
fun onDragStoppedAfterDrag_velocityAtLeastThreshold_goToNextScene() = runGestureTest {
- draggable.onDragStarted(startedPosition = Offset.Zero)
+ draggable.onDragStarted(coroutineScope = coroutineScope, startedPosition = Offset.Zero)
assertScene(currentScene = SceneA, isIdle = false)
draggable.onDelta(pixels = deltaInPixels10)
assertScene(currentScene = SceneA, isIdle = false)
draggable.onDragStopped(
+ coroutineScope = coroutineScope,
velocity = velocityThreshold,
)
assertScene(currentScene = SceneC, isIdle = false)
@@ -159,22 +161,23 @@ class SceneGestureHandlerTest {
@Test
fun onDragStoppedAfterStarted_returnImmediatelyToIdle() = runGestureTest {
- draggable.onDragStarted(startedPosition = Offset.Zero)
+ draggable.onDragStarted(coroutineScope = coroutineScope, startedPosition = Offset.Zero)
assertScene(currentScene = SceneA, isIdle = false)
- draggable.onDragStopped(velocity = 0f)
+ draggable.onDragStopped(coroutineScope = coroutineScope, velocity = 0f)
assertScene(currentScene = SceneA, isIdle = true)
}
@Test
fun startGestureDuringAnimatingOffset_shouldImmediatelyStopTheAnimation() = runGestureTest {
- draggable.onDragStarted(startedPosition = Offset.Zero)
+ draggable.onDragStarted(coroutineScope = coroutineScope, startedPosition = Offset.Zero)
assertScene(currentScene = SceneA, isIdle = false)
draggable.onDelta(pixels = deltaInPixels10)
assertScene(currentScene = SceneA, isIdle = false)
draggable.onDragStopped(
+ coroutineScope = coroutineScope,
velocity = velocityThreshold,
)
@@ -188,7 +191,7 @@ class SceneGestureHandlerTest {
assertScene(currentScene = SceneC, isIdle = false)
// Start a new gesture while the offset is animating
- draggable.onDragStarted(startedPosition = Offset.Zero)
+ draggable.onDragStarted(coroutineScope = coroutineScope, startedPosition = Offset.Zero)
assertThat(sceneGestureHandler.isAnimatingOffset).isFalse()
}
@@ -317,7 +320,7 @@ class SceneGestureHandlerTest {
}
@Test
fun beforeDraggableStart_stop_shouldBeIgnored() = runGestureTest {
- draggable.onDragStopped(velocityThreshold)
+ draggable.onDragStopped(coroutineScope, velocityThreshold)
assertScene(currentScene = SceneA, isIdle = true)
}
@@ -329,7 +332,7 @@ class SceneGestureHandlerTest {
@Test
fun startNestedScrollWhileDragging() = runGestureTest {
- draggable.onDragStarted(Offset.Zero)
+ draggable.onDragStarted(coroutineScope, Offset.Zero)
assertScene(currentScene = SceneA, isIdle = false)
val transition = transitionState as Transition
@@ -341,7 +344,7 @@ class SceneGestureHandlerTest {
assertThat(transition.progress).isEqualTo(0.2f)
// this should be ignored, we are scrolling now!
- draggable.onDragStopped(velocityThreshold)
+ draggable.onDragStopped(coroutineScope, velocityThreshold)
assertScene(currentScene = SceneA, isIdle = false)
nestedScrollEvents(available = offsetY10)
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt
index 6ad2108c05a5..df3b72aa5533 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt
@@ -83,11 +83,7 @@ class SwipeToSceneTest {
}
scene(
TestScenes.SceneC,
- userActions =
- mapOf(
- Swipe.Down to TestScenes.SceneA,
- Swipe(SwipeDirection.Down, pointerCount = 2) to TestScenes.SceneB,
- ),
+ userActions = mapOf(Swipe.Down to TestScenes.SceneA),
) {
Box(Modifier.fillMaxSize())
}
@@ -246,43 +242,4 @@ class SwipeToSceneTest {
assertThat(layoutState.transitionState).isInstanceOf(TransitionState.Idle::class.java)
assertThat(layoutState.transitionState.currentScene).isEqualTo(TestScenes.SceneC)
}
-
- @Test
- fun multiPointerSwipe() {
- // Start at scene C.
- currentScene = TestScenes.SceneC
-
- // The draggable touch slop, i.e. the min px distance a touch pointer must move before it is
- // detected as a drag event.
- var touchSlop = 0f
- rule.setContent {
- touchSlop = LocalViewConfiguration.current.touchSlop
- TestContent()
- }
-
- assertThat(layoutState.transitionState).isInstanceOf(TransitionState.Idle::class.java)
- assertThat(layoutState.transitionState.currentScene).isEqualTo(TestScenes.SceneC)
-
- // Swipe down with two fingers.
- rule.onRoot().performTouchInput {
- repeat(2) { i -> down(pointerId = i, middle) }
- repeat(2) { i ->
- moveBy(pointerId = i, Offset(0f, touchSlop + 10.dp.toPx()), delayMillis = 1_000)
- }
- }
-
- // We are transitioning to B because we used 2 fingers.
- val transition = layoutState.transitionState
- assertThat(transition).isInstanceOf(TransitionState.Transition::class.java)
- assertThat((transition as TransitionState.Transition).fromScene)
- .isEqualTo(TestScenes.SceneC)
- assertThat(transition.toScene).isEqualTo(TestScenes.SceneB)
-
- // Release the fingers and wait for the animation to end. We are back to C because we only
- // swiped 10dp.
- rule.onRoot().performTouchInput { repeat(2) { i -> up(pointerId = i) } }
- rule.waitForIdle()
- assertThat(layoutState.transitionState).isInstanceOf(TransitionState.Idle::class.java)
- assertThat(layoutState.transitionState.currentScene).isEqualTo(TestScenes.SceneC)
- }
}