Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / content / browser / renderer_host / input / touch_action_filter_unittest.cc
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.
4
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"
11
12 using blink::WebGestureEvent;
13 using blink::WebInputEvent;
14
15 namespace content {
16
17 TEST(TouchActionFilterTest, SimpleFilter) {
18   TouchActionFilter filter;
19
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);
30
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));
40
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));
49
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));
60
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));
66
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));
73
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));
78
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();
90 }
91
92 TEST(TouchActionFilterTest, Fling) {
93   TouchActionFilter filter;
94
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);
105
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);
114
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();
123 }
124
125 TEST(TouchActionFilterTest, PanX) {
126   TouchActionFilter filter;
127   const float kDX = 5;
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);
133
134   {
135     // Scrolls with no direction hint are permitted in the X axis.
136     filter.ResetTouchAction();
137     filter.OnSetTouchAction(TOUCH_ACTION_PAN_X);
138
139     WebGestureEvent scroll_begin =
140         SyntheticWebGestureEventBuilder::BuildScrollBegin(0, 0);
141     EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin));
142
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);
148
149     EXPECT_FALSE(filter.FilterGestureEvent(&scroll_end));
150   }
151
152   {
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));
159
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);
165
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);
171
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);
177   }
178
179   {
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));
186
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);
192
193     EXPECT_TRUE(filter.FilterGestureEvent(&scroll_end));
194   }
195   filter.ResetTouchAction();
196 }
197
198 TEST(TouchActionFilterTest, PanY) {
199   TouchActionFilter filter;
200   const float kDX = 5;
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);
206
207   {
208     // Scrolls with no direction hint are permitted in the Y axis.
209     filter.ResetTouchAction();
210     filter.OnSetTouchAction(TOUCH_ACTION_PAN_Y);
211
212     WebGestureEvent scroll_begin =
213         SyntheticWebGestureEventBuilder::BuildScrollBegin(0, 0);
214     EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin));
215
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);
221
222     EXPECT_FALSE(filter.FilterGestureEvent(&scroll_end));
223   }
224
225   {
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));
232
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);
238
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);
244
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);
250   }
251
252   {
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));
259
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);
265
266     EXPECT_TRUE(filter.FilterGestureEvent(&scroll_end));
267   }
268   filter.ResetTouchAction();
269 }
270
271 TEST(TouchActionFilterTest, PanXY) {
272   TouchActionFilter filter;
273   const float kDX = 5;
274   const float kDY = 10;
275   const float kFlingX = 7;
276   const float kFlingY = -4;
277
278   {
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));
285
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);
291
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);
297   }
298
299   {
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));
306
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);
312
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);
318   }
319   filter.ResetTouchAction();
320 }
321
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));
341 }
342
343 TEST(TouchActionFilterTest, MultiTouch) {
344   TouchActionFilter filter;
345
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);
354
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));
365
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();
375 }
376
377 TEST(TouchActionFilterTest, Pinch) {
378   TouchActionFilter filter;
379
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);
391
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));
400
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));
409
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));
418
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));
427
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));
435
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
442   // unit test.
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));
458
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();
473 }
474
475 TEST(TouchActionFilterTest, DoubleTapWithTouchActionAuto) {
476   TouchActionFilter filter;
477
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);
486
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
495   // of the event.
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();
501 }
502
503 TEST(TouchActionFilterTest, DoubleTap) {
504   TouchActionFilter filter;
505
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);
514
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();
530 }
531
532 TEST(TouchActionFilterTest, SingleTapWithTouchActionAuto) {
533   TouchActionFilter filter;
534
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);
541
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();
549 }
550
551 TEST(TouchActionFilterTest, SingleTap) {
552   TouchActionFilter filter;
553
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);
560
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();
569 }
570
571 TEST(TouchActionFilterTest, TouchActionResetsOnResetTouchAction) {
572   TouchActionFilter filter;
573
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);
580
581   filter.ResetTouchAction();
582   filter.OnSetTouchAction(TOUCH_ACTION_NONE);
583   EXPECT_TRUE(filter.FilterGestureEvent(&scroll_begin));
584   EXPECT_TRUE(filter.FilterGestureEvent(&scroll_end));
585
586   filter.ResetTouchAction();
587   filter.OnSetTouchAction(TOUCH_ACTION_NONE);
588   EXPECT_FALSE(filter.FilterGestureEvent(&tap));
589
590   filter.ResetTouchAction();
591   EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin));
592 }
593
594 }  // namespace content