gesture_provider_unittest.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
1// Copyright 2014 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 "base/basictypes.h"
6#include "base/logging.h"
7#include "base/memory/scoped_ptr.h"
8#include "base/message_loop/message_loop.h"
9#include "base/time/time.h"
10#include "testing/gtest/include/gtest/gtest.h"
11#include "ui/events/event_constants.h"
12#include "ui/events/gesture_detection/gesture_event_data.h"
13#include "ui/events/gesture_detection/gesture_provider.h"
14#include "ui/events/gesture_detection/mock_motion_event.h"
15#include "ui/events/gesture_detection/motion_event.h"
16#include "ui/gfx/geometry/point_f.h"
17
18using base::TimeDelta;
19using base::TimeTicks;
20
21namespace ui {
22namespace {
23
24const float kFakeCoordX = 42.f;
25const float kFakeCoordY = 24.f;
26const TimeDelta kOneSecond = TimeDelta::FromSeconds(1);
27const TimeDelta kOneMicrosecond = TimeDelta::FromMicroseconds(1);
28const TimeDelta kDeltaTimeForFlingSequences = TimeDelta::FromMilliseconds(5);
29
30GestureProvider::Config CreateDefaultConfig() {
31  GestureProvider::Config sConfig;
32  // The longpress timeout is non-zero only to indicate ordering with respect to
33  // the showpress timeout.
34  sConfig.gesture_detector_config.showpress_timeout = base::TimeDelta();
35  sConfig.gesture_detector_config.longpress_timeout = kOneMicrosecond;
36
37  // A valid doubletap timeout should always be non-zero. The value is used not
38  // only to trigger the timeout that confirms the tap event, but also to gate
39  // whether the second tap is in fact a double-tap (using a strict inequality
40  // between times for the first up and the second down events). We use 4
41  // microseconds simply to allow several intermediate events to occur before
42  // the second tap at microsecond intervals.
43  sConfig.gesture_detector_config.double_tap_timeout = kOneMicrosecond * 4;
44  return sConfig;
45}
46
47}  // namespace
48
49class GestureProviderTest : public testing::Test, public GestureProviderClient {
50 public:
51  GestureProviderTest() {}
52  virtual ~GestureProviderTest() {}
53
54  static MockMotionEvent ObtainMotionEvent(base::TimeTicks event_time,
55                                           MotionEvent::Action action,
56                                           float x,
57                                           float y) {
58    return MockMotionEvent(action, event_time, x, y);
59  }
60
61  static MockMotionEvent ObtainMotionEvent(base::TimeTicks event_time,
62                                           MotionEvent::Action action,
63                                           float x0,
64                                           float y0,
65                                           float x1,
66                                           float y1) {
67    return MockMotionEvent(action, event_time, x0, y0, x1, y1);
68  }
69
70  static MockMotionEvent ObtainMotionEvent(base::TimeTicks event_time,
71                                           MotionEvent::Action action) {
72    return ObtainMotionEvent(event_time, action, kFakeCoordX, kFakeCoordY);
73  }
74
75  // Test
76  virtual void SetUp() OVERRIDE {
77    gesture_provider_.reset(new GestureProvider(GetDefaultConfig(), this));
78    gesture_provider_->SetMultiTouchSupportEnabled(false);
79  }
80
81  virtual void TearDown() OVERRIDE {
82    gestures_.clear();
83    gesture_provider_.reset();
84  }
85
86  // GestureProviderClient
87  virtual void OnGestureEvent(const GestureEventData& gesture) OVERRIDE {
88    if (gesture.type == ET_GESTURE_SCROLL_BEGIN)
89      active_scroll_begin_event_.reset(new GestureEventData(gesture));
90    gestures_.push_back(gesture);
91  }
92
93  bool CancelActiveTouchSequence() {
94    if (!gesture_provider_->current_down_event())
95      return false;
96    return gesture_provider_->OnTouchEvent(
97        *gesture_provider_->current_down_event()->Cancel());
98  }
99
100  bool HasReceivedGesture(EventType type) const {
101    for (size_t i = 0; i < gestures_.size(); ++i) {
102      if (gestures_[i].type == type)
103        return true;
104    }
105    return false;
106  }
107
108  const GestureEventData& GetMostRecentGestureEvent() const {
109    EXPECT_FALSE(gestures_.empty());
110    return gestures_.back();
111  }
112
113  const EventType GetMostRecentGestureEventType() const {
114    EXPECT_FALSE(gestures_.empty());
115    return gestures_.back().type;
116  }
117
118  size_t GetReceivedGestureCount() const { return gestures_.size(); }
119
120  const GestureEventData& GetReceivedGesture(size_t index) const {
121    EXPECT_LT(index, GetReceivedGestureCount());
122    return gestures_[index];
123  }
124
125  const GestureEventData* GetActiveScrollBeginEvent() const {
126    return active_scroll_begin_event_ ? active_scroll_begin_event_.get() : NULL;
127  }
128
129  const GestureProvider::Config& GetDefaultConfig() const {
130    static GestureProvider::Config sConfig = CreateDefaultConfig();
131    return sConfig;
132  }
133
134  int GetTouchSlop() const {
135    return GetDefaultConfig().gesture_detector_config.scaled_touch_slop;
136  }
137
138  base::TimeDelta GetLongPressTimeout() const {
139    return GetDefaultConfig().gesture_detector_config.longpress_timeout;
140  }
141
142  base::TimeDelta GetShowPressTimeout() const {
143    return GetDefaultConfig().gesture_detector_config.showpress_timeout;
144  }
145
146 protected:
147  void CheckScrollEventSequenceForEndActionType(
148      MotionEvent::Action end_action_type) {
149    base::TimeTicks event_time = base::TimeTicks::Now();
150    const int scroll_to_x = kFakeCoordX + 100;
151    const int scroll_to_y = kFakeCoordY + 100;
152
153    MockMotionEvent event =
154        ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
155
156    EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
157
158    event = ObtainMotionEvent(event_time + kOneSecond,
159                              MotionEvent::ACTION_MOVE,
160                              scroll_to_x,
161                              scroll_to_y);
162    EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
163    EXPECT_TRUE(gesture_provider_->IsScrollInProgress());
164    EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
165    EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
166    ASSERT_EQ(4U, GetReceivedGestureCount()) << "Only TapDown, TapCancel, "
167                                                "ScrollBegin and ScrollBy "
168                                                "should have been sent";
169
170    EXPECT_EQ(ET_GESTURE_TAP_CANCEL, GetReceivedGesture(1).type);
171    EXPECT_EQ(ET_GESTURE_SCROLL_BEGIN, GetReceivedGesture(2).type);
172    EXPECT_EQ(event_time + kOneSecond, GetReceivedGesture(2).time)
173        << "ScrollBegin should have the time of the ACTION_MOVE";
174
175    event = ObtainMotionEvent(
176        event_time + kOneSecond, end_action_type, scroll_to_x, scroll_to_y);
177    gesture_provider_->OnTouchEvent(event);
178    EXPECT_FALSE(gesture_provider_->IsScrollInProgress());
179    EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_END));
180    EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
181  }
182
183  static void RunTasksAndWait(base::TimeDelta delay) {
184    base::MessageLoop::current()->PostDelayedTask(
185        FROM_HERE, base::MessageLoop::QuitClosure(), delay);
186    base::MessageLoop::current()->Run();
187  }
188
189  std::vector<GestureEventData> gestures_;
190  scoped_ptr<GestureProvider> gesture_provider_;
191  scoped_ptr<GestureEventData> active_scroll_begin_event_;
192  base::MessageLoopForUI message_loop_;
193};
194
195// Verify that a DOWN followed shortly by an UP will trigger a single tap.
196TEST_F(GestureProviderTest, GestureTapTap) {
197  base::TimeTicks event_time = base::TimeTicks::Now();
198
199  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false);
200
201  MockMotionEvent event =
202      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
203  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
204  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
205
206  event = ObtainMotionEvent(event_time + kOneMicrosecond,
207                            MotionEvent::ACTION_UP);
208  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
209  EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
210  // Ensure tap details have been set.
211  EXPECT_EQ(10, GetMostRecentGestureEvent().details.tap.width);
212  EXPECT_EQ(10, GetMostRecentGestureEvent().details.tap.height);
213  EXPECT_EQ(1, GetMostRecentGestureEvent().details.tap.tap_count);
214
215}
216
217// Verify that a DOWN followed shortly by an UP will trigger
218// a ET_GESTURE_TAP_UNCONFIRMED event if double-tap is enabled.
219TEST_F(GestureProviderTest, GestureTapTapWithDelay) {
220  base::TimeTicks event_time = base::TimeTicks::Now();
221
222  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true);
223
224  MockMotionEvent event =
225      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
226  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
227  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
228
229  event = ObtainMotionEvent(event_time + kOneMicrosecond,
230                            MotionEvent::ACTION_UP);
231  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
232  EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
233  // Ensure tap details have been set.
234  EXPECT_EQ(10, GetMostRecentGestureEvent().details.tap.width);
235  EXPECT_EQ(10, GetMostRecentGestureEvent().details.tap.height);
236  EXPECT_EQ(1, GetMostRecentGestureEvent().details.tap.tap_count);
237
238  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_TAP));
239}
240
241// Verify that a DOWN followed by a MOVE will trigger fling (but not LONG).
242TEST_F(GestureProviderTest, GestureFlingAndCancelLongPress) {
243  base::TimeTicks event_time = TimeTicks::Now();
244  base::TimeDelta delta_time = kDeltaTimeForFlingSequences;
245
246  MockMotionEvent event =
247      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
248
249  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
250  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
251
252  event = ObtainMotionEvent(event_time + delta_time,
253                            MotionEvent::ACTION_MOVE,
254                            kFakeCoordX * 10,
255                            kFakeCoordY * 10);
256  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
257
258  event = ObtainMotionEvent(event_time + delta_time * 2,
259                            MotionEvent::ACTION_UP,
260                            kFakeCoordX * 10,
261                            kFakeCoordY * 10);
262  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
263  EXPECT_EQ(ET_SCROLL_FLING_START, GetMostRecentGestureEventType());
264  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_PRESS));
265}
266
267// Verify that for a normal scroll the following events are sent:
268// - ET_GESTURE_SCROLL_BEGIN
269// - ET_GESTURE_SCROLL_UPDATE
270// - ET_GESTURE_SCROLL_END
271TEST_F(GestureProviderTest, ScrollEventActionUpSequence) {
272  CheckScrollEventSequenceForEndActionType(MotionEvent::ACTION_UP);
273}
274
275// Verify that for a cancelled scroll the following events are sent:
276// - ET_GESTURE_SCROLL_BEGIN
277// - ET_GESTURE_SCROLL_UPDATE
278// - ET_GESTURE_SCROLL_END
279TEST_F(GestureProviderTest, ScrollEventActionCancelSequence) {
280  CheckScrollEventSequenceForEndActionType(MotionEvent::ACTION_CANCEL);
281}
282
283// Verify that for a normal fling (fling after scroll) the following events are
284// sent:
285// - ET_GESTURE_SCROLL_BEGIN
286// - ET_SCROLL_FLING_START
287TEST_F(GestureProviderTest, FlingEventSequence) {
288  base::TimeTicks event_time = base::TimeTicks::Now();
289  base::TimeDelta delta_time = kDeltaTimeForFlingSequences;
290
291  MockMotionEvent event =
292      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
293
294  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
295
296  event = ObtainMotionEvent(event_time + delta_time,
297                            MotionEvent::ACTION_MOVE,
298                            kFakeCoordX * 5,
299                            kFakeCoordY * 5);
300  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
301  EXPECT_TRUE(gesture_provider_->IsScrollInProgress());
302  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
303  EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
304  ASSERT_EQ(4U, GetReceivedGestureCount());
305  ASSERT_EQ(ET_GESTURE_SCROLL_BEGIN, GetReceivedGesture(2).type);
306
307  // We don't want to take a dependency here on exactly how hints are calculated
308  // for a fling (eg. may depend on velocity), so just validate the direction.
309  int hint_x = GetReceivedGesture(2).details.scroll_begin.delta_x_hint;
310  int hint_y = GetReceivedGesture(2).details.scroll_begin.delta_y_hint;
311  EXPECT_TRUE(hint_x > 0 && hint_y > 0 && hint_x > hint_y)
312      << "ScrollBegin hint should be in positive X axis";
313
314  event = ObtainMotionEvent(event_time + delta_time * 2,
315                            MotionEvent::ACTION_UP,
316                            kFakeCoordX * 10,
317                            kFakeCoordY * 10);
318  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
319  EXPECT_FALSE(gesture_provider_->IsScrollInProgress());
320  EXPECT_EQ(ET_SCROLL_FLING_START, GetMostRecentGestureEventType());
321  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SCROLL_END));
322  EXPECT_EQ(event_time + delta_time * 2, GetMostRecentGestureEvent().time)
323      << "FlingStart should have the time of the ACTION_UP";
324}
325
326TEST_F(GestureProviderTest, TapCancelledWhenWindowFocusLost) {
327  const base::TimeTicks event_time = TimeTicks::Now();
328
329  MockMotionEvent event =
330      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
331  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
332  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
333
334  RunTasksAndWait(GetLongPressTimeout() + GetShowPressTimeout() +
335                  kOneMicrosecond);
336  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SHOW_PRESS));
337  EXPECT_EQ(ET_GESTURE_LONG_PRESS, GetMostRecentGestureEventType());
338
339  // The long press triggers window focus loss by opening a context menu
340  EXPECT_TRUE(CancelActiveTouchSequence());
341  EXPECT_EQ(ET_GESTURE_TAP_CANCEL, GetMostRecentGestureEventType());
342}
343
344TEST_F(GestureProviderTest, TapCancelledWhenScrollBegins) {
345  base::TimeTicks event_time = base::TimeTicks::Now();
346
347  MockMotionEvent event =
348      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
349
350  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
351
352  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
353  event = ObtainMotionEvent(event_time + kOneMicrosecond,
354                            MotionEvent::ACTION_MOVE,
355                            kFakeCoordX + 50,
356                            kFakeCoordY + 50);
357  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
358
359  EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
360  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_TAP_CANCEL));
361}
362
363TEST_F(GestureProviderTest, DoubleTap) {
364  base::TimeTicks event_time = base::TimeTicks::Now();
365
366  MockMotionEvent event =
367      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
368  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
369
370  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
371
372  event = ObtainMotionEvent(event_time + kOneMicrosecond,
373                            MotionEvent::ACTION_UP,
374                            kFakeCoordX,
375                            kFakeCoordY);
376  gesture_provider_->OnTouchEvent(event);
377  EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
378
379  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
380                            MotionEvent::ACTION_DOWN,
381                            kFakeCoordX,
382                            kFakeCoordY);
383  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
384  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
385
386  // Moving a very small amount of distance should not trigger the double tap
387  // drag zoom mode.
388  event = ObtainMotionEvent(event_time + kOneMicrosecond * 3,
389                            MotionEvent::ACTION_MOVE,
390                            kFakeCoordX,
391                            kFakeCoordY + 1);
392  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
393  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
394
395  event = ObtainMotionEvent(event_time + kOneMicrosecond * 3,
396                            MotionEvent::ACTION_UP,
397                            kFakeCoordX,
398                            kFakeCoordY + 1);
399  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
400
401  const GestureEventData& double_tap = GetMostRecentGestureEvent();
402  EXPECT_EQ(ET_GESTURE_DOUBLE_TAP, double_tap.type);
403  // Ensure tap details have been set.
404  EXPECT_EQ(10, double_tap.details.tap.width);
405  EXPECT_EQ(10, double_tap.details.tap.height);
406  EXPECT_EQ(1, double_tap.details.tap.tap_count);
407}
408
409TEST_F(GestureProviderTest, DoubleTapDragZoom) {
410  const base::TimeTicks down_time_1 = TimeTicks::Now();
411  const base::TimeTicks down_time_2 = down_time_1 + kOneMicrosecond * 2;
412
413  MockMotionEvent event =
414      ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
415  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
416
417  event = ObtainMotionEvent(down_time_1 + kOneMicrosecond,
418                            MotionEvent::ACTION_UP,
419                            kFakeCoordX,
420                            kFakeCoordY);
421  gesture_provider_->OnTouchEvent(event);
422  EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
423
424  event = ObtainMotionEvent(
425      down_time_2, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
426  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
427  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
428
429  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
430                            MotionEvent::ACTION_MOVE,
431                            kFakeCoordX,
432                            kFakeCoordY + 100);
433  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
434  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
435  const GestureEventData* scroll_begin_gesture = GetActiveScrollBeginEvent();
436  ASSERT_TRUE(!!scroll_begin_gesture);
437  EXPECT_EQ(0, scroll_begin_gesture->details.scroll_begin.delta_x_hint);
438  EXPECT_EQ(100, scroll_begin_gesture->details.scroll_begin.delta_y_hint);
439  EXPECT_EQ(ET_GESTURE_PINCH_BEGIN, GetMostRecentGestureEventType());
440
441  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
442                            MotionEvent::ACTION_MOVE,
443                            kFakeCoordX,
444                            kFakeCoordY + 200);
445  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
446  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_UPDATE));
447  EXPECT_EQ(ET_GESTURE_PINCH_UPDATE, GetMostRecentGestureEventType());
448
449  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
450                            MotionEvent::ACTION_UP,
451                            kFakeCoordX,
452                            kFakeCoordY + 200);
453  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
454  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_PINCH_END));
455  EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
456}
457
458TEST_F(GestureProviderTest, DoubleTapDragZoomCancelledOnSecondaryPointerDown) {
459  const base::TimeTicks down_time_1 = TimeTicks::Now();
460  const base::TimeTicks down_time_2 = down_time_1 + kOneMicrosecond * 2;
461
462  MockMotionEvent event =
463      ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
464  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
465  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
466
467  event = ObtainMotionEvent(down_time_1 + kOneMicrosecond,
468                            MotionEvent::ACTION_UP);
469  gesture_provider_->OnTouchEvent(event);
470  EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
471
472  event = ObtainMotionEvent(down_time_2, MotionEvent::ACTION_DOWN);
473  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
474  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
475  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_TAP_CANCEL));
476
477  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
478                            MotionEvent::ACTION_MOVE,
479                            kFakeCoordX,
480                            kFakeCoordY - 30);
481  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
482  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
483  EXPECT_EQ(ET_GESTURE_PINCH_BEGIN, GetMostRecentGestureEventType());
484
485  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
486                            MotionEvent::ACTION_POINTER_DOWN,
487                            kFakeCoordX,
488                            kFakeCoordY - 30,
489                            kFakeCoordX + 50,
490                            kFakeCoordY + 50);
491  gesture_provider_->OnTouchEvent(event);
492  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_PINCH_END));
493  EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
494  const size_t gesture_count = GetReceivedGestureCount();
495
496  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
497                            MotionEvent::ACTION_POINTER_UP,
498                            kFakeCoordX,
499                            kFakeCoordY - 30,
500                            kFakeCoordX + 50,
501                            kFakeCoordY + 50);
502  gesture_provider_->OnTouchEvent(event);
503  EXPECT_EQ(gesture_count, GetReceivedGestureCount());
504}
505
506// Generate a scroll gesture and verify that the resulting scroll motion event
507// has both absolute and relative position information.
508TEST_F(GestureProviderTest, ScrollUpdateValues) {
509  const int delta_x = 16;
510  const int delta_y = 84;
511
512  const base::TimeTicks event_time = TimeTicks::Now();
513
514  MockMotionEvent event =
515      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
516  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
517
518  // Move twice so that we get two ET_GESTURE_SCROLL_UPDATE events and can
519  // compare the relative and absolute coordinates.
520  event = ObtainMotionEvent(event_time + kOneMicrosecond,
521                            MotionEvent::ACTION_MOVE,
522                            kFakeCoordX - delta_x / 2,
523                            kFakeCoordY - delta_y / 2);
524  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
525
526  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
527                            MotionEvent::ACTION_MOVE,
528                            kFakeCoordX - delta_x,
529                            kFakeCoordY - delta_y);
530  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
531
532  // Make sure the reported gesture event has all the expected details.
533  ASSERT_LT(0U, GetReceivedGestureCount());
534  GestureEventData gesture = GetMostRecentGestureEvent();
535  EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, gesture.type);
536  EXPECT_EQ(event_time + kOneMicrosecond * 2, gesture.time);
537  EXPECT_EQ(kFakeCoordX - delta_x, gesture.x);
538  EXPECT_EQ(kFakeCoordY - delta_y, gesture.y);
539
540  // No horizontal delta because of snapping.
541  EXPECT_EQ(0, gesture.details.scroll_update.delta_x);
542  EXPECT_EQ(-delta_y / 2, gesture.details.scroll_update.delta_y);
543}
544
545// Verify that fractional scroll deltas are rounded as expected and that
546// fractional scrolling doesn't break scroll snapping.
547TEST_F(GestureProviderTest, FractionalScroll) {
548  const float delta_x = 0.4f;
549  const float delta_y = 5.2f;
550
551  const base::TimeTicks event_time = TimeTicks::Now();
552
553  MockMotionEvent event =
554      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
555  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
556
557  // Skip past the touch slop and move back.
558  event = ObtainMotionEvent(event_time,
559                            MotionEvent::ACTION_MOVE,
560                            kFakeCoordX,
561                            kFakeCoordY + 100);
562  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
563  event = ObtainMotionEvent(event_time,
564                            MotionEvent::ACTION_MOVE);
565  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
566
567  // Now move up slowly, mostly vertically but with a (fractional) bit of
568  // horizontal motion.
569  for(int i = 1; i <= 10; i++) {
570    event = ObtainMotionEvent(event_time + kOneMicrosecond * i,
571                              MotionEvent::ACTION_MOVE,
572                              kFakeCoordX + delta_x * i,
573                              kFakeCoordY + delta_y * i);
574    EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
575
576    ASSERT_LT(0U, GetReceivedGestureCount());
577    GestureEventData gesture = GetMostRecentGestureEvent();
578    EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, gesture.type);
579    EXPECT_EQ(event_time + kOneMicrosecond * i, gesture.time);
580
581    // Verify that the event co-ordinates are still the precise values we
582    // supplied.
583    EXPECT_EQ(kFakeCoordX + delta_x * i, gesture.x);
584    EXPECT_EQ(kFakeCoordY + delta_y * i, gesture.y);
585
586    // Verify that we're scrolling vertically by the expected amount
587    // (modulo rounding).
588    EXPECT_GE(gesture.details.scroll_update.delta_y, (int)delta_y);
589    EXPECT_LE(gesture.details.scroll_update.delta_y, ((int)delta_y) + 1);
590
591    // And that there has been no horizontal motion at all.
592    EXPECT_EQ(0, gesture.details.scroll_update.delta_x);
593  }
594}
595
596// Generate a scroll gesture and verify that the resulting scroll begin event
597// has the expected hint values.
598TEST_F(GestureProviderTest, ScrollBeginValues) {
599  const int delta_x = 13;
600  const int delta_y = 89;
601
602  const base::TimeTicks event_time = TimeTicks::Now();
603
604  MockMotionEvent event =
605      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
606  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
607
608  // Move twice such that the first event isn't sufficient to start
609  // scrolling on it's own.
610  event = ObtainMotionEvent(event_time + kOneMicrosecond,
611                            MotionEvent::ACTION_MOVE,
612                            kFakeCoordX + 2,
613                            kFakeCoordY + 1);
614  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
615  EXPECT_FALSE(gesture_provider_->IsScrollInProgress());
616
617  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
618                            MotionEvent::ACTION_MOVE,
619                            kFakeCoordX + delta_x,
620                            kFakeCoordY + delta_y);
621  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
622  EXPECT_TRUE(gesture_provider_->IsScrollInProgress());
623
624  const GestureEventData* scroll_begin_gesture = GetActiveScrollBeginEvent();
625  ASSERT_TRUE(!!scroll_begin_gesture);
626  EXPECT_EQ(delta_x, scroll_begin_gesture->details.scroll_begin.delta_x_hint);
627  EXPECT_EQ(delta_y, scroll_begin_gesture->details.scroll_begin.delta_y_hint);
628}
629
630TEST_F(GestureProviderTest, LongPressAndTapCancelledWhenScrollBegins) {
631  base::TimeTicks event_time = base::TimeTicks::Now();
632
633  MockMotionEvent event =
634      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
635  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
636  event = ObtainMotionEvent(event_time + kOneMicrosecond,
637                            MotionEvent::ACTION_MOVE,
638                            kFakeCoordX * 5,
639                            kFakeCoordY * 5);
640  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
641  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
642                            MotionEvent::ACTION_MOVE,
643                            kFakeCoordX * 10,
644                            kFakeCoordY * 10);
645  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
646
647  const base::TimeDelta long_press_timeout =
648      GetLongPressTimeout() + GetShowPressTimeout() + kOneMicrosecond;
649  RunTasksAndWait(long_press_timeout);
650
651  // No LONG_TAP as the LONG_PRESS timer is cancelled.
652  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_PRESS));
653  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_TAP));
654}
655
656// Verify that LONG_TAP is triggered after LONG_PRESS followed by an UP.
657TEST_F(GestureProviderTest, GestureLongTap) {
658  base::TimeTicks event_time = base::TimeTicks::Now();
659
660  MockMotionEvent event =
661      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
662  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
663
664  const base::TimeDelta long_press_timeout =
665      GetLongPressTimeout() + GetShowPressTimeout() + kOneMicrosecond;
666  RunTasksAndWait(long_press_timeout);
667
668  EXPECT_EQ(ET_GESTURE_LONG_PRESS, GetMostRecentGestureEventType());
669
670  event = ObtainMotionEvent(event_time + kOneSecond, MotionEvent::ACTION_UP);
671  gesture_provider_->OnTouchEvent(event);
672  EXPECT_EQ(ET_GESTURE_LONG_TAP, GetMostRecentGestureEventType());
673}
674
675TEST_F(GestureProviderTest, GestureLongPressDoesNotPreventScrolling) {
676  base::TimeTicks event_time = base::TimeTicks::Now();
677
678  MockMotionEvent event =
679      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
680  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
681
682  const base::TimeDelta long_press_timeout =
683      GetLongPressTimeout() + GetShowPressTimeout() + kOneMicrosecond;
684  RunTasksAndWait(long_press_timeout);
685
686  EXPECT_EQ(ET_GESTURE_LONG_PRESS, GetMostRecentGestureEventType());
687  event = ObtainMotionEvent(event_time + long_press_timeout,
688                            MotionEvent::ACTION_MOVE,
689                            kFakeCoordX + 100,
690                            kFakeCoordY + 100);
691  gesture_provider_->OnTouchEvent(event);
692
693  EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
694  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
695  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_TAP_CANCEL));
696
697  event = ObtainMotionEvent(event_time + long_press_timeout,
698                            MotionEvent::ACTION_UP);
699  gesture_provider_->OnTouchEvent(event);
700  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_TAP));
701}
702
703TEST_F(GestureProviderTest, NoGestureLongPressDuringDoubleTap) {
704  base::TimeTicks event_time = base::TimeTicks::Now();
705
706  MockMotionEvent event = ObtainMotionEvent(
707      event_time, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
708  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
709
710  event = ObtainMotionEvent(event_time + kOneMicrosecond,
711                            MotionEvent::ACTION_UP,
712                            kFakeCoordX,
713                            kFakeCoordY);
714  gesture_provider_->OnTouchEvent(event);
715  EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
716
717  event = ObtainMotionEvent(event_time + kOneMicrosecond,
718                            MotionEvent::ACTION_DOWN,
719                            kFakeCoordX,
720                            kFakeCoordY);
721  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
722  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
723  EXPECT_TRUE(gesture_provider_->IsDoubleTapInProgress());
724
725  const base::TimeDelta long_press_timeout =
726      GetLongPressTimeout() + GetShowPressTimeout() + kOneMicrosecond;
727  RunTasksAndWait(long_press_timeout);
728  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_PRESS));
729
730  event = ObtainMotionEvent(event_time + long_press_timeout,
731                            MotionEvent::ACTION_MOVE,
732                            kFakeCoordX + 20,
733                            kFakeCoordY + 20);
734  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
735  EXPECT_EQ(ET_GESTURE_PINCH_BEGIN, GetMostRecentGestureEventType());
736  EXPECT_TRUE(gesture_provider_->IsDoubleTapInProgress());
737
738  event = ObtainMotionEvent(event_time + long_press_timeout + kOneMicrosecond,
739                            MotionEvent::ACTION_UP,
740                            kFakeCoordX,
741                            kFakeCoordY + 1);
742  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
743  EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
744  EXPECT_FALSE(gesture_provider_->IsDoubleTapInProgress());
745}
746
747// Verify that the touch slop region is removed from the first scroll delta to
748// avoid a jump when starting to scroll.
749TEST_F(GestureProviderTest, TouchSlopRemovedFromScroll) {
750  const int scaled_touch_slop = GetTouchSlop();
751  const int scroll_delta = 5;
752
753  base::TimeTicks event_time = base::TimeTicks::Now();
754
755  MockMotionEvent event =
756      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
757  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
758
759  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
760                            MotionEvent::ACTION_MOVE,
761                            kFakeCoordX,
762                            kFakeCoordY + scaled_touch_slop + scroll_delta);
763  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
764
765  EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
766  GestureEventData gesture = GetMostRecentGestureEvent();
767  EXPECT_EQ(0, gesture.details.scroll_update.delta_x);
768  EXPECT_EQ(scroll_delta, gesture.details.scroll_update.delta_y);
769}
770
771TEST_F(GestureProviderTest, NoDoubleTapWhenExplicitlyDisabled) {
772  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false);
773
774  base::TimeTicks event_time = base::TimeTicks::Now();
775  MockMotionEvent event = ObtainMotionEvent(
776      event_time, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
777  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
778  EXPECT_EQ(1U, GetReceivedGestureCount());
779  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
780
781  event = ObtainMotionEvent(event_time + kOneMicrosecond,
782                            MotionEvent::ACTION_UP,
783                            kFakeCoordX,
784                            kFakeCoordY);
785  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
786  EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
787
788  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
789                            MotionEvent::ACTION_DOWN,
790                            kFakeCoordX,
791                            kFakeCoordY);
792  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
793  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
794
795  event = ObtainMotionEvent(event_time + kOneMicrosecond * 3,
796                            MotionEvent::ACTION_UP,
797                            kFakeCoordX,
798                            kFakeCoordY);
799  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
800  EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
801}
802
803TEST_F(GestureProviderTest, NoDoubleTapDragZoomWhenDisabledOnPlatform) {
804  const base::TimeTicks down_time_1 = TimeTicks::Now();
805  const base::TimeTicks down_time_2 = down_time_1 + kOneMicrosecond * 2;
806
807  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false);
808
809  MockMotionEvent event =
810      ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
811  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
812
813  event = ObtainMotionEvent(down_time_1 + kOneMicrosecond,
814                            MotionEvent::ACTION_UP,
815                            kFakeCoordX,
816                            kFakeCoordY);
817  gesture_provider_->OnTouchEvent(event);
818
819  event = ObtainMotionEvent(
820      down_time_2, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
821  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
822
823  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
824                            MotionEvent::ACTION_MOVE,
825                            kFakeCoordX,
826                            kFakeCoordY + 100);
827
828  // The move should become a scroll, as doubletap drag zoom is disabled.
829  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
830  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
831  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_BEGIN));
832
833  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
834                            MotionEvent::ACTION_MOVE,
835                            kFakeCoordX,
836                            kFakeCoordY + 200);
837  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
838  EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
839  EXPECT_EQ(down_time_2 + kOneMicrosecond * 2,
840            GetMostRecentGestureEvent().time);
841  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_UPDATE));
842
843  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
844                            MotionEvent::ACTION_UP,
845                            kFakeCoordX,
846                            kFakeCoordY + 200);
847  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
848  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_END));
849}
850
851// Verify that double tap drag zoom feature is not invoked when the gesture
852// handler is told to disable double tap gesture detection.
853// The second tap sequence should be treated just as the first would be.
854TEST_F(GestureProviderTest, NoDoubleTapDragZoomWhenDisabledOnPage) {
855  const base::TimeTicks down_time_1 = TimeTicks::Now();
856  const base::TimeTicks down_time_2 = down_time_1 + kOneMicrosecond * 2;
857
858  gesture_provider_->SetDoubleTapSupportForPageEnabled(false);
859
860  MockMotionEvent event =
861      ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
862  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
863
864  event = ObtainMotionEvent(down_time_1 + kOneMicrosecond,
865                            MotionEvent::ACTION_UP,
866                            kFakeCoordX,
867                            kFakeCoordY);
868  gesture_provider_->OnTouchEvent(event);
869
870  event = ObtainMotionEvent(
871      down_time_2, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
872  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
873
874  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
875                            MotionEvent::ACTION_MOVE,
876                            kFakeCoordX,
877                            kFakeCoordY + 100);
878
879  // The move should become a scroll, as double tap drag zoom is disabled.
880  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
881  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
882  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_BEGIN));
883
884  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
885                            MotionEvent::ACTION_MOVE,
886                            kFakeCoordX,
887                            kFakeCoordY + 200);
888  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
889  EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
890  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_UPDATE));
891
892  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
893                            MotionEvent::ACTION_UP,
894                            kFakeCoordX,
895                            kFakeCoordY + 200);
896  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
897  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_END));
898}
899
900// Verify that updating double tap support during a double tap drag zoom
901// disables double tap detection after the gesture has ended.
902TEST_F(GestureProviderTest, FixedPageScaleDuringDoubleTapDragZoom) {
903  base::TimeTicks down_time_1 = TimeTicks::Now();
904  base::TimeTicks down_time_2 = down_time_1 + kOneMicrosecond * 2;
905
906  // Start a double-tap drag gesture.
907  MockMotionEvent event =
908      ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
909  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
910  event = ObtainMotionEvent(down_time_1 + kOneMicrosecond,
911                            MotionEvent::ACTION_UP,
912                            kFakeCoordX,
913                            kFakeCoordY);
914  gesture_provider_->OnTouchEvent(event);
915  event = ObtainMotionEvent(
916      down_time_2, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
917  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
918  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
919                            MotionEvent::ACTION_MOVE,
920                            kFakeCoordX,
921                            kFakeCoordY + 100);
922  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
923  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
924  EXPECT_EQ(ET_GESTURE_PINCH_BEGIN, GetMostRecentGestureEventType());
925
926  // Simulate setting a fixed page scale (or a mobile viewport);
927  // this should not disrupt the current double-tap gesture.
928  gesture_provider_->SetDoubleTapSupportForPageEnabled(false);
929
930  // Double tap zoom updates should continue.
931  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
932                            MotionEvent::ACTION_MOVE,
933                            kFakeCoordX,
934                            kFakeCoordY + 200);
935  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
936  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_UPDATE));
937  EXPECT_EQ(ET_GESTURE_PINCH_UPDATE, GetMostRecentGestureEventType());
938  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
939                            MotionEvent::ACTION_UP,
940                            kFakeCoordX,
941                            kFakeCoordY + 200);
942  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
943  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_PINCH_END));
944  EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
945
946  // The double-tap gesture has finished, but the page scale is fixed.
947  // The same event sequence should not generate any double tap getsures.
948  gestures_.clear();
949  down_time_1 += kOneMicrosecond * 40;
950  down_time_2 += kOneMicrosecond * 40;
951
952  // Start a double-tap drag gesture.
953  event = ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
954  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
955  event = ObtainMotionEvent(down_time_1 + kOneMicrosecond,
956                            MotionEvent::ACTION_UP,
957                            kFakeCoordX,
958                            kFakeCoordY);
959  gesture_provider_->OnTouchEvent(event);
960  event = ObtainMotionEvent(
961      down_time_2, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
962  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
963  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
964                            MotionEvent::ACTION_MOVE,
965                            kFakeCoordX,
966                            kFakeCoordY + 100);
967  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
968  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
969  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_BEGIN));
970
971  // Double tap zoom updates should not be sent.
972  // Instead, the second tap drag becomes a scroll gesture sequence.
973  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
974                            MotionEvent::ACTION_MOVE,
975                            kFakeCoordX,
976                            kFakeCoordY + 200);
977  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
978  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_UPDATE));
979  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_UPDATE));
980  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
981                            MotionEvent::ACTION_UP,
982                            kFakeCoordX,
983                            kFakeCoordY + 200);
984  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
985  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_END));
986}
987
988// Verify that pinch zoom sends the proper event sequence.
989TEST_F(GestureProviderTest, PinchZoom) {
990  base::TimeTicks event_time = base::TimeTicks::Now();
991  const int scaled_touch_slop = GetTouchSlop();
992
993  gesture_provider_->SetMultiTouchSupportEnabled(true);
994
995  int secondary_coord_x = kFakeCoordX + 20 * scaled_touch_slop;
996  int secondary_coord_y = kFakeCoordY + 20 * scaled_touch_slop;
997
998  MockMotionEvent event =
999      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
1000  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1001  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1002
1003  event = ObtainMotionEvent(event_time,
1004                            MotionEvent::ACTION_POINTER_DOWN,
1005                            kFakeCoordX,
1006                            kFakeCoordY,
1007                            secondary_coord_x,
1008                            secondary_coord_y);
1009  gesture_provider_->OnTouchEvent(event);
1010  EXPECT_EQ(1U, GetReceivedGestureCount());
1011
1012  secondary_coord_x += 5 * scaled_touch_slop;
1013  secondary_coord_y += 5 * scaled_touch_slop;
1014
1015  event = ObtainMotionEvent(event_time,
1016                            MotionEvent::ACTION_MOVE,
1017                            kFakeCoordX,
1018                            kFakeCoordY,
1019                            secondary_coord_x,
1020                            secondary_coord_y);
1021
1022  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1023  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_PINCH_BEGIN));
1024  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
1025  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_PINCH_UPDATE));
1026  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_UPDATE));
1027
1028  event = ObtainMotionEvent(event_time,
1029                            MotionEvent::ACTION_POINTER_UP,
1030                            kFakeCoordX,
1031                            kFakeCoordY,
1032                            secondary_coord_x,
1033                            secondary_coord_y);
1034
1035  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1036  EXPECT_EQ(ET_GESTURE_PINCH_END, GetMostRecentGestureEventType());
1037  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SCROLL_END));
1038
1039  event = ObtainMotionEvent(event_time, MotionEvent::ACTION_UP);
1040  gesture_provider_->OnTouchEvent(event);
1041  EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
1042}
1043
1044// Verify that the timer of LONG_PRESS will be cancelled when scrolling begins
1045// so LONG_PRESS and LONG_TAP won't be triggered.
1046TEST_F(GestureProviderTest, GesturesCancelledAfterLongPressCausesLostFocus) {
1047  base::TimeTicks event_time = base::TimeTicks::Now();
1048
1049  MockMotionEvent event =
1050      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
1051  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1052
1053  const base::TimeDelta long_press_timeout =
1054      GetLongPressTimeout() + GetShowPressTimeout() + kOneMicrosecond;
1055  RunTasksAndWait(long_press_timeout);
1056  EXPECT_EQ(ET_GESTURE_LONG_PRESS, GetMostRecentGestureEventType());
1057
1058  EXPECT_TRUE(CancelActiveTouchSequence());
1059  EXPECT_EQ(ET_GESTURE_TAP_CANCEL, GetMostRecentGestureEventType());
1060
1061  event = ObtainMotionEvent(event_time + long_press_timeout,
1062                            MotionEvent::ACTION_UP);
1063  gesture_provider_->OnTouchEvent(event);
1064  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_TAP));
1065}
1066
1067// Verify that inserting a touch cancel event will trigger proper touch and
1068// gesture sequence cancellation.
1069TEST_F(GestureProviderTest, CancelActiveTouchSequence) {
1070  base::TimeTicks event_time = base::TimeTicks::Now();
1071
1072  EXPECT_FALSE(CancelActiveTouchSequence());
1073  EXPECT_EQ(0U, GetReceivedGestureCount());
1074
1075  MockMotionEvent event =
1076      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
1077  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1078  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1079
1080  ASSERT_TRUE(CancelActiveTouchSequence());
1081  EXPECT_EQ(ET_GESTURE_TAP_CANCEL, GetMostRecentGestureEventType());
1082
1083  // Subsequent MotionEvent's are dropped until ACTION_DOWN.
1084  event = ObtainMotionEvent(event_time + kOneMicrosecond,
1085                            MotionEvent::ACTION_MOVE);
1086  EXPECT_FALSE(gesture_provider_->OnTouchEvent(event));
1087
1088  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
1089                            MotionEvent::ACTION_UP);
1090  EXPECT_FALSE(gesture_provider_->OnTouchEvent(event));
1091
1092  event = ObtainMotionEvent(event_time + kOneMicrosecond * 3,
1093                            MotionEvent::ACTION_DOWN);
1094  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1095  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1096}
1097
1098}  // namespace ui
1099