• David Bokan's avatar
    Set correct whitelisted touch action in fling · f22d6160
    David Bokan authored
    A touch event can be blocking or non-blocking. They can be sent to the
    main thread if the compositor determines that the main thread must know
    about the event. If the event is sent as blocking, the browser will
    avoid dispatching further events until the main thread responds by
    ACK'ing the event. This allows author script to call preventDefault to
    change how gestures are dispatched. A non-blocking event is sent to the
    main thread but as purely informational; the main thread won't ACK the
    event and the browser won't block before dispatching successive gesture
    events
    
    The compositor can turn a blocking touch event into a non-blocking one.
    This is done while a fling is in progress to prevent janking fling
    boosting (see https://crbug.com/595327). In this case, if a user touches
    down during a fling we want the browser to dispatch scroll events
    immediately without waiting on an ACK so that the scroll can continue or
    boost the fling without interruption. The compositor does this by
    setting the touch as DID_NOT_HANDLE_NON_BLOCKING_DUE_TO_FLING which will
    cause it to be forwarded as non-blocking to the main thread.
    
    Compositor touch action[1] lets the browser receive an ACK from the
    compositor to let it know a set of "safe" whitelisted touch actions that
    can be dispatched before the ACK from the main thread arrives. This
    allows scrolls to be dispatched with less latency in some cases if the
    compositor can determine that the main thread won't block certain touch
    actions. The whitelisted touch action is sent back to the browser at the
    same time as the event is forwarded to the main thread.
    
    The bug here is caused by the whitelisted touch action not accounting
    for the "non-blocking fling" behavior. When the touchstart hits a
    blocking region (e.g. non-passive event listener) the whitelisted touch
    action set to kNone (the compositor can't guarantee the main thread wont
    block any gestures)[2,3]. However, if we're in a fling the event will be
    made non-blocking so that the main thread *cannot* block scrolls. Worse,
    because it's non-blocking the main thread won't ACK the event at all so
    the browser will block dispatching any gestures until a new one is
    started.
    
    This CL fixes the issue by setting the whitelisted touch action to kAuto
    (allow all) when we enter a "non-blocking due to fling" state.
    
    
    [1] https://docs.google.com/document/d/1bSv_qNsLLnpXImuH7sHa6D3R_0GdDYkTiNjxso8Rgxo/edit#heading=h.jvxrm66og6z0
    [2] https://cs.chromium.org/chromium/src/third_party/blink/renderer/core/layout/layout_object.h?l=2229&rcl=b9275f87a13183e295a7a55bc6cef6eaea4ed86c
    [3] https://cs.chromium.org/chromium/src/ui/events/blink/input_handler_proxy.cc?l=1016&rcl=25ed318ba5c24057ea2a402c62f25649fda5093f
    
    Bug: 1048098
    Change-Id: Ifa2fdd2fb7124f6f350f05e08f905229731297bb
    Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2132843Reviewed-by: default avatarXida Chen <xidachen@chromium.org>
    Reviewed-by: default avatarDave Tapuska <dtapuska@chromium.org>
    Commit-Queue: Dave Tapuska <dtapuska@chromium.org>
    Cr-Commit-Position: refs/heads/master@{#756833}
    f22d6160
input_handler_proxy.cc 52.5 KB