diff options
| author | 2024-07-11 14:44:41 +0000 | |
|---|---|---|
| committer | 2024-07-11 14:44:41 +0000 | |
| commit | d441a8bcdd1032b4d1bcfee2da0c8e6df3979d7e (patch) | |
| tree | 2773e7ba21e57cc86216396ef315c7c2e6698146 | |
| parent | 218de6a5d66480f0f366cb5e717976a1ba9912a9 (diff) | |
multiPointerDraggable set an order for PointerEventScopes
The order is important here: we want to make sure that the previous
PointerEventScope is initialized first. This ensures that the following
PointerEventScope doesn't receive more events than the first one.
Test: A lot of manual testing (Hard to reproduce it, seems a race condition)
Bug: 352522308
Flag: com.android.systemui.scene_container
Change-Id: Iba816edd0cd3a62c3acc8ee3ff5af746b0293905
| -rw-r--r-- | packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt | 81 |
1 files changed, 44 insertions, 37 deletions
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 index cdcfc84ce92a..615d393f8bee 100644 --- 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 @@ -241,43 +241,50 @@ internal class MultiPointerDraggableNode( } } - awaitPointerEventScope { - while (isActive) { - try { - detectDragGestures( - orientation = orientation, - startDragImmediately = startDragImmediately, - onDragStart = { startedPosition, overSlop, pointersDown -> - velocityTracker.resetTracking() - onDragStarted(startedPosition, overSlop, pointersDown) - }, - onDrag = { controller, change, amount -> - velocityTracker.addPointerInputChange(change) - controller.onDrag(amount) - }, - onDragEnd = { controller -> - val viewConfiguration = currentValueOf(LocalViewConfiguration) - val maxVelocity = - viewConfiguration.maximumFlingVelocity.let { Velocity(it, it) } - val velocity = velocityTracker.calculateVelocity(maxVelocity) - controller.onStop( - velocity = - when (orientation) { - Orientation.Horizontal -> velocity.x - Orientation.Vertical -> velocity.y - }, - canChangeScene = true, - ) - }, - onDragCancel = { controller -> - controller.onStop(velocity = 0f, canChangeScene = true) - }, - swipeDetector = swipeDetector - ) - } catch (exception: CancellationException) { - // If the coroutine scope is active, we can just restart the drag cycle. - if (!isActive) { - throw exception + // The order is important here: we want to make sure that the previous PointerEventScope + // is initialized first. This ensures that the following PointerEventScope doesn't + // receive more events than the first one. + launch { + awaitPointerEventScope { + while (isActive) { + try { + detectDragGestures( + orientation = orientation, + startDragImmediately = startDragImmediately, + onDragStart = { startedPosition, overSlop, pointersDown -> + velocityTracker.resetTracking() + onDragStarted(startedPosition, overSlop, pointersDown) + }, + onDrag = { controller, change, amount -> + velocityTracker.addPointerInputChange(change) + controller.onDrag(amount) + }, + onDragEnd = { controller -> + val viewConfiguration = currentValueOf(LocalViewConfiguration) + val maxVelocity = + viewConfiguration.maximumFlingVelocity.let { + Velocity(it, it) + } + val velocity = velocityTracker.calculateVelocity(maxVelocity) + controller.onStop( + velocity = + when (orientation) { + Orientation.Horizontal -> velocity.x + Orientation.Vertical -> velocity.y + }, + canChangeScene = true, + ) + }, + onDragCancel = { controller -> + controller.onStop(velocity = 0f, canChangeScene = true) + }, + swipeDetector = swipeDetector + ) + } catch (exception: CancellationException) { + // If the coroutine scope is active, we can just restart the drag cycle. + if (!isActive) { + throw exception + } } } } |