Skip to content

Duplicate Multi-touch Events in Android Platform Views #176574

Closed

Description

@evil159

Steps to reproduce

  1. Create a Flutter app with an AndroidView inside GestureDetector with long press callbacks:
  2. In the native Android view, log all MotionEvent actions with timestamps and pointer counts
  3. Perform a pinch/scale gesture

Expected results

I/flutter (28829): Flutter: Long press CANCEL
D/NativeView(28829): Action: ACTION_DOWN, Pointers: 1, Time: 580981037
D/NativeView(28829): Action: ACTION_POINTER_DOWN(1), Pointers: 2, Time: 580981037
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981198
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981235
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981251
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981268
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981285
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981301
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981315
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981335
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981351
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981368
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981385
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981401
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981418
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981432
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981468
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981485
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981501
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981518
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981535
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981551
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981557
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981585
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981601
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981618
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981632
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981678
D/NativeView(28829): Action: ACTION_POINTER_UP(0), Pointers: 2, Time: 580981786

Actual results

I/flutter (28829): Flutter: Long press CANCEL
D/NativeView(28829): Action: ACTION_DOWN, Pointers: 1, Time: 580981037
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981198
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981235
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981251
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981268
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981285
D/NativeView(28829): Action: ACTION_POINTER_DOWN(1), Pointers: 2, Time: 580981037
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981198
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981235
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981251
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981268
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981285
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981301
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981315
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981335
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981351
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981368
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981385
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981401
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981418
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981432
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981468
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981485
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981501
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981518
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981535
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981551
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981557
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981585
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981601
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981618
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981632
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981678
D/NativeView(28829): Action: ACTION_POINTER_UP(0), Pointers: 2, Time: 580981786

Code sample

Code sample
GestureDetector(
    behavior: HitTestBehavior.translucent,
    onLongPressStart: (dt) => _sendLongPressEvent("Long press START"),
    onLongPressCancel: () => _sendLongPressEvent("Long press CANCEL"),
    onLongPressMoveUpdate: (details) => _sendLongPressEvent("Long press UPDATE"),
    onLongPressEnd: (details) => _sendLongPressEvent("Long press END"),
    child: AndroidView(
      viewType: 'native-view',
      layoutDirection: TextDirection.ltr,
    ),
  )

Code sample

Sample project

motion_events.zip

Logs

Logs
I/flutter (28829): Flutter: Long press CANCEL
D/NativeView(28829): Action: ACTION_DOWN, Pointers: 1, Time: 580981037
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981198
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981235
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981251
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981268
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981285
D/NativeView(28829): Action: ACTION_POINTER_DOWN(1), Pointers: 2, Time: 580981037
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981198
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981235
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981251
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981268
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981285
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981301
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981315
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981335
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981351
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981368
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981385
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981401
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981418
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981432
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981468
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981485
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981501
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981518
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981535
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981551
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981557
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981585
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981601
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981618
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981632
D/NativeView(28829): Action: ACTION_MOVE, Pointers: 2, Time: 580981678
D/NativeView(28829): Action: ACTION_POINTER_UP(0), Pointers: 2, Time: 580981786

Flutter Doctor output

Doctor output
[✓] Flutter (Channel stable, 3.35.5, on macOS 26.0.1 25A362 darwin-arm64, locale en-US) [204ms]
    • Flutter version 3.35.5 on channel stable at /Users/romanlaitarenko/Developer/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision ac4e799d23 (10 days ago), 2025-09-26 12:05:09 -0700
    • Engine revision d3d45dcf25
    • Dart version 3.9.2
    • DevTools version 2.48.0
    • Feature flags: enable-web, enable-linux-desktop, enable-macos-desktop, enable-windows-desktop, enable-android, enable-ios, cli-animations, enable-swift-package-manager,
      enable-lldb-debugging

[!] Android toolchain - develop for Android devices (Android SDK version 36.0.0) [759ms]
    • Android SDK at /Users/romanlaitarenko/Library/Android/sdk
    • Emulator version 35.5.10.0 (build_id 13402964) (CL:N/A)
    • Platform android-36, build-tools 36.0.0
    • ANDROID_HOME = /Users/romanlaitarenko/Library/Android/sdk
    • Java binary at: /Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home/bin/java
      This JDK is specified in your Flutter configuration.
      To change the current JDK, run: `flutter config --jdk-dir="path/to/jdk"`.
    • Java version OpenJDK Runtime Environment Temurin-17.0.16+8 (build 17.0.16+8)
    ! Some Android licenses not accepted. To resolve this, run: flutter doctor --android-licenses

[✓] Xcode - develop for iOS and macOS (Xcode 26.0.1) [454ms]
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 17A400
    • CocoaPods version 1.16.2

[✗] Chrome - develop for the web (Cannot find Chrome executable at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome) [8ms]
    ! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable.

[✓] Android Studio (version 2024.3) [8ms]
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 21.0.6+-13368085-b895.109)

[✓] Connected device (4 available) [5.9s]
    • sdk gphone16k arm64 (mobile)           • emulator-5554                        • android-arm64 • Android 15 (API 35) (emulator)
    • Roman’s iPhone (2) (wireless) (mobile) • 00008110-00110D1614F9801E            • ios           • iOS 26.0.1 23A355
    • iPhone 16 Pro (mobile)                 • CCF1D21D-4E0C-423A-870B-005E7F4F2EBD • ios           • com.apple.CoreSimulator.SimRuntime.iOS-18-6 (simulator)
    • macOS (desktop)                        • macos                                • darwin-arm64  • macOS 26.0.1 25A362 darwin-arm64

[✓] Network resources [213ms]
    • All expected network resources are available.

! Doctor found issues in 2 categories.

Activity

  1. tirth-patel-nc commented on Oct 7, 2025

    @tirth-patel-nc
    Member

    @evil159 thanks for the report. Please confirm whether #96640 is related to your case or For us to further investigate this issue, please provide a completed and minimal reproducible code sample that doesn’t include 3rd party plugins or complex production code. Thank you!

  2. added
    waiting for responseThe Flutter team cannot make further progress on this issue until the original reporter responds
    on Oct 7, 2025
  3. evil159 commented on Oct 7, 2025

    @evil159
    Author

    Hi @tirth-patel-nc, thank you for looking into it. I don't believe this issue is related to #96640, this issue is present only on Android and I believe is related to Android-specific motion event replay after gesture arena contest. I have attached a minimal reproducible sample project to the description of the ticket. Please let me know if I can help in any way.

  4. removed
    waiting for responseThe Flutter team cannot make further progress on this issue until the original reporter responds
    on Oct 7, 2025
  5. tirth-patel-nc commented on Oct 8, 2025

    @tirth-patel-nc
    Member

    Thanks for the report. I'm able to reproduce the same behavior as shown in the actual results with the latest SDK versions using provided code sample and steps. I'm not very familiar with PlatformViews and their gesture handling, so I'll leave this to the team for further investigation.

    stable : 3.35.5
    master : 3.37.0-1.0.pre-454
    
    Logs
    I/flutter (22065): Long press CANCEL
    D/NativeView(22065): NativeView: ACTION_DOWN, Pointers: 1, Time: 6464463
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 1, Time: 6464479
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464484
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464508
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464527
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464544
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464561
    D/NativeView(22065): NativeView: ACTION_POINTER_DOWN(1), Pointers: 2, Time: 6464479
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464484
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464508
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464527
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464544
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464561
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464577
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464594
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464611
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464628
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464644
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464661
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464678
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464694
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464711
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464728
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464744
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464761
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464778
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464794
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464811
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464828
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464844
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464861
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464878
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464894
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464911
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464928
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464944
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464961
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464978
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6464995
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465011
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465028
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465045
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465061
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465078
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465095
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465111
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465128
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465145
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465161
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465178
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465195
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465211
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465228
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465245
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465261
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465278
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465295
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465312
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465328
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465345
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465362
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465377
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465395
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465412
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465428
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465440
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465462
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465478
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465495
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465512
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465528
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465544
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465555
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465573
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465595
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465610
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465628
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465645
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465659
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465679
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465685
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465712
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465729
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465745
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465762
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465779
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465795
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465812
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465829
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465845
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465862
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465879
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465895
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465912
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465929
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465945
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465962
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465979
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6465996
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6466012
    D/NativeView(22065): NativeView: ACTION_POINTER_UP(0), Pointers: 2, Time: 6466028
    D/NativeView(22065): NativeView: ACTION_UP, Pointers: 1, Time: 6466028
    I/flutter (22065): Long press CANCEL
    D/NativeView(22065): NativeView: ACTION_DOWN, Pointers: 1, Time: 6466028
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 1, Time: 6466044
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6466062
    I/flutter (22065): Long press CANCEL
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6466065
    D/NativeView(22065): NativeView: ACTION_POINTER_DOWN(1), Pointers: 2, Time: 6466044
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6466062
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 2, Time: 6466065
    D/NativeView(22065): NativeView: ACTION_POINTER_UP(0), Pointers: 2, Time: 6466071
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 1, Time: 6466079
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 1, Time: 6466096
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 1, Time: 6466110
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 1, Time: 6466512
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 1, Time: 6466529
    D/NativeView(22065): NativeView: ACTION_MOVE, Pointers: 1, Time: 6466542
    D/NativeView(22065): NativeView: ACTION_UP, Pointers: 1, Time: 6466546
  6. added
    platform-androidAndroid applications specifically
    team-androidOwned by Android platform team
    has reproducible stepsThe issue has been confirmed reproducible and is ready to work on
    a: platform-viewsEmbedding Android/iOS views in Flutter apps
    frameworkflutter/packages/flutter repository. See also f: labels.
    f: gesturesflutter/packages/flutter/gestures repository.
    and removed
    in triagePresently being triaged by the triage team
    on Oct 8, 2025
  7. evil159 commented on Oct 8, 2025

    @evil159
    Author

    @tirth-patel-nc Thank you for confirming this! One thing to note is that I believe this has started happening in Flutter SDK 3.19.

  8. added
    P2Important issues not at the top of the work list
    triaged-androidTriaged by Android platform team
    on Oct 14, 2025
  9. jason-simmons commented on Nov 1, 2025

    @jason-simmons
    Member

    The embedder's AndroidTouchProcessor converts the original Android touch event into multiple pointer data messages that are sent to the framework.

    The framework will handle the messages and route them to the platform view widget. The framework's _AndroidMotionEventConverter then needs to map the messages back to Android-style events that can be sent to the embedder and forwarded to the Android native view.

    The app is seeing duplicates because _AndroidMotionEventConverter is not recognizing that some messages should be merged into one Android event.

    _AndroidMotionEventConverter.toAndroidMotionEvent determines whether a message is part of a batch by comparing the message's pointer index against the _AndroidMotionEventConverter's internal pointerPositions map of known pointers. If the index is not the last expected index based on the size of pointerPositions, then the _AndroidMotionEventConverter skips that message so that only one event is sent for each batch.

    However, _AndroidMotionEventConverter.pointerPositions can be out of sync with the state of the Android embedder.

    If the AndroidTouchProcessor receives an Android event with two pointers, then it will send a message for pointer index 0 and another message for pointer index 1.
    But if _AndroidMotionEventConverter has not yet seen a message that references pointer index 1, then pointerPositions will only contain one pointer. _AndroidMotionEventConverter.toAndroidMotionEvent will think that pointer index 0 is the last message of the batch, and it will send the message to the embedder.

    Later, when _AndroidMotionEventConverter sees the message about pointer index 1 that was part of the same Android event, it will add that pointer to pointerPositions. _AndroidMotionEventConverter.toAndroidMotionEvent will now think that pointer index 1 is the last message of the batch, and it will also send that message to the embedder.

    The embedder thus receives two messages that originated from the same Android event. The embedder's MotionEventTracker will map both messages back to the same MotionEvent, and the Android native view will receive that event twice.

    One option for fixing this would be adding the number of pointers in the original Android touch event to the message sent to the framework. That would make it unnecessary for the _AndroidMotionEventConverter to infer it from its internal state.

    The message already has a pointerData field that AndroidTouchProcessor uses to send a batching flag in other scenarios. For this class of events, pointerData could encode the Android event's pointer count.

  10. github-actions commented on Nov 25, 2025

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  11. locked as resolved and limited conversation to collaborators on Nov 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work lista: platform-viewsEmbedding Android/iOS views in Flutter appsf: gesturesflutter/packages/flutter/gestures repository.found in release: 3.35Found to occur in 3.35found in release: 3.37Found to occur in 3.37frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onplatform-androidAndroid applications specificallyr: fixedIssue is closed as already fixed in a newer versionteam-androidOwned by Android platform teamtriaged-androidTriaged by Android platform team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions