Repository navigation
Request unbuffered dispatch for platform view motion events after _PlatformViewGestureRecognizer rejects gesture - #192259
Conversation
…na rejection in HCPP
_PlatformViewGestureRecognizer rejects gesture
…re matching downTime - Pass gesture downTime timestamp (gestureId) from _PlatformViewGestureRecognizer through PlatformViewController to the Android platform views channel. - In PlatformViewWrapper and FlutterMutatorView, track isGestureActive and currentDownTime. - Only honor onFlutterWonGesture when a gesture is currently active and the gestureId matches currentDownTime. - Add comprehensive unit tests verifying matching, mismatched, and post-touch rejection scenarios.
…loads and artifacts
227b8d7 to
ded4972
Compare
7e7ad80 to
f2b4df6
Compare
- Fix multi-touch gestureId tracking in _PlatformViewGestureRecognizer by not clearing _downTimes on acceptGesture, preserving the initial gesture downTime. - Document cross-language downTime invariant in Dart, AndroidTouchProcessor, and PlatformViewsChannel. - Guard gestureId != null before calling rejectGesture and use .ignore(). - Deduplicate gesture tracking between FlutterMutatorView and PlatformViewWrapper into PlatformViewGestureTracker with sentinel downTime (-1). - Restore final on channelHandler in PlatformViewsController and PlatformViewsController2, using constructor injection in PlatformViewsControllerDelegator for testing. - Reduce test-only visibility surface to package-private where applicable. - Remove redundant AndroidViewController.rejectGesture override and clarify PlatformViewController.rejectGesture documentation. - Add multi-touch unit test in platform_view_test.dart and comprehensive tests in PlatformViewGestureTrackerTest.
48f22ef to
67204fd
Compare
… constructors Null-guard platformViewsController and platformViewsController2 when passing their channelHandler instances to the delegator constructor, preventing NullPointerExceptions in tests and environments where only one controller is provided.
…t overload - Correct comment in platform_view.dart and AndroidTouchProcessor.java regarding PointerEventResampler, noting that when resampling is enabled PointerDownEvent.timeStamp is resampled to sampleTime and safely degrades to buffered dispatch. - Drop unused onTouchEvent(MotionEvent, View) overload and unused View import in PlatformViewGestureTracker.
…ator PlatformViewsControllerDelegator delegates between two controllers and cannot function if either controller is null. Mark parameters @nonnull and remove the unused dead delegator instantiation in PlatformViewsControllerTest.
|
autosubmit label was removed for flutter/flutter/192259, because - The status or check suite Google testing has failed. Please fix the issues identified (or deflake) before re-applying this label. |
|
autosubmit label was removed for flutter/flutter/192259, because - The status or check suite Google testing has failed. Please fix the issues identified (or deflake) before re-applying this label. |
|
autosubmit label was removed for flutter/flutter/192259, because - The status or check suite Mac_arm64_verify_binaries has failed. Please fix the issues identified (or deflake) before re-applying this label. |
|
autosubmit label was removed for flutter/flutter/192259, because - The status or check suite Google testing has failed. Please fix the issues identified (or deflake) before re-applying this label. |
|
autosubmit label was removed for flutter/flutter/192259, because - The status or check suite Dashboard Checks has failed. Please fix the issues identified (or deflake) before re-applying this label. |
flutter/flutter@8b3e8f5...27fec0e 2026-09-14 ttankkeo112@gmail.com Add dedicated rubber band spring for overscroll recovery in BouncingScrollPhysics (flutter/flutter#187568) 2026-09-14 engine-flutter-autoroll@skia.org Roll Skia from 83c984a6daf5 to 59904977fcbb (8 revisions) (flutter/flutter#192767) 2026-09-14 34871572+gmackall@users.noreply.github.com Request unbuffered dispatch for platform view motion events after `_PlatformViewGestureRecognizer` rejects gesture (flutter/flutter#192259) 2026-09-14 engine-flutter-autoroll@skia.org Roll Fuchsia GN SDK from ZsxUUK2SfA-TrNvb8... to PDJz3b3CL31uoLOkD... (flutter/flutter#192440) 2026-09-14 codefu@google.com ci(bringup): cleanup some bringup (flutter/flutter#192752) 2026-09-14 kevmoo@users.noreply.github.com Warn users on potential removal of dart:html in dry run (flutter/flutter#192710) 2026-09-14 codefu@google.com docs: migrate design document guidance to flutter/rfc (flutter/flutter#192648) 2026-09-14 154381524+flutteractionsbot@users.noreply.github.com Sync CHANGELOG.md from stable (flutter/flutter#192499) 2026-09-14 engine-flutter-autoroll@skia.org Roll Skia from 7a6fd7ff72d5 to 83c984a6daf5 (1 revision) (flutter/flutter#192745) 2026-09-14 1961493+harryterkelsen@users.noreply.github.com RELAND: [devicelab] Clean up Chrome profile directories and trap abort signals in web benchmarks (flutter/flutter#192655) 2026-09-14 kevmoo@users.noreply.github.com fix(web): hide --web-content-hash until content hashing is complete (flutter/flutter#192663) 2026-09-14 engine-flutter-autoroll@skia.org Roll Skia from 527751088719 to 7a6fd7ff72d5 (2 revisions) (flutter/flutter#192725) 2026-09-14 engine-flutter-autoroll@skia.org Roll Skia from eaf9f82813eb to 527751088719 (1 revision) (flutter/flutter#192722) 2026-09-14 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from AQu85JoTHCMET3Q8G... to 7R1l5MhSZZUr1Q6D1... (flutter/flutter#192719) 2026-09-14 robert.ancell@canonical.com [Linux] Clear the frame when there is nothing to render (flutter/flutter#192461) If this roll has caused a breakage, revert this CL and set the roller to dry run mode using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC stuartmorgan@google.com,tarrinneal@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Changes platform view touch input for all modes to request the unbuffered stream for the given event when the GestureArena determines the platform view has bowed out of ownership of that event, via View.requestUnbufferedDispatch(). Flutter content itself makes this request, but currently platform views don't.
This greatly improves platform view scrolling smoothness, while having no breaking change or impact on platform views performing gesture handling (because the GestureArena has determined that they don't own the input event).
Problem & Invariant
Under high-load or scrolling scenarios, buffered touch dispatch causes visible jank and input lag. Flutter requests unbuffered dispatch for its own rendering, but platform views continue using buffered streams unless requested. Simply requesting unbuffered dispatch unconditionally can cause issues if gestures are still competing or owned by the platform view. Scoping unbuffered dispatch to gestures that Flutter has won ensures that platform views receive fast, unbuffered dispatch specifically during Flutter gestures (like scrolling).
Architecture & Gesture Correlation (
embedderId)Previous iterations attempted to correlate gestures across the channel by matching synthetic
downTimetimestamps packed intoPointerDownEvent.timeStamp. However, resamplers or clock drift can alter event timestamps.Instead, this PR uses Flutter's canonical
embedderIdmechanism:MotionEventarrives,AndroidTouchProcessortracks it usingMotionEventTracker.track(event)and populatespacket.putLong(motionEventId), which the framework receives asPointerEvent.embedderId._PlatformViewGestureRecognizerrecords theembedderIdof the pointer-down event. When Flutter wins the arena and callsrejectGesture(pointer), the framework sendsgestureId(set toembedderId) over theflutter/platform_viewssystem channel.MotionEventTracker.peek):PlatformViewsControllerandPlatformViewsController2handleonRejectGesture(viewId, gestureId).motionEventTracker.peek(MotionEventId.from(gestureId))to look up the nativeMotionEventwithout consuming it from the tracker.MotionEvent, the nativedownTimeis retrieved and passed toFlutterMutatorViewandPlatformViewWrapper.PlatformViewGestureTrackermarksflutterWonGesture = trueif thedownTimematches the current active gesture stream, and keeps callingrequestUnbufferedDispatch()for all remaining events in the gesture untilACTION_UPorACTION_CANCEL.peek()returnsnull(e.g. if the event was already popped or on non-Android embedders), or ifgestureIdis 0 or unmatched, the optimization degrades gracefully to standard buffered touch dispatch without breaking input handling.Tests
packages/flutter/test/rendering/platform_view_test.dartrejectGesturepasses the pointer'sembedderIdasgestureId.embedderIds.embedderIdis 0.PlatformViewsControllerTest: VerifiesrejectGesturewith validgestureIdlooks up trackedMotionEventand enables unbuffered dispatch; verifies mismatched or missing IDs do not enable it.PlatformViewsController2Test: Verifies same behavior on the modern hybrid composition pipeline.FlutterMutatorViewTestandPlatformViewWrapperTest: Verifies gesture tracking acrossACTION_DOWN,ACTION_MOVEsequences, and resetting onACTION_UP/ACTION_CANCEL.Supersedes #192249
Pre-launch Checklist
///).Generated with Gemini / AI assistance.