gesture_provider_unittest.cc revision 0529e5d033099cbfc42635f6f6183833b09dff6e
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);
29const float kMockTouchRadius = MockMotionEvent::TOUCH_MAJOR / 2;
30
31GestureProvider::Config CreateDefaultConfig() {
32  GestureProvider::Config sConfig;
33  // The longpress timeout is non-zero only to indicate ordering with respect to
34  // the showpress timeout.
35  sConfig.gesture_detector_config.showpress_timeout = base::TimeDelta();
36  sConfig.gesture_detector_config.longpress_timeout = kOneMicrosecond;
37
38  // A valid doubletap timeout should always be non-zero. The value is used not
39  // only to trigger the timeout that confirms the tap event, but also to gate
40  // whether the second tap is in fact a double-tap (using a strict inequality
41  // between times for the first up and the second down events). We use 4
42  // microseconds simply to allow several intermediate events to occur before
43  // the second tap at microsecond intervals.
44  sConfig.gesture_detector_config.double_tap_timeout = kOneMicrosecond * 4;
45  return sConfig;
46}
47
48gfx::RectF BoundsForSingleMockTouchAtLocation(float x, float y) {
49  float diameter = MockMotionEvent::TOUCH_MAJOR;
50  return gfx::RectF(x - diameter / 2, y - diameter / 2, diameter, diameter);
51}
52
53}  // namespace
54
55class GestureProviderTest : public testing::Test, public GestureProviderClient {
56 public:
57  GestureProviderTest() {}
58  virtual ~GestureProviderTest() {}
59
60  static MockMotionEvent ObtainMotionEvent(base::TimeTicks event_time,
61                                           MotionEvent::Action action,
62                                           float x,
63                                           float y) {
64    return MockMotionEvent(action, event_time, x, y);
65  }
66
67  static MockMotionEvent ObtainMotionEvent(base::TimeTicks event_time,
68                                           MotionEvent::Action action,
69                                           float x0,
70                                           float y0,
71                                           float x1,
72                                           float y1) {
73    return MockMotionEvent(action, event_time, x0, y0, x1, y1);
74  }
75
76  static MockMotionEvent ObtainMotionEvent(base::TimeTicks event_time,
77                                           MotionEvent::Action action) {
78    return ObtainMotionEvent(event_time, action, kFakeCoordX, kFakeCoordY);
79  }
80
81  // Test
82  virtual void SetUp() OVERRIDE {
83    gesture_provider_.reset(new GestureProvider(GetDefaultConfig(), this));
84    gesture_provider_->SetMultiTouchZoomSupportEnabled(false);
85  }
86
87  virtual void TearDown() OVERRIDE {
88    gestures_.clear();
89    gesture_provider_.reset();
90  }
91
92  // GestureProviderClient
93  virtual void OnGestureEvent(const GestureEventData& gesture) OVERRIDE {
94    if (gesture.type == ET_GESTURE_SCROLL_BEGIN)
95      active_scroll_begin_event_.reset(new GestureEventData(gesture));
96    gestures_.push_back(gesture);
97  }
98
99  bool CancelActiveTouchSequence() {
100    if (!gesture_provider_->current_down_event())
101      return false;
102    return gesture_provider_->OnTouchEvent(
103        *gesture_provider_->current_down_event()->Cancel());
104  }
105
106  bool HasReceivedGesture(EventType type) const {
107    for (size_t i = 0; i < gestures_.size(); ++i) {
108      if (gestures_[i].type == type)
109        return true;
110    }
111    return false;
112  }
113
114  const GestureEventData& GetMostRecentGestureEvent() const {
115    EXPECT_FALSE(gestures_.empty());
116    return gestures_.back();
117  }
118
119  EventType GetMostRecentGestureEventType() const {
120    EXPECT_FALSE(gestures_.empty());
121    return gestures_.back().type;
122  }
123
124  size_t GetReceivedGestureCount() const { return gestures_.size(); }
125
126  const GestureEventData& GetReceivedGesture(size_t index) const {
127    EXPECT_LT(index, GetReceivedGestureCount());
128    return gestures_[index];
129  }
130
131  const GestureEventData* GetActiveScrollBeginEvent() const {
132    return active_scroll_begin_event_ ? active_scroll_begin_event_.get() : NULL;
133  }
134
135  const GestureProvider::Config& GetDefaultConfig() const {
136    static GestureProvider::Config sConfig = CreateDefaultConfig();
137    return sConfig;
138  }
139
140  float GetTouchSlop() const {
141    return GetDefaultConfig().gesture_detector_config.touch_slop;
142  }
143
144  base::TimeDelta GetLongPressTimeout() const {
145    return GetDefaultConfig().gesture_detector_config.longpress_timeout;
146  }
147
148  base::TimeDelta GetShowPressTimeout() const {
149    return GetDefaultConfig().gesture_detector_config.showpress_timeout;
150  }
151
152  void SetBeginEndTypesEnabled(bool enabled) {
153    GestureProvider::Config config = GetDefaultConfig();
154    config.gesture_begin_end_types_enabled = true;
155    gesture_provider_.reset(new GestureProvider(config, this));
156    gesture_provider_->SetMultiTouchZoomSupportEnabled(false);
157  }
158
159  bool HasDownEvent() const { return gesture_provider_->current_down_event(); }
160
161 protected:
162  void CheckScrollEventSequenceForEndActionType(
163      MotionEvent::Action end_action_type) {
164    base::TimeTicks event_time = base::TimeTicks::Now();
165    const float scroll_to_x = kFakeCoordX + 100;
166    const float scroll_to_y = kFakeCoordY + 100;
167    int motion_event_id = 0;
168
169    MockMotionEvent event =
170        ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
171    event.SetId(++motion_event_id);
172
173    EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
174
175    event = ObtainMotionEvent(event_time + kOneSecond,
176                              MotionEvent::ACTION_MOVE,
177                              scroll_to_x,
178                              scroll_to_y);
179    event.SetId(++motion_event_id);
180
181    EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
182    EXPECT_TRUE(gesture_provider_->IsScrollInProgress());
183    EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
184    EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
185    EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
186    EXPECT_EQ(BoundsForSingleMockTouchAtLocation(scroll_to_x, scroll_to_y),
187              GetMostRecentGestureEvent().details.bounding_box());
188    ASSERT_EQ(3U, GetReceivedGestureCount()) << "Only TapDown, "
189                                                "ScrollBegin and ScrollBy "
190                                                "should have been sent";
191
192    EXPECT_EQ(ET_GESTURE_SCROLL_BEGIN, GetReceivedGesture(1).type);
193    EXPECT_EQ(motion_event_id, GetReceivedGesture(1).motion_event_id);
194    EXPECT_EQ(event_time + kOneSecond, GetReceivedGesture(1).time)
195        << "ScrollBegin should have the time of the ACTION_MOVE";
196
197    event = ObtainMotionEvent(
198        event_time + kOneSecond, end_action_type, scroll_to_x, scroll_to_y);
199    event.SetId(++motion_event_id);
200
201    gesture_provider_->OnTouchEvent(event);
202    EXPECT_FALSE(gesture_provider_->IsScrollInProgress());
203    EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_END));
204    EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
205    EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
206    EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
207    EXPECT_EQ(BoundsForSingleMockTouchAtLocation(scroll_to_x, scroll_to_y),
208              GetMostRecentGestureEvent().details.bounding_box());
209  }
210
211  static void RunTasksAndWait(base::TimeDelta delay) {
212    base::MessageLoop::current()->PostDelayedTask(
213        FROM_HERE, base::MessageLoop::QuitClosure(), delay);
214    base::MessageLoop::current()->Run();
215  }
216
217  std::vector<GestureEventData> gestures_;
218  scoped_ptr<GestureProvider> gesture_provider_;
219  scoped_ptr<GestureEventData> active_scroll_begin_event_;
220  base::MessageLoopForUI message_loop_;
221};
222
223// Verify that a DOWN followed shortly by an UP will trigger a single tap.
224TEST_F(GestureProviderTest, GestureTapTap) {
225  base::TimeTicks event_time = base::TimeTicks::Now();
226  int motion_event_id = 0;
227
228  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false);
229
230  MockMotionEvent event =
231      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
232  event.SetId(++motion_event_id);
233
234  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
235  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
236  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
237  EXPECT_EQ(BoundsForSingleMockTouchAtLocation(kFakeCoordX, kFakeCoordY),
238            GetMostRecentGestureEvent().details.bounding_box());
239
240  event = ObtainMotionEvent(event_time + kOneMicrosecond,
241                            MotionEvent::ACTION_UP);
242  event.SetId(++motion_event_id);
243
244  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
245  EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
246  // Ensure tap details have been set.
247  EXPECT_EQ(1, GetMostRecentGestureEvent().details.tap_count());
248  EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
249  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
250  EXPECT_EQ(BoundsForSingleMockTouchAtLocation(kFakeCoordX, kFakeCoordY),
251            GetMostRecentGestureEvent().details.bounding_box());
252}
253
254// Verify that a DOWN followed shortly by an UP will trigger
255// a ET_GESTURE_TAP_UNCONFIRMED event if double-tap is enabled.
256TEST_F(GestureProviderTest, GestureTapTapWithDelay) {
257  base::TimeTicks event_time = base::TimeTicks::Now();
258  int motion_event_id = 0;
259
260  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true);
261
262  MockMotionEvent event =
263      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
264  event.SetId(++motion_event_id);
265
266  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
267  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
268  EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
269  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
270  EXPECT_EQ(BoundsForSingleMockTouchAtLocation(kFakeCoordX, kFakeCoordY),
271            GetMostRecentGestureEvent().details.bounding_box());
272
273  event = ObtainMotionEvent(event_time + kOneMicrosecond,
274                            MotionEvent::ACTION_UP);
275  event.SetId(++motion_event_id);
276
277  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
278  EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
279  // Ensure tap details have been set.
280  EXPECT_EQ(1, GetMostRecentGestureEvent().details.tap_count());
281  EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
282  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
283  EXPECT_EQ(BoundsForSingleMockTouchAtLocation(kFakeCoordX, kFakeCoordY),
284            GetMostRecentGestureEvent().details.bounding_box());
285
286  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_TAP));
287}
288
289// Verify that a DOWN followed by a MOVE will trigger fling (but not LONG).
290TEST_F(GestureProviderTest, GestureFlingAndCancelLongPress) {
291  base::TimeTicks event_time = TimeTicks::Now();
292  base::TimeDelta delta_time = kDeltaTimeForFlingSequences;
293  int motion_event_id = 0;
294
295  MockMotionEvent event =
296      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
297  event.SetId(++motion_event_id);
298
299  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
300  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
301  EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
302  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
303
304  event = ObtainMotionEvent(event_time + delta_time,
305                            MotionEvent::ACTION_MOVE,
306                            kFakeCoordX * 10,
307                            kFakeCoordY * 10);
308  event.SetId(++motion_event_id);
309  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
310
311  event = ObtainMotionEvent(event_time + delta_time * 2,
312                            MotionEvent::ACTION_UP,
313                            kFakeCoordX * 10,
314                            kFakeCoordY * 10);
315  event.SetId(++motion_event_id);
316
317  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
318  EXPECT_EQ(ET_SCROLL_FLING_START, GetMostRecentGestureEventType());
319  EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
320  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
321  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_PRESS));
322  EXPECT_EQ(
323      BoundsForSingleMockTouchAtLocation(kFakeCoordX * 10, kFakeCoordY * 10),
324      GetMostRecentGestureEvent().details.bounding_box());
325}
326
327// Verify that for a normal scroll the following events are sent:
328// - ET_GESTURE_SCROLL_BEGIN
329// - ET_GESTURE_SCROLL_UPDATE
330// - ET_GESTURE_SCROLL_END
331TEST_F(GestureProviderTest, ScrollEventActionUpSequence) {
332  CheckScrollEventSequenceForEndActionType(MotionEvent::ACTION_UP);
333}
334
335// Verify that for a cancelled scroll the following events are sent:
336// - ET_GESTURE_SCROLL_BEGIN
337// - ET_GESTURE_SCROLL_UPDATE
338// - ET_GESTURE_SCROLL_END
339TEST_F(GestureProviderTest, ScrollEventActionCancelSequence) {
340  CheckScrollEventSequenceForEndActionType(MotionEvent::ACTION_CANCEL);
341}
342
343// Verify that for a normal fling (fling after scroll) the following events are
344// sent:
345// - ET_GESTURE_SCROLL_BEGIN
346// - ET_SCROLL_FLING_START
347TEST_F(GestureProviderTest, FlingEventSequence) {
348  base::TimeTicks event_time = base::TimeTicks::Now();
349  base::TimeDelta delta_time = kDeltaTimeForFlingSequences;
350  int motion_event_id = 0;
351
352  MockMotionEvent event =
353      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
354  event.SetId(++motion_event_id);
355
356  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
357
358  event = ObtainMotionEvent(event_time + delta_time,
359                            MotionEvent::ACTION_MOVE,
360                            kFakeCoordX * 5,
361                            kFakeCoordY * 5);
362  event.SetId(++motion_event_id);
363
364  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
365  EXPECT_TRUE(gesture_provider_->IsScrollInProgress());
366  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
367  EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
368  EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
369  ASSERT_EQ(3U, GetReceivedGestureCount());
370  ASSERT_EQ(ET_GESTURE_SCROLL_BEGIN, GetReceivedGesture(1).type);
371  EXPECT_EQ(motion_event_id, GetReceivedGesture(1).motion_event_id);
372
373  // We don't want to take a dependency here on exactly how hints are calculated
374  // for a fling (eg. may depend on velocity), so just validate the direction.
375  int hint_x = GetReceivedGesture(1).details.scroll_x_hint();
376  int hint_y = GetReceivedGesture(1).details.scroll_y_hint();
377  EXPECT_TRUE(hint_x > 0 && hint_y > 0 && hint_x > hint_y)
378      << "ScrollBegin hint should be in positive X axis";
379
380  event = ObtainMotionEvent(event_time + delta_time * 2,
381                            MotionEvent::ACTION_UP,
382                            kFakeCoordX * 10,
383                            kFakeCoordY * 10);
384  event.SetId(++motion_event_id);
385
386  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
387  EXPECT_FALSE(gesture_provider_->IsScrollInProgress());
388  EXPECT_EQ(ET_SCROLL_FLING_START, GetMostRecentGestureEventType());
389  EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
390  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
391  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SCROLL_END));
392  EXPECT_EQ(event_time + delta_time * 2, GetMostRecentGestureEvent().time)
393      << "FlingStart should have the time of the ACTION_UP";
394}
395
396TEST_F(GestureProviderTest, GestureCancelledWhenWindowFocusLost) {
397  const base::TimeTicks event_time = TimeTicks::Now();
398
399  MockMotionEvent event =
400      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
401  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
402  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
403
404  RunTasksAndWait(GetLongPressTimeout() + GetShowPressTimeout() +
405                  kOneMicrosecond);
406  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SHOW_PRESS));
407  EXPECT_EQ(ET_GESTURE_LONG_PRESS, GetMostRecentGestureEventType());
408
409  // The long press triggers window focus loss by opening a context menu.
410  EXPECT_TRUE(CancelActiveTouchSequence());
411  EXPECT_FALSE(HasDownEvent());
412
413  // A final ACTION_UP should have no effect.
414  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
415                            MotionEvent::ACTION_UP);
416  EXPECT_FALSE(gesture_provider_->OnTouchEvent(event));
417}
418
419TEST_F(GestureProviderTest, NoTapAfterScrollBegins) {
420  base::TimeTicks event_time = base::TimeTicks::Now();
421
422  MockMotionEvent event =
423      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
424
425  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
426
427  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
428  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
429  event = ObtainMotionEvent(event_time + kOneMicrosecond,
430                            MotionEvent::ACTION_MOVE,
431                            kFakeCoordX + 50,
432                            kFakeCoordY + 50);
433  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
434  EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
435
436  event = ObtainMotionEvent(event_time + kOneSecond,
437                            MotionEvent::ACTION_UP,
438                            kFakeCoordX + 50,
439                            kFakeCoordY + 50);
440  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
441  EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
442  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_TAP));
443}
444
445TEST_F(GestureProviderTest, DoubleTap) {
446  base::TimeTicks event_time = base::TimeTicks::Now();
447
448  MockMotionEvent event =
449      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
450  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
451
452  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
453  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
454
455  event = ObtainMotionEvent(event_time + kOneMicrosecond,
456                            MotionEvent::ACTION_UP,
457                            kFakeCoordX,
458                            kFakeCoordY);
459  gesture_provider_->OnTouchEvent(event);
460  EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
461  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
462
463  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
464                            MotionEvent::ACTION_DOWN,
465                            kFakeCoordX,
466                            kFakeCoordY);
467  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
468  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
469  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
470
471  // Moving a very small amount of distance should not trigger the double tap
472  // drag zoom mode.
473  event = ObtainMotionEvent(event_time + kOneMicrosecond * 3,
474                            MotionEvent::ACTION_MOVE,
475                            kFakeCoordX,
476                            kFakeCoordY + 1);
477  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
478  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
479  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
480
481  event = ObtainMotionEvent(event_time + kOneMicrosecond * 3,
482                            MotionEvent::ACTION_UP,
483                            kFakeCoordX,
484                            kFakeCoordY + 1);
485  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
486
487  const GestureEventData& double_tap = GetMostRecentGestureEvent();
488  EXPECT_EQ(ET_GESTURE_DOUBLE_TAP, double_tap.type);
489  // Ensure tap details have been set.
490  EXPECT_EQ(10, double_tap.details.bounding_box().width());
491  EXPECT_EQ(10, double_tap.details.bounding_box().height());
492  EXPECT_EQ(1, double_tap.details.tap_count());
493}
494
495TEST_F(GestureProviderTest, DoubleTapDragZoomBasic) {
496  const base::TimeTicks down_time_1 = TimeTicks::Now();
497  const base::TimeTicks down_time_2 = down_time_1 + kOneMicrosecond * 2;
498
499  MockMotionEvent event =
500      ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
501  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
502
503  event = ObtainMotionEvent(down_time_1 + kOneMicrosecond,
504                            MotionEvent::ACTION_UP,
505                            kFakeCoordX,
506                            kFakeCoordY);
507  gesture_provider_->OnTouchEvent(event);
508  EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
509  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
510
511  event = ObtainMotionEvent(
512      down_time_2, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
513  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
514  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
515  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
516
517  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
518                            MotionEvent::ACTION_MOVE,
519                            kFakeCoordX,
520                            kFakeCoordY + 100);
521  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
522  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
523  ASSERT_EQ(ET_GESTURE_PINCH_BEGIN, GetMostRecentGestureEventType());
524  EXPECT_EQ(BoundsForSingleMockTouchAtLocation(kFakeCoordX, kFakeCoordY + 100),
525            GetMostRecentGestureEvent().details.bounding_box());
526
527  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
528                            MotionEvent::ACTION_MOVE,
529                            kFakeCoordX,
530                            kFakeCoordY + 200);
531  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
532  ASSERT_EQ(ET_GESTURE_PINCH_UPDATE, GetMostRecentGestureEventType());
533  EXPECT_LT(1.f, GetMostRecentGestureEvent().details.scale());
534  EXPECT_EQ(BoundsForSingleMockTouchAtLocation(kFakeCoordX, kFakeCoordY + 200),
535            GetMostRecentGestureEvent().details.bounding_box());
536
537  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
538                            MotionEvent::ACTION_MOVE,
539                            kFakeCoordX,
540                            kFakeCoordY + 100);
541  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
542  ASSERT_EQ(ET_GESTURE_PINCH_UPDATE, GetMostRecentGestureEventType());
543  EXPECT_GT(1.f, GetMostRecentGestureEvent().details.scale());
544  EXPECT_EQ(BoundsForSingleMockTouchAtLocation(kFakeCoordX, kFakeCoordY + 100),
545            GetMostRecentGestureEvent().details.bounding_box());
546
547  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 4,
548                            MotionEvent::ACTION_UP,
549                            kFakeCoordX,
550                            kFakeCoordY - 200);
551  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
552  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_PINCH_END));
553  EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
554  EXPECT_EQ(BoundsForSingleMockTouchAtLocation(kFakeCoordX, kFakeCoordY - 200),
555            GetMostRecentGestureEvent().details.bounding_box());
556}
557
558// Generate a scroll gesture and verify that the resulting scroll motion event
559// has both absolute and relative position information.
560TEST_F(GestureProviderTest, ScrollUpdateValues) {
561  const float delta_x = 16;
562  const float delta_y = 84;
563
564  const base::TimeTicks event_time = TimeTicks::Now();
565
566  MockMotionEvent event =
567      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
568  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
569
570  // Move twice so that we get two ET_GESTURE_SCROLL_UPDATE events and can
571  // compare the relative and absolute coordinates.
572  event = ObtainMotionEvent(event_time + kOneMicrosecond,
573                            MotionEvent::ACTION_MOVE,
574                            kFakeCoordX - delta_x / 2,
575                            kFakeCoordY - delta_y / 2);
576  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
577
578  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
579                            MotionEvent::ACTION_MOVE,
580                            kFakeCoordX - delta_x,
581                            kFakeCoordY - delta_y);
582  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
583
584  // Make sure the reported gesture event has all the expected details.
585  ASSERT_LT(0U, GetReceivedGestureCount());
586  GestureEventData gesture = GetMostRecentGestureEvent();
587  EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, gesture.type);
588  EXPECT_EQ(event_time + kOneMicrosecond * 2, gesture.time);
589  EXPECT_EQ(kFakeCoordX - delta_x, gesture.x);
590  EXPECT_EQ(kFakeCoordY - delta_y, gesture.y);
591  EXPECT_EQ(1, gesture.details.touch_points());
592
593  // No horizontal delta because of snapping.
594  EXPECT_EQ(0, gesture.details.scroll_x());
595  EXPECT_EQ(-delta_y / 2, gesture.details.scroll_y());
596}
597
598// Verify that fractional scroll deltas are rounded as expected and that
599// fractional scrolling doesn't break scroll snapping.
600TEST_F(GestureProviderTest, FractionalScroll) {
601  const float delta_x = 0.4f;
602  const float delta_y = 5.2f;
603
604  const base::TimeTicks event_time = TimeTicks::Now();
605
606  MockMotionEvent event =
607      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
608  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
609
610  // Skip past the touch slop and move back.
611  event = ObtainMotionEvent(event_time,
612                            MotionEvent::ACTION_MOVE,
613                            kFakeCoordX,
614                            kFakeCoordY + 100);
615  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
616  event = ObtainMotionEvent(event_time,
617                            MotionEvent::ACTION_MOVE);
618  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
619
620  // Now move up slowly, mostly vertically but with a (fractional) bit of
621  // horizontal motion.
622  for(int i = 1; i <= 10; i++) {
623    event = ObtainMotionEvent(event_time + kOneMicrosecond * i,
624                              MotionEvent::ACTION_MOVE,
625                              kFakeCoordX + delta_x * i,
626                              kFakeCoordY + delta_y * i);
627    EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
628
629    ASSERT_LT(0U, GetReceivedGestureCount());
630    GestureEventData gesture = GetMostRecentGestureEvent();
631    EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, gesture.type);
632    EXPECT_EQ(event_time + kOneMicrosecond * i, gesture.time);
633    EXPECT_EQ(1, gesture.details.touch_points());
634
635    // Verify that the event co-ordinates are still the precise values we
636    // supplied.
637    EXPECT_EQ(kFakeCoordX + delta_x * i, gesture.x);
638    EXPECT_EQ(kFakeCoordY + delta_y * i, gesture.y);
639
640    // Verify that we're scrolling vertically by the expected amount
641    // (modulo rounding).
642    EXPECT_GE(gesture.details.scroll_y(), (int)delta_y);
643    EXPECT_LE(gesture.details.scroll_y(), ((int)delta_y) + 1);
644
645    // And that there has been no horizontal motion at all.
646    EXPECT_EQ(0, gesture.details.scroll_x());
647  }
648}
649
650// Generate a scroll gesture and verify that the resulting scroll begin event
651// has the expected hint values.
652TEST_F(GestureProviderTest, ScrollBeginValues) {
653  const float delta_x = 13;
654  const float delta_y = 89;
655
656  const base::TimeTicks event_time = TimeTicks::Now();
657
658  MockMotionEvent event =
659      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
660  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
661
662  // Move twice such that the first event isn't sufficient to start
663  // scrolling on it's own.
664  event = ObtainMotionEvent(event_time + kOneMicrosecond,
665                            MotionEvent::ACTION_MOVE,
666                            kFakeCoordX + 2,
667                            kFakeCoordY + 1);
668  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
669  EXPECT_FALSE(gesture_provider_->IsScrollInProgress());
670
671  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
672                            MotionEvent::ACTION_MOVE,
673                            kFakeCoordX + delta_x,
674                            kFakeCoordY + delta_y);
675  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
676  EXPECT_TRUE(gesture_provider_->IsScrollInProgress());
677
678  const GestureEventData* scroll_begin_gesture = GetActiveScrollBeginEvent();
679  ASSERT_TRUE(!!scroll_begin_gesture);
680  EXPECT_EQ(delta_x, scroll_begin_gesture->details.scroll_x_hint());
681  EXPECT_EQ(delta_y, scroll_begin_gesture->details.scroll_y_hint());
682}
683
684TEST_F(GestureProviderTest, LongPressAndTapCancelledWhenScrollBegins) {
685  base::TimeTicks event_time = base::TimeTicks::Now();
686
687  MockMotionEvent event =
688      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
689  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
690  event = ObtainMotionEvent(event_time + kOneMicrosecond,
691                            MotionEvent::ACTION_MOVE,
692                            kFakeCoordX * 5,
693                            kFakeCoordY * 5);
694  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
695  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
696                            MotionEvent::ACTION_MOVE,
697                            kFakeCoordX * 10,
698                            kFakeCoordY * 10);
699  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
700
701  const base::TimeDelta long_press_timeout =
702      GetLongPressTimeout() + GetShowPressTimeout() + kOneMicrosecond;
703  RunTasksAndWait(long_press_timeout);
704
705  // No LONG_TAP as the LONG_PRESS timer is cancelled.
706  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_PRESS));
707  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_TAP));
708}
709
710// Verify that LONG_TAP is triggered after LONG_PRESS followed by an UP.
711TEST_F(GestureProviderTest, GestureLongTap) {
712  base::TimeTicks event_time = base::TimeTicks::Now();
713
714  MockMotionEvent event =
715      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
716  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
717
718  const base::TimeDelta long_press_timeout =
719      GetLongPressTimeout() + GetShowPressTimeout() + kOneMicrosecond;
720  RunTasksAndWait(long_press_timeout);
721
722  EXPECT_EQ(ET_GESTURE_LONG_PRESS, GetMostRecentGestureEventType());
723  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
724  EXPECT_EQ(BoundsForSingleMockTouchAtLocation(kFakeCoordX, kFakeCoordY),
725            GetMostRecentGestureEvent().details.bounding_box());
726
727  event = ObtainMotionEvent(event_time + kOneSecond, MotionEvent::ACTION_UP);
728  gesture_provider_->OnTouchEvent(event);
729  EXPECT_EQ(ET_GESTURE_LONG_TAP, GetMostRecentGestureEventType());
730  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
731  EXPECT_EQ(BoundsForSingleMockTouchAtLocation(kFakeCoordX, kFakeCoordY),
732            GetMostRecentGestureEvent().details.bounding_box());
733}
734
735TEST_F(GestureProviderTest, GestureLongPressDoesNotPreventScrolling) {
736  base::TimeTicks event_time = base::TimeTicks::Now();
737
738  MockMotionEvent event =
739      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
740  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
741
742  const base::TimeDelta long_press_timeout =
743      GetLongPressTimeout() + GetShowPressTimeout() + kOneMicrosecond;
744  RunTasksAndWait(long_press_timeout);
745
746  EXPECT_EQ(ET_GESTURE_LONG_PRESS, GetMostRecentGestureEventType());
747  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
748  event = ObtainMotionEvent(event_time + long_press_timeout,
749                            MotionEvent::ACTION_MOVE,
750                            kFakeCoordX + 100,
751                            kFakeCoordY + 100);
752  gesture_provider_->OnTouchEvent(event);
753
754  EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
755  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
756  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
757
758  event = ObtainMotionEvent(event_time + long_press_timeout,
759                            MotionEvent::ACTION_UP);
760  gesture_provider_->OnTouchEvent(event);
761  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_TAP));
762}
763
764TEST_F(GestureProviderTest, NoGestureLongPressDuringDoubleTap) {
765  base::TimeTicks event_time = base::TimeTicks::Now();
766  int motion_event_id = 0;
767
768  MockMotionEvent event = ObtainMotionEvent(
769      event_time, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
770  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
771
772  event = ObtainMotionEvent(event_time + kOneMicrosecond,
773                            MotionEvent::ACTION_UP,
774                            kFakeCoordX,
775                            kFakeCoordY);
776  gesture_provider_->OnTouchEvent(event);
777  EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
778  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
779
780  event = ObtainMotionEvent(event_time + kOneMicrosecond,
781                            MotionEvent::ACTION_DOWN,
782                            kFakeCoordX,
783                            kFakeCoordY);
784  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
785  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
786  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
787  EXPECT_TRUE(gesture_provider_->IsDoubleTapInProgress());
788
789  const base::TimeDelta long_press_timeout =
790      GetLongPressTimeout() + GetShowPressTimeout() + kOneMicrosecond;
791  RunTasksAndWait(long_press_timeout);
792  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_PRESS));
793
794  event = ObtainMotionEvent(event_time + long_press_timeout,
795                            MotionEvent::ACTION_MOVE,
796                            kFakeCoordX + 20,
797                            kFakeCoordY + 20);
798  event.SetId(++motion_event_id);
799
800  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
801  EXPECT_EQ(ET_GESTURE_PINCH_BEGIN, GetMostRecentGestureEventType());
802  EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
803  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
804  EXPECT_TRUE(gesture_provider_->IsDoubleTapInProgress());
805
806  event = ObtainMotionEvent(event_time + long_press_timeout + kOneMicrosecond,
807                            MotionEvent::ACTION_UP,
808                            kFakeCoordX,
809                            kFakeCoordY + 1);
810  event.SetId(++motion_event_id);
811  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
812  EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
813  EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
814  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
815  EXPECT_FALSE(gesture_provider_->IsDoubleTapInProgress());
816}
817
818// Verify that the touch slop region is removed from the first scroll delta to
819// avoid a jump when starting to scroll.
820TEST_F(GestureProviderTest, TouchSlopRemovedFromScroll) {
821  const float touch_slop = GetTouchSlop();
822  const float scroll_delta = 5;
823
824  base::TimeTicks event_time = base::TimeTicks::Now();
825
826  MockMotionEvent event =
827      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
828  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
829
830  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
831                            MotionEvent::ACTION_MOVE,
832                            kFakeCoordX,
833                            kFakeCoordY + touch_slop + scroll_delta);
834  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
835
836  EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
837  GestureEventData gesture = GetMostRecentGestureEvent();
838  EXPECT_EQ(0, gesture.details.scroll_x());
839  EXPECT_EQ(scroll_delta, gesture.details.scroll_y());
840  EXPECT_EQ(1, gesture.details.touch_points());
841}
842
843// Verify that movement within the touch slop region does not generate a scroll,
844// and that the slop region is correct even when using fractional coordinates.
845TEST_F(GestureProviderTest, NoScrollWithinTouchSlop) {
846  const float touch_slop = GetTouchSlop();
847  const float scale_factor = 2.5f;
848  const int touch_slop_pixels = static_cast<int>(scale_factor * touch_slop);
849
850  base::TimeTicks event_time = base::TimeTicks::Now();
851
852  MockMotionEvent event =
853      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
854  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
855
856  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
857                            MotionEvent::ACTION_MOVE,
858                            kFakeCoordX + touch_slop_pixels / scale_factor,
859                            kFakeCoordY);
860  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
861  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
862
863  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
864                            MotionEvent::ACTION_MOVE,
865                            kFakeCoordX,
866                            kFakeCoordY + touch_slop_pixels / scale_factor);
867  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
868  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
869
870  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
871                            MotionEvent::ACTION_MOVE,
872                            kFakeCoordX - touch_slop_pixels / scale_factor,
873                            kFakeCoordY);
874  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
875  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
876
877  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
878                            MotionEvent::ACTION_MOVE,
879                            kFakeCoordX,
880                            kFakeCoordY - touch_slop_pixels / scale_factor);
881  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
882  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
883
884  event =
885      ObtainMotionEvent(event_time + kOneMicrosecond * 2,
886                        MotionEvent::ACTION_MOVE,
887                        kFakeCoordX,
888                        kFakeCoordY + (touch_slop_pixels + 1.f) / scale_factor);
889  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
890  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
891}
892
893TEST_F(GestureProviderTest, NoDoubleTapWhenExplicitlyDisabled) {
894  // Ensure that double-tap gestures can be disabled.
895  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false);
896
897  base::TimeTicks event_time = base::TimeTicks::Now();
898  MockMotionEvent event = ObtainMotionEvent(
899      event_time, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
900  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
901  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
902
903  event = ObtainMotionEvent(event_time + kOneMicrosecond,
904                            MotionEvent::ACTION_UP,
905                            kFakeCoordX,
906                            kFakeCoordY);
907  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
908  EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
909
910  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
911                            MotionEvent::ACTION_DOWN,
912                            kFakeCoordX,
913                            kFakeCoordY);
914  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
915  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
916
917  event = ObtainMotionEvent(event_time + kOneMicrosecond * 3,
918                            MotionEvent::ACTION_UP,
919                            kFakeCoordX,
920                            kFakeCoordY);
921  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
922  EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
923
924  // Ensure that double-tap gestures can be interrupted.
925  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true);
926
927  event_time = base::TimeTicks::Now();
928  event = ObtainMotionEvent(
929      event_time, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
930  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
931  EXPECT_EQ(5U, GetReceivedGestureCount());
932
933  event = ObtainMotionEvent(event_time + kOneMicrosecond,
934                            MotionEvent::ACTION_UP,
935                            kFakeCoordX,
936                            kFakeCoordY);
937  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
938  EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
939
940  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false);
941  EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
942
943  // Ensure that double-tap gestures can be resumed.
944  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true);
945
946  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
947                            MotionEvent::ACTION_DOWN,
948                            kFakeCoordX,
949                            kFakeCoordY);
950  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
951  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
952
953  event = ObtainMotionEvent(event_time + kOneMicrosecond * 3,
954                            MotionEvent::ACTION_UP,
955                            kFakeCoordX,
956                            kFakeCoordY);
957  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
958  EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
959
960  event = ObtainMotionEvent(event_time + kOneMicrosecond * 4,
961                            MotionEvent::ACTION_DOWN,
962                            kFakeCoordX,
963                            kFakeCoordY);
964  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
965  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
966
967  event = ObtainMotionEvent(event_time + kOneMicrosecond * 5,
968                            MotionEvent::ACTION_UP,
969                            kFakeCoordX,
970                            kFakeCoordY);
971  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
972  EXPECT_EQ(ET_GESTURE_DOUBLE_TAP, GetMostRecentGestureEventType());
973}
974
975TEST_F(GestureProviderTest, NoDelayedTapWhenDoubleTapSupportToggled) {
976  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true);
977
978  base::TimeTicks event_time = base::TimeTicks::Now();
979  MockMotionEvent event = ObtainMotionEvent(
980      event_time, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
981  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
982  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
983  EXPECT_EQ(1U, GetReceivedGestureCount());
984
985  event = ObtainMotionEvent(event_time + kOneMicrosecond,
986                            MotionEvent::ACTION_UP,
987                            kFakeCoordX,
988                            kFakeCoordY);
989  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
990  EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
991  EXPECT_EQ(2U, GetReceivedGestureCount());
992
993  // Disabling double-tap during the tap timeout should flush the delayed tap.
994  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false);
995  EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
996  EXPECT_EQ(3U, GetReceivedGestureCount());
997
998  // No further timeout gestures should arrive.
999  const base::TimeDelta long_press_timeout =
1000      GetLongPressTimeout() + GetShowPressTimeout() + kOneMicrosecond;
1001  RunTasksAndWait(long_press_timeout);
1002  EXPECT_EQ(3U, GetReceivedGestureCount());
1003}
1004
1005TEST_F(GestureProviderTest, NoDoubleTapDragZoomWhenDisabledOnPlatform) {
1006  const base::TimeTicks down_time_1 = TimeTicks::Now();
1007  const base::TimeTicks down_time_2 = down_time_1 + kOneMicrosecond * 2;
1008
1009  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false);
1010
1011  MockMotionEvent event =
1012      ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
1013  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1014
1015  event = ObtainMotionEvent(down_time_1 + kOneMicrosecond,
1016                            MotionEvent::ACTION_UP,
1017                            kFakeCoordX,
1018                            kFakeCoordY);
1019  gesture_provider_->OnTouchEvent(event);
1020
1021  event = ObtainMotionEvent(
1022      down_time_2, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
1023  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1024
1025  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
1026                            MotionEvent::ACTION_MOVE,
1027                            kFakeCoordX,
1028                            kFakeCoordY + 100);
1029
1030  // The move should become a scroll, as doubletap drag zoom is disabled.
1031  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1032  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
1033  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_BEGIN));
1034
1035  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
1036                            MotionEvent::ACTION_MOVE,
1037                            kFakeCoordX,
1038                            kFakeCoordY + 200);
1039  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1040  EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
1041  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1042  EXPECT_EQ(down_time_2 + kOneMicrosecond * 2,
1043            GetMostRecentGestureEvent().time);
1044  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_UPDATE));
1045
1046  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
1047                            MotionEvent::ACTION_UP,
1048                            kFakeCoordX,
1049                            kFakeCoordY + 200);
1050  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1051  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_END));
1052}
1053
1054// Verify that double tap drag zoom feature is not invoked when the gesture
1055// handler is told to disable double tap gesture detection.
1056// The second tap sequence should be treated just as the first would be.
1057TEST_F(GestureProviderTest, NoDoubleTapDragZoomWhenDisabledOnPage) {
1058  const base::TimeTicks down_time_1 = TimeTicks::Now();
1059  const base::TimeTicks down_time_2 = down_time_1 + kOneMicrosecond * 2;
1060
1061  gesture_provider_->SetDoubleTapSupportForPageEnabled(false);
1062
1063  MockMotionEvent event =
1064      ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
1065  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1066
1067  event = ObtainMotionEvent(down_time_1 + kOneMicrosecond,
1068                            MotionEvent::ACTION_UP,
1069                            kFakeCoordX,
1070                            kFakeCoordY);
1071  gesture_provider_->OnTouchEvent(event);
1072
1073  event = ObtainMotionEvent(
1074      down_time_2, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
1075  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1076
1077  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
1078                            MotionEvent::ACTION_MOVE,
1079                            kFakeCoordX,
1080                            kFakeCoordY + 100);
1081
1082  // The move should become a scroll, as double tap drag zoom is disabled.
1083  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1084  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
1085  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_BEGIN));
1086
1087  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
1088                            MotionEvent::ACTION_MOVE,
1089                            kFakeCoordX,
1090                            kFakeCoordY + 200);
1091  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1092  EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
1093  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1094  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_UPDATE));
1095
1096  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
1097                            MotionEvent::ACTION_UP,
1098                            kFakeCoordX,
1099                            kFakeCoordY + 200);
1100  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1101  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_END));
1102}
1103
1104// Verify that updating double tap support during a double tap drag zoom
1105// disables double tap detection after the gesture has ended.
1106TEST_F(GestureProviderTest, FixedPageScaleDuringDoubleTapDragZoom) {
1107  base::TimeTicks down_time_1 = TimeTicks::Now();
1108  base::TimeTicks down_time_2 = down_time_1 + kOneMicrosecond * 2;
1109
1110  gesture_provider_->SetDoubleTapSupportForPageEnabled(true);
1111  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true);
1112
1113  // Start a double-tap drag gesture.
1114  MockMotionEvent event =
1115      ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
1116  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1117  event = ObtainMotionEvent(down_time_1 + kOneMicrosecond,
1118                            MotionEvent::ACTION_UP,
1119                            kFakeCoordX,
1120                            kFakeCoordY);
1121  gesture_provider_->OnTouchEvent(event);
1122  event = ObtainMotionEvent(
1123      down_time_2, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
1124  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1125  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
1126                            MotionEvent::ACTION_MOVE,
1127                            kFakeCoordX,
1128                            kFakeCoordY + 100);
1129  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1130  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
1131  EXPECT_EQ(ET_GESTURE_PINCH_BEGIN, GetMostRecentGestureEventType());
1132  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1133
1134  // Simulate setting a fixed page scale (or a mobile viewport);
1135  // this should not disrupt the current double-tap gesture.
1136  gesture_provider_->SetDoubleTapSupportForPageEnabled(false);
1137
1138  // Double tap zoom updates should continue.
1139  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
1140                            MotionEvent::ACTION_MOVE,
1141                            kFakeCoordX,
1142                            kFakeCoordY + 200);
1143  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1144  EXPECT_EQ(ET_GESTURE_PINCH_UPDATE, GetMostRecentGestureEventType());
1145  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1146  EXPECT_LT(1.f, GetMostRecentGestureEvent().details.scale());
1147  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
1148                            MotionEvent::ACTION_UP,
1149                            kFakeCoordX,
1150                            kFakeCoordY + 200);
1151  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1152  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_PINCH_END));
1153  EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
1154  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1155
1156  // The double-tap gesture has finished, but the page scale is fixed.
1157  // The same event sequence should not generate any double tap getsures.
1158  gestures_.clear();
1159  down_time_1 += kOneMicrosecond * 40;
1160  down_time_2 += kOneMicrosecond * 40;
1161
1162  // Start a double-tap drag gesture.
1163  event = ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
1164  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1165  event = ObtainMotionEvent(down_time_1 + kOneMicrosecond,
1166                            MotionEvent::ACTION_UP,
1167                            kFakeCoordX,
1168                            kFakeCoordY);
1169  gesture_provider_->OnTouchEvent(event);
1170  event = ObtainMotionEvent(
1171      down_time_2, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
1172  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1173  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
1174                            MotionEvent::ACTION_MOVE,
1175                            kFakeCoordX,
1176                            kFakeCoordY + 100);
1177  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1178  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
1179  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_BEGIN));
1180
1181  // Double tap zoom updates should not be sent.
1182  // Instead, the second tap drag becomes a scroll gesture sequence.
1183  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
1184                            MotionEvent::ACTION_MOVE,
1185                            kFakeCoordX,
1186                            kFakeCoordY + 200);
1187  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1188  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_UPDATE));
1189  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_UPDATE));
1190  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
1191                            MotionEvent::ACTION_UP,
1192                            kFakeCoordX,
1193                            kFakeCoordY + 200);
1194  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1195  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_END));
1196}
1197
1198// Verify that pinch zoom sends the proper event sequence.
1199TEST_F(GestureProviderTest, PinchZoom) {
1200  base::TimeTicks event_time = base::TimeTicks::Now();
1201  const float touch_slop = GetTouchSlop();
1202  int motion_event_id = 0;
1203
1204  gesture_provider_->SetDoubleTapSupportForPageEnabled(false);
1205  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true);
1206  gesture_provider_->SetMultiTouchZoomSupportEnabled(true);
1207
1208  int secondary_coord_x = kFakeCoordX + 20 * touch_slop;
1209  int secondary_coord_y = kFakeCoordY + 20 * touch_slop;
1210
1211  MockMotionEvent event =
1212      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
1213  event.SetId(++motion_event_id);
1214  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1215  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1216  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1217  EXPECT_EQ(BoundsForSingleMockTouchAtLocation(kFakeCoordX, kFakeCoordY),
1218            GetMostRecentGestureEvent().details.bounding_box());
1219
1220  // Toggling double-tap support should not take effect until the next sequence.
1221  gesture_provider_->SetDoubleTapSupportForPageEnabled(true);
1222
1223  event = ObtainMotionEvent(event_time,
1224                            MotionEvent::ACTION_POINTER_DOWN,
1225                            kFakeCoordX,
1226                            kFakeCoordY,
1227                            secondary_coord_x,
1228                            secondary_coord_y);
1229  event.SetId(++motion_event_id);
1230
1231  gesture_provider_->OnTouchEvent(event);
1232  EXPECT_EQ(1U, GetReceivedGestureCount());
1233  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1234  EXPECT_EQ(BoundsForSingleMockTouchAtLocation(kFakeCoordX, kFakeCoordY),
1235            GetMostRecentGestureEvent().details.bounding_box());
1236
1237  secondary_coord_x += 5 * touch_slop;
1238  secondary_coord_y += 5 * touch_slop;
1239  event = ObtainMotionEvent(event_time,
1240                            MotionEvent::ACTION_MOVE,
1241                            kFakeCoordX,
1242                            kFakeCoordY,
1243                            secondary_coord_x,
1244                            secondary_coord_y);
1245  event.SetId(++motion_event_id);
1246
1247  // Toggling double-tap support should not take effect until the next sequence.
1248  gesture_provider_->SetDoubleTapSupportForPageEnabled(false);
1249
1250  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1251  EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
1252  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
1253  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_PINCH_BEGIN));
1254  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
1255  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_UPDATE));
1256  EXPECT_EQ(
1257      gfx::RectF(kFakeCoordX - kMockTouchRadius,
1258                 kFakeCoordY - kMockTouchRadius,
1259                 secondary_coord_x - kFakeCoordX + kMockTouchRadius * 2,
1260                 secondary_coord_y - kFakeCoordY + kMockTouchRadius * 2),
1261      GetMostRecentGestureEvent().details.bounding_box());
1262
1263  secondary_coord_x += 2 * touch_slop;
1264  secondary_coord_y += 2 * touch_slop;
1265  event = ObtainMotionEvent(event_time,
1266                            MotionEvent::ACTION_MOVE,
1267                            kFakeCoordX,
1268                            kFakeCoordY,
1269                            secondary_coord_x,
1270                            secondary_coord_y);
1271  event.SetId(++motion_event_id);
1272
1273  // Toggling double-tap support should not take effect until the next sequence.
1274  gesture_provider_->SetDoubleTapSupportForPageEnabled(true);
1275
1276  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1277  EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
1278  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_UPDATE));
1279  EXPECT_EQ(ET_GESTURE_PINCH_UPDATE, GetMostRecentGestureEventType());
1280  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
1281  EXPECT_LT(1.f, GetMostRecentGestureEvent().details.scale());
1282  EXPECT_EQ(
1283      gfx::RectF(kFakeCoordX - kMockTouchRadius,
1284                 kFakeCoordY - kMockTouchRadius,
1285                 secondary_coord_x - kFakeCoordX + kMockTouchRadius * 2,
1286                 secondary_coord_y - kFakeCoordY + kMockTouchRadius * 2),
1287      GetMostRecentGestureEvent().details.bounding_box());
1288
1289  event = ObtainMotionEvent(event_time,
1290                            MotionEvent::ACTION_POINTER_UP,
1291                            kFakeCoordX,
1292                            kFakeCoordY,
1293                            secondary_coord_x,
1294                            secondary_coord_y);
1295  event.SetId(++motion_event_id);
1296
1297  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1298  EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
1299  EXPECT_EQ(ET_GESTURE_PINCH_END, GetMostRecentGestureEventType());
1300  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
1301  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SCROLL_END));
1302  EXPECT_EQ(
1303      gfx::RectF(kFakeCoordX - kMockTouchRadius,
1304                 kFakeCoordY - kMockTouchRadius,
1305                 secondary_coord_x - kFakeCoordX + kMockTouchRadius * 2,
1306                 secondary_coord_y - kFakeCoordY + kMockTouchRadius * 2),
1307      GetMostRecentGestureEvent().details.bounding_box());
1308
1309  event = ObtainMotionEvent(event_time, MotionEvent::ACTION_UP);
1310  gesture_provider_->OnTouchEvent(event);
1311  EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
1312  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1313  EXPECT_EQ(gfx::RectF(kFakeCoordX - kMockTouchRadius,
1314                       kFakeCoordY - kMockTouchRadius,
1315                       kMockTouchRadius * 2,
1316                       kMockTouchRadius * 2),
1317            GetMostRecentGestureEvent().details.bounding_box());
1318}
1319
1320// Verify that the timer of LONG_PRESS will be cancelled when scrolling begins
1321// so LONG_PRESS and LONG_TAP won't be triggered.
1322TEST_F(GestureProviderTest, GesturesCancelledAfterLongPressCausesLostFocus) {
1323  base::TimeTicks event_time = base::TimeTicks::Now();
1324
1325  MockMotionEvent event =
1326      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
1327  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1328
1329  const base::TimeDelta long_press_timeout =
1330      GetLongPressTimeout() + GetShowPressTimeout() + kOneMicrosecond;
1331  RunTasksAndWait(long_press_timeout);
1332  EXPECT_EQ(ET_GESTURE_LONG_PRESS, GetMostRecentGestureEventType());
1333  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1334
1335  EXPECT_TRUE(CancelActiveTouchSequence());
1336  EXPECT_FALSE(HasDownEvent());
1337
1338  event = ObtainMotionEvent(event_time + long_press_timeout,
1339                            MotionEvent::ACTION_UP);
1340  gesture_provider_->OnTouchEvent(event);
1341  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_TAP));
1342}
1343
1344// Verify that inserting a touch cancel event will trigger proper touch and
1345// gesture sequence cancellation.
1346TEST_F(GestureProviderTest, CancelActiveTouchSequence) {
1347  base::TimeTicks event_time = base::TimeTicks::Now();
1348  int motion_event_id = 0;
1349
1350  EXPECT_FALSE(CancelActiveTouchSequence());
1351  EXPECT_EQ(0U, GetReceivedGestureCount());
1352
1353  MockMotionEvent event =
1354      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
1355  event.SetId(++motion_event_id);
1356  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1357  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1358  EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
1359  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1360
1361  ASSERT_TRUE(CancelActiveTouchSequence());
1362  EXPECT_FALSE(HasDownEvent());
1363
1364  // Subsequent MotionEvent's are dropped until ACTION_DOWN.
1365  event = ObtainMotionEvent(event_time + kOneMicrosecond,
1366                            MotionEvent::ACTION_MOVE);
1367  EXPECT_FALSE(gesture_provider_->OnTouchEvent(event));
1368
1369  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
1370                            MotionEvent::ACTION_UP);
1371  EXPECT_FALSE(gesture_provider_->OnTouchEvent(event));
1372
1373  event = ObtainMotionEvent(event_time + kOneMicrosecond * 3,
1374                            MotionEvent::ACTION_DOWN);
1375  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1376  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1377  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1378}
1379
1380TEST_F(GestureProviderTest, DoubleTapDragZoomCancelledOnSecondaryPointerDown) {
1381  const base::TimeTicks down_time_1 = TimeTicks::Now();
1382  const base::TimeTicks down_time_2 = down_time_1 + kOneMicrosecond * 2;
1383
1384  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true);
1385
1386  MockMotionEvent event =
1387      ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
1388  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1389  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1390  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1391
1392  event =
1393      ObtainMotionEvent(down_time_1 + kOneMicrosecond, MotionEvent::ACTION_UP);
1394  gesture_provider_->OnTouchEvent(event);
1395  EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
1396  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1397
1398  event = ObtainMotionEvent(down_time_2, MotionEvent::ACTION_DOWN);
1399  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1400  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1401  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1402
1403  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
1404                            MotionEvent::ACTION_MOVE,
1405                            kFakeCoordX,
1406                            kFakeCoordY - 30);
1407  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1408  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
1409  EXPECT_EQ(ET_GESTURE_PINCH_BEGIN, GetMostRecentGestureEventType());
1410  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1411
1412  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
1413                            MotionEvent::ACTION_POINTER_DOWN,
1414                            kFakeCoordX,
1415                            kFakeCoordY - 30,
1416                            kFakeCoordX + 50,
1417                            kFakeCoordY + 50);
1418  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1419  EXPECT_EQ(ET_GESTURE_PINCH_END, GetMostRecentGestureEventType());
1420  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
1421
1422  const size_t gesture_count = GetReceivedGestureCount();
1423  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
1424                            MotionEvent::ACTION_POINTER_UP,
1425                            kFakeCoordX,
1426                            kFakeCoordY - 30,
1427                            kFakeCoordX + 50,
1428                            kFakeCoordY + 50);
1429  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1430  EXPECT_EQ(gesture_count, GetReceivedGestureCount());
1431
1432  event = ObtainMotionEvent(down_time_2 + kOneSecond,
1433                            MotionEvent::ACTION_UP);
1434  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1435  EXPECT_EQ(gesture_count + 1, GetReceivedGestureCount());
1436  EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
1437  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1438}
1439
1440// Verify that gesture begin and gesture end events are dispatched correctly.
1441TEST_F(GestureProviderTest, GestureBeginAndEnd) {
1442  SetBeginEndTypesEnabled(true);
1443  base::TimeTicks event_time = base::TimeTicks::Now();
1444
1445  EXPECT_EQ(0U, GetReceivedGestureCount());
1446  MockMotionEvent event =
1447      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
1448  event.pointer_count = 1;
1449  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1450  EXPECT_EQ(ET_GESTURE_BEGIN, GetReceivedGesture(0).type);
1451  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1452  EXPECT_EQ(2U, GetReceivedGestureCount());
1453  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1454  EXPECT_EQ(gfx::RectF(kFakeCoordX - kMockTouchRadius,
1455                       kFakeCoordY - kMockTouchRadius,
1456                       kMockTouchRadius * 2,
1457                       kMockTouchRadius * 2),
1458            GetMostRecentGestureEvent().details.bounding_box());
1459
1460  event = ObtainMotionEvent(event_time, MotionEvent::ACTION_POINTER_DOWN);
1461  event.pointer_count = 2;
1462  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1463  EXPECT_EQ(ET_GESTURE_BEGIN, GetMostRecentGestureEventType());
1464  EXPECT_EQ(3U, GetReceivedGestureCount());
1465  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
1466
1467  event = ObtainMotionEvent(event_time, MotionEvent::ACTION_POINTER_DOWN);
1468  event.pointer_count = 3;
1469  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1470  EXPECT_EQ(ET_GESTURE_BEGIN, GetMostRecentGestureEventType());
1471  EXPECT_EQ(4U, GetReceivedGestureCount());
1472  EXPECT_EQ(3, GetMostRecentGestureEvent().details.touch_points());
1473
1474  event = ObtainMotionEvent(event_time, MotionEvent::ACTION_POINTER_UP);
1475  event.pointer_count = 2;
1476  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1477  EXPECT_EQ(ET_GESTURE_END, GetMostRecentGestureEventType());
1478  EXPECT_EQ(5U, GetReceivedGestureCount());
1479  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
1480
1481  event = ObtainMotionEvent(event_time, MotionEvent::ACTION_POINTER_DOWN);
1482  event.pointer_count = 3;
1483  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1484  EXPECT_EQ(ET_GESTURE_BEGIN, GetMostRecentGestureEventType());
1485  EXPECT_EQ(6U, GetReceivedGestureCount());
1486  EXPECT_EQ(3, GetMostRecentGestureEvent().details.touch_points());
1487
1488  event = ObtainMotionEvent(event_time, MotionEvent::ACTION_POINTER_UP);
1489  event.pointer_count = 2;
1490  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1491  EXPECT_EQ(ET_GESTURE_END, GetMostRecentGestureEventType());
1492  EXPECT_EQ(7U, GetReceivedGestureCount());
1493  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
1494
1495  event = ObtainMotionEvent(event_time, MotionEvent::ACTION_POINTER_UP);
1496  event.pointer_count = 1;
1497  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1498  EXPECT_EQ(ET_GESTURE_END, GetMostRecentGestureEventType());
1499  EXPECT_EQ(8U, GetReceivedGestureCount());
1500  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1501
1502  event = ObtainMotionEvent(event_time, MotionEvent::ACTION_UP);
1503  event.pointer_count = 1;
1504  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1505  EXPECT_EQ(ET_GESTURE_END, GetMostRecentGestureEventType());
1506  EXPECT_EQ(9U, GetReceivedGestureCount());
1507  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1508
1509  event = ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
1510  event.pointer_count = 1;
1511  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1512  EXPECT_EQ(ET_GESTURE_BEGIN, GetReceivedGesture(9).type);
1513  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1514  EXPECT_EQ(11U, GetReceivedGestureCount());
1515  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1516
1517  event = ObtainMotionEvent(event_time, MotionEvent::ACTION_CANCEL);
1518  event.pointer_count = 1;
1519  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1520  EXPECT_EQ(ET_GESTURE_END, GetMostRecentGestureEventType());
1521  EXPECT_EQ(12U, GetReceivedGestureCount());
1522  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1523}
1524
1525}  // namespace ui
1526