@@ -447,8 +447,8 @@ private int getPointerDeviceTypeForToolType(int toolType) {
447447 }
448448 }
449449
450- private void addPointerForIndex (MotionEvent event , int pointerIndex , ByteBuffer packet ) {
451- int pointerChange = getPointerChangeForAction ( event . getActionMasked ());
450+ private void addPointerForIndex (MotionEvent event , int pointerIndex , int pointerChange ,
451+ int pointerData , ByteBuffer packet ) {
452452 if (pointerChange == -1 ) {
453453 return ;
454454 }
@@ -503,6 +503,8 @@ private void addPointerForIndex(MotionEvent event, int pointerIndex, ByteBuffer
503503 } else {
504504 packet .putDouble (0.0 ); // tilt
505505 }
506+
507+ packet .putLong (pointerData ); // platformData
506508 }
507509
508510 @ Override
@@ -521,26 +523,44 @@ public boolean onTouchEvent(MotionEvent event) {
521523 }
522524
523525 // These values must match the unpacking code in hooks.dart.
524- final int kPointerDataFieldCount = 20 ;
526+ final int kPointerDataFieldCount = 21 ;
525527 final int kBytePerField = 8 ;
526528
529+ // This value must match the value in framework's platform_view.dart.
530+ // This flag indicates whether the original Android pointer events were batched together.
531+ final int kPointerDataFlagBatched = 1 ;
532+
527533 int pointerCount = event .getPointerCount ();
528534
529535 ByteBuffer packet = ByteBuffer .allocateDirect (pointerCount * kPointerDataFieldCount * kBytePerField );
530536 packet .order (ByteOrder .LITTLE_ENDIAN );
531537
532538 int maskedAction = event .getActionMasked ();
533- // ACTION_UP, ACTION_POINTER_UP, ACTION_DOWN, and ACTION_POINTER_DOWN
534- // only apply to a single pointer, other events apply to all pointers.
535- if (maskedAction == MotionEvent .ACTION_UP || maskedAction == MotionEvent .ACTION_POINTER_UP
536- || maskedAction == MotionEvent .ACTION_DOWN || maskedAction == MotionEvent .ACTION_POINTER_DOWN ) {
537- addPointerForIndex (event , event .getActionIndex (), packet );
539+ int pointerChange = getPointerChangeForAction (event .getActionMasked ());
540+ if (maskedAction == MotionEvent .ACTION_DOWN || maskedAction == MotionEvent .ACTION_POINTER_DOWN ) {
541+ // ACTION_DOWN and ACTION_POINTER_DOWN always apply to a single pointer only.
542+ addPointerForIndex (event , event .getActionIndex (), pointerChange , 0 , packet );
543+ } else if (maskedAction == MotionEvent .ACTION_UP || maskedAction == MotionEvent .ACTION_POINTER_UP ) {
544+ // ACTION_UP and ACTION_POINTER_UP may contain position updates for other pointers.
545+ // We are converting these updates to move events here in order to preserve this data.
546+ // We also mark these events with a flag in order to help the framework reassemble
547+ // the original Android event later, should it need to forward it to a PlatformView.
548+ for (int p = 0 ; p < pointerCount ; p ++) {
549+ if (p != event .getActionIndex ()) {
550+ if (event .getToolType (p ) == MotionEvent .TOOL_TYPE_FINGER ) {
551+ addPointerForIndex (event , p , kPointerChangeMove , kPointerDataFlagBatched , packet );
552+ }
553+ }
554+ }
555+ // It's important that we're sending the UP event last. This allows PlatformView
556+ // to correctly batch everything back into the original Android event if needed.
557+ addPointerForIndex (event , event .getActionIndex (), pointerChange , 0 , packet );
538558 } else {
539559 // ACTION_MOVE may not actually mean all pointers have moved
540560 // but it's the responsibility of a later part of the system to
541561 // ignore 0-deltas if desired.
542562 for (int p = 0 ; p < pointerCount ; p ++) {
543- addPointerForIndex (event , p , packet );
563+ addPointerForIndex (event , p , pointerChange , 0 , packet );
544564 }
545565 }
546566
0 commit comments