Commit a27f2244 authored by David Bokan's avatar David Bokan Committed by Commit Bot

Fix Aura double-tap touch-action filtering

The double-tap gesture on Aura (which causes zoom) does not respect the
touch-action filter as it should. i.e., double-tapping over a region
with touch-action: none should prevent zooming.

This is caused by IsGestureEvent() returning false for the
TAP_UNCONFIRMED event. IsGestureEvent is used in EventHandler::OnEvent
to determine whether to pass the event to OnGestureEvent and meant that
the TAP_UNCONFIRMED gesture would get dropped at this point.

The reason this was working on Android was that Android's
GestureProivderClient is RenderWidgetHostViewAndroid. When
FilteredGestureProvider forwards the gesture it passes it straight back
to the RWHVA which doesn't go through the IsGestureEvent check mentioned
above.

On Aura, the GestureProviderClient is GestureProviderAura which passes
the forwarded gesture back through WindowEventDispatch before finding
the RenderWidgetHostViewAura. The WindowEventDispatch call chain is
where we accidentally filtered the TAP_UNCONFIRMED gesture because of
!IsGestureEvent. This means the TouchActionFilter never saw this
gesture, which it needs to determine whether to filter the subsequent
double-tap gesture.

Bug: 865090
Change-Id: I5f8932dcf8b33ec132fa946864a462610cc8413b
Reviewed-on: https://chromium-review.googlesource.com/1213881Reviewed-by: default avatarDavid Bokan <bokan@chromium.org>
Reviewed-by: default avatarSadrul Chowdhury <sadrul@chromium.org>
Commit-Queue: David Bokan <bokan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#590173}
parent d78cd972
<script src='../../../../resources/gesture-util.js'></script>
<script src='../../../../resources/testharness.js'></script>
<script src='../../../../resources/testharnessreport.js'></script>
<style>
html,body {
margin: 0;
width: 100%;
height: 100%;
touch-action: none;
/* Checkerboard pattern for manual testing, so zooming is easily seen. */
background-image:
linear-gradient(45deg, #808080 25%, transparent 25%),
linear-gradient(-45deg, #808080 25%, transparent 25%),
linear-gradient(45deg, transparent 75%, #808080 75%),
linear-gradient(-45deg, transparent 75%, #808080 75%);
background-size:80px 80px;
}
.message {
width: 100%;
text-align: center;
background-color: aliceblue;
font-size: xx-large;
}
</style>
<div class="message">
touch-action: none should prevent zooming on double-tap. Test manually by
double-tapping anywhere. The page must not zoom-in.
</div>
<script>
// Test that double-tapping on a region that's declared touch-action: none
// doesn't cause the double-tap zoom gesture. This gesture is only supported
// on some (Android and CrOS tablet-mode) platforms.
promise_test(async () => {
await waitForCompositorCommit();
await doubleTapAt(400, 300);
await conditionHolds(
() => { return visualViewport.scale == 1; },
"Double-tap causes zoom despite 'touch-action:none'!");
}, "'touch-action: none' prevents double-tap zoom");
</script>
...@@ -34,8 +34,8 @@ function conditionHolds(condition, error_message = 'Condition is not true anymor ...@@ -34,8 +34,8 @@ function conditionHolds(condition, error_message = 'Condition is not true anymor
const MAX_FRAME = 100; const MAX_FRAME = 100;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
function tick(frames) { function tick(frames) {
// We requestAnimationFrame either for 200 frames or until condition is // We requestAnimationFrame either for 100 frames or until condition is
// met. // violated.
if (frames >= MAX_FRAME) if (frames >= MAX_FRAME)
resolve(); resolve();
else if (!condition()) else if (!condition())
...@@ -310,6 +310,29 @@ function touchTapOn(xPosition, yPosition) { ...@@ -310,6 +310,29 @@ function touchTapOn(xPosition, yPosition) {
}); });
} }
function doubleTapAt(xPosition, yPosition) {
// This comes from config constants in gesture_detector.cc.
const DOUBLE_TAP_MINIMUM_DURATION_S = 0.04;
return new Promise(function(resolve, reject) {
if (!window.chrome || !chrome.gpuBenchmarking) {
reject("chrome.gpuBenchmarking not found.");
return;
}
chrome.gpuBenchmarking.pointerActionSequence( [{
source: 'touch',
actions: [
{ name: 'pointerDown', x: xPosition, y: yPosition },
{ name: 'pointerUp' },
{ name: 'pause', duration: DOUBLE_TAP_MINIMUM_DURATION_S },
{ name: 'pointerDown', x: xPosition, y: yPosition },
{ name: 'pointerUp' }
]
}], resolve);
});
}
function approx_equals(actual, expected, epsilon) { function approx_equals(actual, expected, epsilon) {
return actual >= expected - epsilon && actual <= expected + epsilon; return actual >= expected - epsilon && actual <= expected + epsilon;
} }
...@@ -179,6 +179,7 @@ class EVENTS_EXPORT Event { ...@@ -179,6 +179,7 @@ class EVENTS_EXPORT Event {
case ET_GESTURE_DOUBLE_TAP: case ET_GESTURE_DOUBLE_TAP:
case ET_GESTURE_TAP_CANCEL: case ET_GESTURE_TAP_CANCEL:
case ET_GESTURE_TAP_DOWN: case ET_GESTURE_TAP_DOWN:
case ET_GESTURE_TAP_UNCONFIRMED:
case ET_GESTURE_BEGIN: case ET_GESTURE_BEGIN:
case ET_GESTURE_END: case ET_GESTURE_END:
case ET_GESTURE_TWO_FINGER_TAP: case ET_GESTURE_TWO_FINGER_TAP:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment