1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/renderer_host/event_with_latency_info.h"
6 #include "content/browser/renderer_host/input/touch_action_filter.h"
7 #include "content/common/input/input_event_ack_state.h"
8 #include "content/common/input/synthetic_web_input_event_builders.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 #include "third_party/WebKit/public/web/WebInputEvent.h"
12 using blink::WebGestureEvent;
13 using blink::WebInputEvent;
17 TEST(TouchActionFilterTest, SimpleFilter) {
18 TouchActionFilter filter;
20 WebGestureEvent scroll_begin =
21 SyntheticWebGestureEventBuilder::BuildScrollBegin(2, 3);
22 const float kDeltaX = 5;
23 const float kDeltaY = 10;
24 WebGestureEvent scroll_update =
25 SyntheticWebGestureEventBuilder::BuildScrollUpdate(kDeltaX, kDeltaY, 0);
26 WebGestureEvent scroll_end = SyntheticWebGestureEventBuilder::Build(
27 WebInputEvent::GestureScrollEnd, WebGestureEvent::Touchscreen);
28 WebGestureEvent tap = SyntheticWebGestureEventBuilder::Build(
29 WebInputEvent::GestureTap, WebGestureEvent::Touchscreen);
31 // No events filtered by default.
32 filter.ResetTouchAction();
33 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin));
34 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_update));
35 EXPECT_EQ(kDeltaX, scroll_update.data.scrollUpdate.deltaX);
36 EXPECT_EQ(kDeltaY, scroll_update.data.scrollUpdate.deltaY);
37 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_end));
38 filter.ResetTouchAction();
39 EXPECT_FALSE(filter.FilterGestureEvent(&tap));
41 // TOUCH_ACTION_AUTO doesn't cause any filtering.
42 filter.ResetTouchAction();
43 filter.OnSetTouchAction(TOUCH_ACTION_AUTO);
44 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin));
45 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_update));
46 EXPECT_EQ(kDeltaX, scroll_update.data.scrollUpdate.deltaX);
47 EXPECT_EQ(kDeltaY, scroll_update.data.scrollUpdate.deltaY);
48 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_end));
50 // TOUCH_ACTION_NONE filters out all scroll events, but no other events.
51 filter.ResetTouchAction();
52 filter.OnSetTouchAction(TOUCH_ACTION_NONE);
53 EXPECT_FALSE(filter.FilterGestureEvent(&tap));
54 EXPECT_TRUE(filter.FilterGestureEvent(&scroll_begin));
55 EXPECT_TRUE(filter.FilterGestureEvent(&scroll_update));
56 EXPECT_TRUE(filter.FilterGestureEvent(&scroll_update));
57 EXPECT_EQ(kDeltaX, scroll_update.data.scrollUpdate.deltaX);
58 EXPECT_EQ(kDeltaY, scroll_update.data.scrollUpdate.deltaY);
59 EXPECT_TRUE(filter.FilterGestureEvent(&scroll_end));
61 // When a new touch sequence begins, the state is reset.
62 filter.ResetTouchAction();
63 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin));
64 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_update));
65 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_end));
67 // Setting touch action doesn't impact any in-progress gestures.
68 filter.ResetTouchAction();
69 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin));
70 filter.OnSetTouchAction(TOUCH_ACTION_NONE);
71 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_update));
72 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_end));
74 // And the state is still cleared for the next gesture.
75 filter.ResetTouchAction();
76 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin));
77 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_end));
79 // Changing the touch action during a gesture has no effect.
80 filter.ResetTouchAction();
81 filter.OnSetTouchAction(TOUCH_ACTION_NONE);
82 EXPECT_TRUE(filter.FilterGestureEvent(&scroll_begin));
83 filter.OnSetTouchAction(TOUCH_ACTION_AUTO);
84 EXPECT_TRUE(filter.FilterGestureEvent(&scroll_update));
85 EXPECT_TRUE(filter.FilterGestureEvent(&scroll_update));
86 EXPECT_EQ(kDeltaX, scroll_update.data.scrollUpdate.deltaX);
87 EXPECT_EQ(kDeltaY, scroll_update.data.scrollUpdate.deltaY);
88 EXPECT_TRUE(filter.FilterGestureEvent(&scroll_end));
89 filter.ResetTouchAction();
92 TEST(TouchActionFilterTest, Fling) {
93 TouchActionFilter filter;
95 WebGestureEvent scroll_begin =
96 SyntheticWebGestureEventBuilder::BuildScrollBegin(2, 3);
97 WebGestureEvent scroll_update =
98 SyntheticWebGestureEventBuilder::BuildScrollUpdate(5, 10, 0);
99 const float kFlingX = 7;
100 const float kFlingY = -4;
101 WebGestureEvent fling_start = SyntheticWebGestureEventBuilder::BuildFling(
102 kFlingX, kFlingY, WebGestureEvent::Touchscreen);
103 WebGestureEvent pad_fling = SyntheticWebGestureEventBuilder::BuildFling(
104 kFlingX, kFlingY, WebGestureEvent::Touchpad);
106 // TOUCH_ACTION_NONE filters out fling events.
107 filter.ResetTouchAction();
108 filter.OnSetTouchAction(TOUCH_ACTION_NONE);
109 EXPECT_TRUE(filter.FilterGestureEvent(&scroll_begin));
110 EXPECT_TRUE(filter.FilterGestureEvent(&scroll_update));
111 EXPECT_TRUE(filter.FilterGestureEvent(&fling_start));
112 EXPECT_EQ(kFlingX, fling_start.data.flingStart.velocityX);
113 EXPECT_EQ(kFlingY, fling_start.data.flingStart.velocityY);
115 // touchpad flings aren't filtered.
116 filter.ResetTouchAction();
117 filter.OnSetTouchAction(TOUCH_ACTION_NONE);
118 EXPECT_TRUE(filter.FilterGestureEvent(&scroll_begin));
119 EXPECT_TRUE(filter.FilterGestureEvent(&scroll_update));
120 EXPECT_FALSE(filter.FilterGestureEvent(&pad_fling));
121 EXPECT_TRUE(filter.FilterGestureEvent(&fling_start));
122 filter.ResetTouchAction();
125 TEST(TouchActionFilterTest, PanX) {
126 TouchActionFilter filter;
128 const float kDY = 10;
129 const float kFlingX = 7;
130 const float kFlingY = -4;
131 WebGestureEvent scroll_end = SyntheticWebGestureEventBuilder::Build(
132 WebInputEvent::GestureScrollEnd, WebGestureEvent::Touchscreen);
135 // Scrolls with no direction hint are permitted in the X axis.
136 filter.ResetTouchAction();
137 filter.OnSetTouchAction(TOUCH_ACTION_PAN_X);
139 WebGestureEvent scroll_begin =
140 SyntheticWebGestureEventBuilder::BuildScrollBegin(0, 0);
141 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin));
143 WebGestureEvent scroll_update =
144 SyntheticWebGestureEventBuilder::BuildScrollUpdate(kDX, kDY, 0);
145 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_update));
146 EXPECT_EQ(kDX, scroll_update.data.scrollUpdate.deltaX);
147 EXPECT_EQ(0, scroll_update.data.scrollUpdate.deltaY);
149 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_end));
153 // Scrolls hinted mostly in the X axis are permitted in that axis.
154 filter.ResetTouchAction();
155 filter.OnSetTouchAction(TOUCH_ACTION_PAN_X);
156 WebGestureEvent scroll_begin =
157 SyntheticWebGestureEventBuilder::BuildScrollBegin(-7, 6);
158 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin));
160 WebGestureEvent scroll_update =
161 SyntheticWebGestureEventBuilder::BuildScrollUpdate(kDX, kDY, 0);
162 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_update));
163 EXPECT_EQ(kDX, scroll_update.data.scrollUpdate.deltaX);
164 EXPECT_EQ(0, scroll_update.data.scrollUpdate.deltaY);
166 WebGestureEvent scroll_update2 =
167 SyntheticWebGestureEventBuilder::BuildScrollUpdate(-4, -2, 0);
168 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_update2));
169 EXPECT_EQ(-4, scroll_update2.data.scrollUpdate.deltaX);
170 EXPECT_EQ(0, scroll_update2.data.scrollUpdate.deltaY);
172 WebGestureEvent fling_start = SyntheticWebGestureEventBuilder::BuildFling(
173 kFlingX, kFlingY, WebGestureEvent::Touchscreen);
174 EXPECT_FALSE(filter.FilterGestureEvent(&fling_start));
175 EXPECT_EQ(kFlingX, fling_start.data.flingStart.velocityX);
176 EXPECT_EQ(0, fling_start.data.flingStart.velocityY);
180 // Scrolls hinted mostly in the Y direction are suppressed entirely.
181 filter.ResetTouchAction();
182 filter.OnSetTouchAction(TOUCH_ACTION_PAN_X);
183 WebGestureEvent scroll_begin =
184 SyntheticWebGestureEventBuilder::BuildScrollBegin(-7, 8);
185 EXPECT_TRUE(filter.FilterGestureEvent(&scroll_begin));
187 WebGestureEvent scroll_update =
188 SyntheticWebGestureEventBuilder::BuildScrollUpdate(kDX, kDY, 0);
189 EXPECT_TRUE(filter.FilterGestureEvent(&scroll_update));
190 EXPECT_EQ(kDX, scroll_update.data.scrollUpdate.deltaX);
191 EXPECT_EQ(kDY, scroll_update.data.scrollUpdate.deltaY);
193 EXPECT_TRUE(filter.FilterGestureEvent(&scroll_end));
195 filter.ResetTouchAction();
198 TEST(TouchActionFilterTest, PanY) {
199 TouchActionFilter filter;
201 const float kDY = 10;
202 const float kFlingX = 7;
203 const float kFlingY = -4;
204 WebGestureEvent scroll_end = SyntheticWebGestureEventBuilder::Build(
205 WebInputEvent::GestureScrollEnd, WebGestureEvent::Touchscreen);
208 // Scrolls with no direction hint are permitted in the Y axis.
209 filter.ResetTouchAction();
210 filter.OnSetTouchAction(TOUCH_ACTION_PAN_Y);
212 WebGestureEvent scroll_begin =
213 SyntheticWebGestureEventBuilder::BuildScrollBegin(0, 0);
214 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin));
216 WebGestureEvent scroll_update =
217 SyntheticWebGestureEventBuilder::BuildScrollUpdate(kDX, kDY, 0);
218 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_update));
219 EXPECT_EQ(0, scroll_update.data.scrollUpdate.deltaX);
220 EXPECT_EQ(kDY, scroll_update.data.scrollUpdate.deltaY);
222 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_end));
226 // Scrolls hinted mostly in the Y axis are permitted in that axis.
227 filter.ResetTouchAction();
228 filter.OnSetTouchAction(TOUCH_ACTION_PAN_Y);
229 WebGestureEvent scroll_begin =
230 SyntheticWebGestureEventBuilder::BuildScrollBegin(-6, 7);
231 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin));
233 WebGestureEvent scroll_update =
234 SyntheticWebGestureEventBuilder::BuildScrollUpdate(kDX, kDY, 0);
235 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_update));
236 EXPECT_EQ(0, scroll_update.data.scrollUpdate.deltaX);
237 EXPECT_EQ(kDY, scroll_update.data.scrollUpdate.deltaY);
239 WebGestureEvent scroll_update2 =
240 SyntheticWebGestureEventBuilder::BuildScrollUpdate(-4, -2, 0);
241 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_update2));
242 EXPECT_EQ(0, scroll_update2.data.scrollUpdate.deltaX);
243 EXPECT_EQ(-2, scroll_update2.data.scrollUpdate.deltaY);
245 WebGestureEvent fling_start = SyntheticWebGestureEventBuilder::BuildFling(
246 kFlingX, kFlingY, WebGestureEvent::Touchscreen);
247 EXPECT_FALSE(filter.FilterGestureEvent(&fling_start));
248 EXPECT_EQ(0, fling_start.data.flingStart.velocityX);
249 EXPECT_EQ(kFlingY, fling_start.data.flingStart.velocityY);
253 // Scrolls hinted mostly in the X direction are suppressed entirely.
254 filter.ResetTouchAction();
255 filter.OnSetTouchAction(TOUCH_ACTION_PAN_Y);
256 WebGestureEvent scroll_begin =
257 SyntheticWebGestureEventBuilder::BuildScrollBegin(-8, 7);
258 EXPECT_TRUE(filter.FilterGestureEvent(&scroll_begin));
260 WebGestureEvent scroll_update =
261 SyntheticWebGestureEventBuilder::BuildScrollUpdate(kDX, kDY, 0);
262 EXPECT_TRUE(filter.FilterGestureEvent(&scroll_update));
263 EXPECT_EQ(kDX, scroll_update.data.scrollUpdate.deltaX);
264 EXPECT_EQ(kDY, scroll_update.data.scrollUpdate.deltaY);
266 EXPECT_TRUE(filter.FilterGestureEvent(&scroll_end));
268 filter.ResetTouchAction();
271 TEST(TouchActionFilterTest, PanXY) {
272 TouchActionFilter filter;
274 const float kDY = 10;
275 const float kFlingX = 7;
276 const float kFlingY = -4;
279 // Scrolls hinted in the X axis are permitted and unmodified.
280 filter.ResetTouchAction();
281 filter.OnSetTouchAction(TOUCH_ACTION_PAN_X_Y);
282 WebGestureEvent scroll_begin =
283 SyntheticWebGestureEventBuilder::BuildScrollBegin(-7, 6);
284 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin));
286 WebGestureEvent scroll_update =
287 SyntheticWebGestureEventBuilder::BuildScrollUpdate(kDX, kDY, 0);
288 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_update));
289 EXPECT_EQ(kDX, scroll_update.data.scrollUpdate.deltaX);
290 EXPECT_EQ(kDY, scroll_update.data.scrollUpdate.deltaY);
292 WebGestureEvent fling_start = SyntheticWebGestureEventBuilder::BuildFling(
293 kFlingX, kFlingY, WebGestureEvent::Touchscreen);
294 EXPECT_FALSE(filter.FilterGestureEvent(&fling_start));
295 EXPECT_EQ(kFlingX, fling_start.data.flingStart.velocityX);
296 EXPECT_EQ(kFlingY, fling_start.data.flingStart.velocityY);
300 // Scrolls hinted in the Y axis are permitted and unmodified.
301 filter.ResetTouchAction();
302 filter.OnSetTouchAction(TOUCH_ACTION_PAN_X_Y);
303 WebGestureEvent scroll_begin =
304 SyntheticWebGestureEventBuilder::BuildScrollBegin(-6, 7);
305 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin));
307 WebGestureEvent scroll_update =
308 SyntheticWebGestureEventBuilder::BuildScrollUpdate(kDX, kDY, 0);
309 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_update));
310 EXPECT_EQ(kDX, scroll_update.data.scrollUpdate.deltaX);
311 EXPECT_EQ(kDY, scroll_update.data.scrollUpdate.deltaY);
313 WebGestureEvent fling_start = SyntheticWebGestureEventBuilder::BuildFling(
314 kFlingX, kFlingY, WebGestureEvent::Touchscreen);
315 EXPECT_FALSE(filter.FilterGestureEvent(&fling_start));
316 EXPECT_EQ(kFlingX, fling_start.data.flingStart.velocityX);
317 EXPECT_EQ(kFlingY, fling_start.data.flingStart.velocityY);
319 filter.ResetTouchAction();
322 TEST(TouchActionFilterTest, Intersect) {
323 EXPECT_EQ(TOUCH_ACTION_NONE,
324 TouchActionFilter::Intersect(TOUCH_ACTION_NONE, TOUCH_ACTION_AUTO));
325 EXPECT_EQ(TOUCH_ACTION_NONE,
326 TouchActionFilter::Intersect(TOUCH_ACTION_AUTO, TOUCH_ACTION_NONE));
327 EXPECT_EQ(TOUCH_ACTION_PAN_X,
328 TouchActionFilter::Intersect(TOUCH_ACTION_AUTO, TOUCH_ACTION_PAN_X));
329 EXPECT_EQ(TOUCH_ACTION_PAN_Y,
330 TouchActionFilter::Intersect(TOUCH_ACTION_PAN_Y, TOUCH_ACTION_AUTO));
331 EXPECT_EQ(TOUCH_ACTION_AUTO,
332 TouchActionFilter::Intersect(TOUCH_ACTION_AUTO, TOUCH_ACTION_AUTO));
333 EXPECT_EQ(TOUCH_ACTION_PAN_X,
334 TouchActionFilter::Intersect(TOUCH_ACTION_PAN_X_Y, TOUCH_ACTION_PAN_X));
335 EXPECT_EQ(TOUCH_ACTION_PAN_Y,
336 TouchActionFilter::Intersect(TOUCH_ACTION_PAN_Y, TOUCH_ACTION_PAN_X_Y));
337 EXPECT_EQ(TOUCH_ACTION_PAN_X_Y,
338 TouchActionFilter::Intersect(TOUCH_ACTION_PAN_X_Y, TOUCH_ACTION_AUTO));
339 EXPECT_EQ(TOUCH_ACTION_NONE,
340 TouchActionFilter::Intersect(TOUCH_ACTION_PAN_X, TOUCH_ACTION_PAN_Y));
343 TEST(TouchActionFilterTest, MultiTouch) {
344 TouchActionFilter filter;
346 WebGestureEvent scroll_begin =
347 SyntheticWebGestureEventBuilder::BuildScrollBegin(2, 3);
348 const float kDeltaX = 5;
349 const float kDeltaY = 10;
350 WebGestureEvent scroll_update =
351 SyntheticWebGestureEventBuilder::BuildScrollUpdate(kDeltaX, kDeltaY, 0);
352 WebGestureEvent scroll_end = SyntheticWebGestureEventBuilder::Build(
353 WebInputEvent::GestureScrollEnd, WebGestureEvent::Touchscreen);
355 // For multiple points, the intersection is what matters.
356 filter.ResetTouchAction();
357 filter.OnSetTouchAction(TOUCH_ACTION_NONE);
358 filter.OnSetTouchAction(TOUCH_ACTION_AUTO);
359 EXPECT_TRUE(filter.FilterGestureEvent(&scroll_begin));
360 EXPECT_TRUE(filter.FilterGestureEvent(&scroll_update));
361 EXPECT_TRUE(filter.FilterGestureEvent(&scroll_update));
362 EXPECT_EQ(kDeltaX, scroll_update.data.scrollUpdate.deltaX);
363 EXPECT_EQ(kDeltaY, scroll_update.data.scrollUpdate.deltaY);
364 EXPECT_TRUE(filter.FilterGestureEvent(&scroll_end));
366 // Intersection of PAN_X and PAN_Y is NONE.
367 filter.ResetTouchAction();
368 filter.OnSetTouchAction(TOUCH_ACTION_PAN_X);
369 filter.OnSetTouchAction(TOUCH_ACTION_PAN_Y);
370 filter.OnSetTouchAction(TOUCH_ACTION_PAN_X_Y);
371 EXPECT_TRUE(filter.FilterGestureEvent(&scroll_begin));
372 EXPECT_TRUE(filter.FilterGestureEvent(&scroll_update));
373 EXPECT_TRUE(filter.FilterGestureEvent(&scroll_end));
374 filter.ResetTouchAction();
377 TEST(TouchActionFilterTest, Pinch) {
378 TouchActionFilter filter;
380 WebGestureEvent scroll_begin =
381 SyntheticWebGestureEventBuilder::BuildScrollBegin(2, 3);
382 WebGestureEvent pinch_begin = SyntheticWebGestureEventBuilder::Build(
383 WebInputEvent::GesturePinchBegin, WebGestureEvent::Touchscreen);
384 WebGestureEvent pinch_update =
385 SyntheticWebGestureEventBuilder::BuildPinchUpdate(
386 1.2f, 5, 5, 0, WebGestureEvent::Touchscreen);
387 WebGestureEvent pinch_end = SyntheticWebGestureEventBuilder::Build(
388 WebInputEvent::GesturePinchEnd, WebGestureEvent::Touchscreen);
389 WebGestureEvent scroll_end = SyntheticWebGestureEventBuilder::Build(
390 WebInputEvent::GestureScrollEnd, WebGestureEvent::Touchscreen);
392 // Pinch is allowed with touch-action: auto.
393 filter.ResetTouchAction();
394 filter.OnSetTouchAction(TOUCH_ACTION_AUTO);
395 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin));
396 EXPECT_FALSE(filter.FilterGestureEvent(&pinch_begin));
397 EXPECT_FALSE(filter.FilterGestureEvent(&pinch_update));
398 EXPECT_FALSE(filter.FilterGestureEvent(&pinch_end));
399 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_end));
401 // Pinch is not allowed with touch-action: none.
402 filter.ResetTouchAction();
403 filter.OnSetTouchAction(TOUCH_ACTION_NONE);
404 EXPECT_TRUE(filter.FilterGestureEvent(&scroll_begin));
405 EXPECT_TRUE(filter.FilterGestureEvent(&pinch_begin));
406 EXPECT_TRUE(filter.FilterGestureEvent(&pinch_update));
407 EXPECT_TRUE(filter.FilterGestureEvent(&pinch_end));
408 EXPECT_TRUE(filter.FilterGestureEvent(&scroll_end));
410 // Pinch is not allowed with touch-action: pan-x pan-y.
411 filter.ResetTouchAction();
412 filter.OnSetTouchAction(TOUCH_ACTION_PAN_X_Y);
413 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin));
414 EXPECT_TRUE(filter.FilterGestureEvent(&pinch_begin));
415 EXPECT_TRUE(filter.FilterGestureEvent(&pinch_update));
416 EXPECT_TRUE(filter.FilterGestureEvent(&pinch_end));
417 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_end));
419 // Pinch is allowed with touch-action: manipulation.
420 filter.ResetTouchAction();
421 filter.OnSetTouchAction(TOUCH_ACTION_MANIPULATION);
422 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin));
423 EXPECT_FALSE(filter.FilterGestureEvent(&pinch_begin));
424 EXPECT_FALSE(filter.FilterGestureEvent(&pinch_update));
425 EXPECT_FALSE(filter.FilterGestureEvent(&pinch_end));
426 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_end));
428 // Pinch state is automatically reset at the end of a scroll.
429 filter.ResetTouchAction();
430 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin));
431 EXPECT_FALSE(filter.FilterGestureEvent(&pinch_begin));
432 EXPECT_FALSE(filter.FilterGestureEvent(&pinch_update));
433 EXPECT_FALSE(filter.FilterGestureEvent(&pinch_end));
434 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_end));
436 // Pinching can become disallowed during a single scroll gesture, but
437 // can't become allowed again until the scroll terminates.
438 // Note that the current TouchEventQueue design makes this scenario
439 // impossible in practice (no touch events are sent to the renderer
440 // while scrolling) and so no SetTouchAction can occur. But this
441 // could change in the future, so it's still worth verifying in this
443 filter.ResetTouchAction();
444 filter.OnSetTouchAction(TOUCH_ACTION_AUTO);
445 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin));
446 EXPECT_FALSE(filter.FilterGestureEvent(&pinch_begin));
447 EXPECT_FALSE(filter.FilterGestureEvent(&pinch_update));
448 EXPECT_FALSE(filter.FilterGestureEvent(&pinch_end));
449 filter.OnSetTouchAction(TOUCH_ACTION_NONE);
450 EXPECT_TRUE(filter.FilterGestureEvent(&pinch_begin));
451 EXPECT_TRUE(filter.FilterGestureEvent(&pinch_update));
452 EXPECT_TRUE(filter.FilterGestureEvent(&pinch_end));
453 filter.OnSetTouchAction(TOUCH_ACTION_AUTO);
454 EXPECT_TRUE(filter.FilterGestureEvent(&pinch_begin));
455 EXPECT_TRUE(filter.FilterGestureEvent(&pinch_update));
456 EXPECT_TRUE(filter.FilterGestureEvent(&pinch_end));
457 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_end));
459 // Once a pinch has started, any change in state won't affect the current
460 // pinch gesture, but can affect a future one within the same scroll.
461 filter.ResetTouchAction();
462 filter.OnSetTouchAction(TOUCH_ACTION_AUTO);
463 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin));
464 EXPECT_FALSE(filter.FilterGestureEvent(&pinch_begin));
465 filter.OnSetTouchAction(TOUCH_ACTION_NONE);
466 EXPECT_FALSE(filter.FilterGestureEvent(&pinch_update));
467 EXPECT_FALSE(filter.FilterGestureEvent(&pinch_end));
468 EXPECT_TRUE(filter.FilterGestureEvent(&pinch_begin));
469 EXPECT_TRUE(filter.FilterGestureEvent(&pinch_update));
470 EXPECT_TRUE(filter.FilterGestureEvent(&pinch_end));
471 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_end));
472 filter.ResetTouchAction();
475 TEST(TouchActionFilterTest, DoubleTapWithTouchActionAuto) {
476 TouchActionFilter filter;
478 WebGestureEvent tap_down = SyntheticWebGestureEventBuilder::Build(
479 WebInputEvent::GestureTapDown, WebGestureEvent::Touchscreen);
480 WebGestureEvent unconfirmed_tap = SyntheticWebGestureEventBuilder::Build(
481 WebInputEvent::GestureTapUnconfirmed, WebGestureEvent::Touchscreen);
482 WebGestureEvent tap_cancel = SyntheticWebGestureEventBuilder::Build(
483 WebInputEvent::GestureTapCancel, WebGestureEvent::Touchscreen);
484 WebGestureEvent double_tap = SyntheticWebGestureEventBuilder::Build(
485 WebInputEvent::GestureDoubleTap, WebGestureEvent::Touchscreen);
487 // Double tap is allowed with touch action auto.
488 filter.ResetTouchAction();
489 EXPECT_FALSE(filter.FilterGestureEvent(&tap_down));
490 EXPECT_FALSE(filter.FilterGestureEvent(&unconfirmed_tap));
491 EXPECT_EQ(unconfirmed_tap.type, WebInputEvent::GestureTapUnconfirmed);
492 // The tap cancel will come as part of the next touch sequence.
493 filter.ResetTouchAction();
494 // Changing the touch action for the second tap doesn't effect the behaviour
496 filter.OnSetTouchAction(TOUCH_ACTION_NONE);
497 EXPECT_FALSE(filter.FilterGestureEvent(&tap_cancel));
498 EXPECT_FALSE(filter.FilterGestureEvent(&tap_down));
499 EXPECT_FALSE(filter.FilterGestureEvent(&double_tap));
500 filter.ResetTouchAction();
503 TEST(TouchActionFilterTest, DoubleTap) {
504 TouchActionFilter filter;
506 WebGestureEvent tap_down = SyntheticWebGestureEventBuilder::Build(
507 WebInputEvent::GestureTapDown, WebGestureEvent::Touchscreen);
508 WebGestureEvent unconfirmed_tap = SyntheticWebGestureEventBuilder::Build(
509 WebInputEvent::GestureTapUnconfirmed, WebGestureEvent::Touchscreen);
510 WebGestureEvent tap_cancel = SyntheticWebGestureEventBuilder::Build(
511 WebInputEvent::GestureTapCancel, WebGestureEvent::Touchscreen);
512 WebGestureEvent double_tap = SyntheticWebGestureEventBuilder::Build(
513 WebInputEvent::GestureDoubleTap, WebGestureEvent::Touchscreen);
515 // Double tap is disabled with any touch action other than auto.
516 filter.ResetTouchAction();
517 filter.OnSetTouchAction(TOUCH_ACTION_MANIPULATION);
518 EXPECT_FALSE(filter.FilterGestureEvent(&tap_down));
519 EXPECT_FALSE(filter.FilterGestureEvent(&unconfirmed_tap));
520 EXPECT_EQ(WebInputEvent::GestureTap, unconfirmed_tap.type);
521 // Changing the touch action for the second tap doesn't effect the behaviour
522 // of the event. The tap cancel will come as part of the next touch sequence.
523 filter.ResetTouchAction();
524 filter.OnSetTouchAction(TOUCH_ACTION_AUTO);
525 EXPECT_TRUE(filter.FilterGestureEvent(&tap_cancel));
526 EXPECT_FALSE(filter.FilterGestureEvent(&tap_down));
527 EXPECT_FALSE(filter.FilterGestureEvent(&double_tap));
528 EXPECT_EQ(WebInputEvent::GestureTap, double_tap.type);
529 filter.ResetTouchAction();
532 TEST(TouchActionFilterTest, SingleTapWithTouchActionAuto) {
533 TouchActionFilter filter;
535 WebGestureEvent tap_down = SyntheticWebGestureEventBuilder::Build(
536 WebInputEvent::GestureTapDown, WebGestureEvent::Touchscreen);
537 WebGestureEvent unconfirmed_tap1 = SyntheticWebGestureEventBuilder::Build(
538 WebInputEvent::GestureTapUnconfirmed, WebGestureEvent::Touchscreen);
539 WebGestureEvent tap = SyntheticWebGestureEventBuilder::Build(
540 WebInputEvent::GestureTap, WebGestureEvent::Touchscreen);
542 // Single tap is allowed with touch action auto.
543 filter.ResetTouchAction();
544 EXPECT_FALSE(filter.FilterGestureEvent(&tap_down));
545 EXPECT_FALSE(filter.FilterGestureEvent(&unconfirmed_tap1));
546 EXPECT_EQ(WebInputEvent::GestureTapUnconfirmed, unconfirmed_tap1.type);
547 EXPECT_FALSE(filter.FilterGestureEvent(&tap));
548 filter.ResetTouchAction();
551 TEST(TouchActionFilterTest, SingleTap) {
552 TouchActionFilter filter;
554 WebGestureEvent tap_down = SyntheticWebGestureEventBuilder::Build(
555 WebInputEvent::GestureTapDown, WebGestureEvent::Touchscreen);
556 WebGestureEvent unconfirmed_tap1 = SyntheticWebGestureEventBuilder::Build(
557 WebInputEvent::GestureTapUnconfirmed, WebGestureEvent::Touchscreen);
558 WebGestureEvent tap = SyntheticWebGestureEventBuilder::Build(
559 WebInputEvent::GestureTap, WebGestureEvent::Touchscreen);
561 // With touch action other than auto, tap unconfirmed is turned into tap.
562 filter.ResetTouchAction();
563 filter.OnSetTouchAction(TOUCH_ACTION_NONE);
564 EXPECT_FALSE(filter.FilterGestureEvent(&tap_down));
565 EXPECT_FALSE(filter.FilterGestureEvent(&unconfirmed_tap1));
566 EXPECT_EQ(WebInputEvent::GestureTap, unconfirmed_tap1.type);
567 EXPECT_TRUE(filter.FilterGestureEvent(&tap));
568 filter.ResetTouchAction();
571 TEST(TouchActionFilterTest, TouchActionResetsOnResetTouchAction) {
572 TouchActionFilter filter;
574 WebGestureEvent tap = SyntheticWebGestureEventBuilder::Build(
575 WebInputEvent::GestureTap, WebGestureEvent::Touchscreen);
576 WebGestureEvent scroll_begin =
577 SyntheticWebGestureEventBuilder::BuildScrollBegin(2, 3);
578 WebGestureEvent scroll_end = SyntheticWebGestureEventBuilder::Build(
579 WebInputEvent::GestureScrollEnd, WebGestureEvent::Touchscreen);
581 filter.ResetTouchAction();
582 filter.OnSetTouchAction(TOUCH_ACTION_NONE);
583 EXPECT_TRUE(filter.FilterGestureEvent(&scroll_begin));
584 EXPECT_TRUE(filter.FilterGestureEvent(&scroll_end));
586 filter.ResetTouchAction();
587 filter.OnSetTouchAction(TOUCH_ACTION_NONE);
588 EXPECT_FALSE(filter.FilterGestureEvent(&tap));
590 filter.ResetTouchAction();
591 EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin));
594 } // namespace content