From d441a8bcdd1032b4d1bcfee2da0c8e6df3979d7e Mon Sep 17 00:00:00 2001 From: omarmt Date: Thu, 11 Jul 2024 14:44:41 +0000 Subject: 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 --- .../animation/scene/MultiPointerDraggable.kt | 81 ++++++++++++---------- 1 file 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 + } } } } -- cgit v1.2.3-59-g8ed1b