gesture_provider_unittest.cc revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
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;
30const float kMaxTwoFingerTapSeparation = 300;
31
32GestureProvider::Config CreateDefaultConfig() {
33  GestureProvider::Config sConfig;
34  // The longpress timeout is non-zero only to indicate ordering with respect to
35  // the showpress timeout.
36  sConfig.gesture_detector_config.showpress_timeout = base::TimeDelta();
37  sConfig.gesture_detector_config.longpress_timeout = kOneMicrosecond;
38
39  // A valid doubletap timeout should always be non-zero. The value is used not
40  // only to trigger the timeout that confirms the tap event, but also to gate
41  // whether the second tap is in fact a double-tap (using a strict inequality
42  // between times for the first up and the second down events). We use 4
43  // microseconds simply to allow several intermediate events to occur before
44  // the second tap at microsecond intervals.
45  sConfig.gesture_detector_config.double_tap_timeout = kOneMicrosecond * 4;
46  sConfig.gesture_detector_config.double_tap_min_time = kOneMicrosecond * 2;
47
48  sConfig.scale_gesture_detector_config.gesture_detector_config =
49      sConfig.gesture_detector_config;
50  return sConfig;
51}
52
53gfx::RectF BoundsForSingleMockTouchAtLocation(float x, float y) {
54  float diameter = MockMotionEvent::TOUCH_MAJOR;
55  return gfx::RectF(x - diameter / 2, y - diameter / 2, diameter, diameter);
56}
57
58}  // namespace
59
60class GestureProviderTest : public testing::Test, public GestureProviderClient {
61 public:
62  GestureProviderTest() {}
63  virtual ~GestureProviderTest() {}
64
65  static MockMotionEvent ObtainMotionEvent(base::TimeTicks event_time,
66                                           MotionEvent::Action action,
67                                           float x,
68                                           float y) {
69    return MockMotionEvent(action, event_time, x, y);
70  }
71
72  static MockMotionEvent ObtainMotionEvent(base::TimeTicks event_time,
73                                           MotionEvent::Action action,
74                                           float x0,
75                                           float y0,
76                                           float x1,
77                                           float y1) {
78    return MockMotionEvent(action, event_time, x0, y0, x1, y1);
79  }
80
81  static MockMotionEvent ObtainMotionEvent(base::TimeTicks event_time,
82                                           MotionEvent::Action action,
83                                           float x0,
84                                           float y0,
85                                           float x1,
86                                           float y1,
87                                           float x2,
88                                           float y2) {
89    return MockMotionEvent(action, event_time, x0, y0, x1, y1, x2, y2);
90  }
91
92  static MockMotionEvent ObtainMotionEvent(
93      base::TimeTicks event_time,
94      MotionEvent::Action action,
95      const std::vector<gfx::PointF>& positions) {
96    switch (positions.size()) {
97      case 1:
98        return MockMotionEvent(
99            action, event_time, positions[0].x(), positions[0].y());
100      case 2:
101        return MockMotionEvent(action,
102                               event_time,
103                               positions[0].x(),
104                               positions[0].y(),
105                               positions[1].x(),
106                               positions[1].y());
107      case 3:
108        return MockMotionEvent(action,
109                               event_time,
110                               positions[0].x(),
111                               positions[0].y(),
112                               positions[1].x(),
113                               positions[1].y(),
114                               positions[2].x(),
115                               positions[2].y());
116      default:
117        CHECK(false) << "MockMotionEvent only supports 1-3 pointers";
118        return MockMotionEvent();
119    }
120  }
121
122  static MockMotionEvent ObtainMotionEvent(base::TimeTicks event_time,
123                                           MotionEvent::Action action) {
124    return ObtainMotionEvent(event_time, action, kFakeCoordX, kFakeCoordY);
125  }
126
127  // Test
128  virtual void SetUp() OVERRIDE { SetUpWithConfig(GetDefaultConfig()); }
129
130  virtual void TearDown() OVERRIDE {
131    gestures_.clear();
132    gesture_provider_.reset();
133  }
134
135  // GestureProviderClient
136  virtual void OnGestureEvent(const GestureEventData& gesture) OVERRIDE {
137    if (gesture.type() == ET_GESTURE_SCROLL_BEGIN)
138      active_scroll_begin_event_.reset(new GestureEventData(gesture));
139    gestures_.push_back(gesture);
140  }
141
142  void SetUpWithConfig(const GestureProvider::Config& config) {
143    gesture_provider_.reset(new GestureProvider(config, this));
144    gesture_provider_->SetMultiTouchZoomSupportEnabled(false);
145  }
146
147  void ResetGestureDetection() {
148    CancelActiveTouchSequence();
149    gestures_.clear();
150  }
151  bool CancelActiveTouchSequence() {
152    if (!gesture_provider_->current_down_event())
153      return false;
154    return gesture_provider_->OnTouchEvent(
155        *gesture_provider_->current_down_event()->Cancel());
156  }
157
158  bool HasReceivedGesture(EventType type) const {
159    for (size_t i = 0; i < gestures_.size(); ++i) {
160      if (gestures_[i].type() == type)
161        return true;
162    }
163    return false;
164  }
165
166  const GestureEventData& GetMostRecentGestureEvent() const {
167    EXPECT_FALSE(gestures_.empty());
168    return gestures_.back();
169  }
170
171  EventType GetMostRecentGestureEventType() const {
172    EXPECT_FALSE(gestures_.empty());
173    return gestures_.back().type();
174  }
175
176  size_t GetReceivedGestureCount() const { return gestures_.size(); }
177
178  const GestureEventData& GetReceivedGesture(size_t index) const {
179    EXPECT_LT(index, GetReceivedGestureCount());
180    return gestures_[index];
181  }
182
183  const GestureEventData* GetActiveScrollBeginEvent() const {
184    return active_scroll_begin_event_ ? active_scroll_begin_event_.get() : NULL;
185  }
186
187  const GestureProvider::Config& GetDefaultConfig() const {
188    static GestureProvider::Config sConfig = CreateDefaultConfig();
189    return sConfig;
190  }
191
192  float GetTouchSlop() const {
193    return GetDefaultConfig().gesture_detector_config.touch_slop;
194  }
195
196  float GetMinScalingSpan() const {
197    return GetDefaultConfig().scale_gesture_detector_config.min_scaling_span;
198  }
199
200  float GetMinSwipeVelocity() const {
201    return GetDefaultConfig().gesture_detector_config.minimum_swipe_velocity;
202  }
203
204  base::TimeDelta GetLongPressTimeout() const {
205    return GetDefaultConfig().gesture_detector_config.longpress_timeout;
206  }
207
208  base::TimeDelta GetShowPressTimeout() const {
209    return GetDefaultConfig().gesture_detector_config.showpress_timeout;
210  }
211
212  base::TimeDelta GetDoubleTapTimeout() const {
213    return GetDefaultConfig().gesture_detector_config.double_tap_timeout;
214  }
215
216  base::TimeDelta GetDoubleTapMinTime() const {
217    return GetDefaultConfig().gesture_detector_config.double_tap_min_time;
218  }
219
220  base::TimeDelta GetValidDoubleTapDelay() const {
221    return (GetDoubleTapTimeout() + GetDoubleTapMinTime()) / 2;
222  }
223
224  void EnableBeginEndTypes() {
225    GestureProvider::Config config = GetDefaultConfig();
226    config.gesture_begin_end_types_enabled = true;
227    SetUpWithConfig(config);
228  }
229
230  void EnableSwipe() {
231    GestureProvider::Config config = GetDefaultConfig();
232    config.gesture_detector_config.swipe_enabled = true;
233    SetUpWithConfig(config);
234  }
235
236  void EnableTwoFingerTap(float max_distance_for_two_finger_tap,
237                          base::TimeDelta two_finger_tap_timeout) {
238    GestureProvider::Config config = GetDefaultConfig();
239    config.gesture_detector_config.two_finger_tap_enabled = true;
240    config.gesture_detector_config.two_finger_tap_max_separation =
241        max_distance_for_two_finger_tap;
242    config.gesture_detector_config.two_finger_tap_timeout =
243        two_finger_tap_timeout;
244    SetUpWithConfig(config);
245  }
246
247  void SetMinPinchUpdateSpanDelta(float min_pinch_update_span_delta) {
248    GestureProvider::Config config = GetDefaultConfig();
249    config.scale_gesture_detector_config.min_pinch_update_span_delta =
250        min_pinch_update_span_delta;
251    SetUpWithConfig(config);
252  }
253
254  void SetMinGestureBoundsLength(float min_gesture_bound_length) {
255    GestureProvider::Config config = GetDefaultConfig();
256    config.min_gesture_bounds_length = min_gesture_bound_length;
257    SetUpWithConfig(config);
258  }
259
260  bool HasDownEvent() const { return gesture_provider_->current_down_event(); }
261
262 protected:
263  void CheckScrollEventSequenceForEndActionType(
264      MotionEvent::Action end_action_type) {
265    base::TimeTicks event_time = base::TimeTicks::Now();
266    const float scroll_to_x = kFakeCoordX + 100;
267    const float scroll_to_y = kFakeCoordY + 100;
268    int motion_event_id = 0;
269
270    MockMotionEvent event =
271        ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
272    event.SetId(++motion_event_id);
273
274    EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
275
276    event = ObtainMotionEvent(event_time + kOneSecond,
277                              MotionEvent::ACTION_MOVE,
278                              scroll_to_x,
279                              scroll_to_y);
280    event.SetId(++motion_event_id);
281
282    EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
283    EXPECT_TRUE(gesture_provider_->IsScrollInProgress());
284    EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
285    EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
286    EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
287    EXPECT_EQ(BoundsForSingleMockTouchAtLocation(scroll_to_x, scroll_to_y),
288              GetMostRecentGestureEvent().details.bounding_box());
289    ASSERT_EQ(3U, GetReceivedGestureCount()) << "Only TapDown, "
290                                                "ScrollBegin and ScrollBy "
291                                                "should have been sent";
292
293    EXPECT_EQ(ET_GESTURE_SCROLL_BEGIN, GetReceivedGesture(1).type());
294    EXPECT_EQ(motion_event_id, GetReceivedGesture(1).motion_event_id);
295    EXPECT_EQ(event_time + kOneSecond, GetReceivedGesture(1).time)
296        << "ScrollBegin should have the time of the ACTION_MOVE";
297
298    event = ObtainMotionEvent(
299        event_time + kOneSecond, end_action_type, scroll_to_x, scroll_to_y);
300    event.SetId(++motion_event_id);
301
302    gesture_provider_->OnTouchEvent(event);
303    EXPECT_FALSE(gesture_provider_->IsScrollInProgress());
304    EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_END));
305    EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
306    EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
307    EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
308    EXPECT_EQ(BoundsForSingleMockTouchAtLocation(scroll_to_x, scroll_to_y),
309              GetMostRecentGestureEvent().details.bounding_box());
310  }
311
312  void OneFingerSwipe(float vx, float vy) {
313    std::vector<gfx::Vector2dF> velocities;
314    velocities.push_back(gfx::Vector2dF(vx, vy));
315    MultiFingerSwipe(velocities);
316  }
317
318  void TwoFingerSwipe(float vx0, float vy0, float vx1, float vy1) {
319    std::vector<gfx::Vector2dF> velocities;
320    velocities.push_back(gfx::Vector2dF(vx0, vy0));
321    velocities.push_back(gfx::Vector2dF(vx1, vy1));
322    MultiFingerSwipe(velocities);
323  }
324
325  void ThreeFingerSwipe(float vx0,
326                        float vy0,
327                        float vx1,
328                        float vy1,
329                        float vx2,
330                        float vy2) {
331    std::vector<gfx::Vector2dF> velocities;
332    velocities.push_back(gfx::Vector2dF(vx0, vy0));
333    velocities.push_back(gfx::Vector2dF(vx1, vy1));
334    velocities.push_back(gfx::Vector2dF(vx2, vy2));
335    MultiFingerSwipe(velocities);
336  }
337
338  void MultiFingerSwipe(std::vector<gfx::Vector2dF> velocities) {
339    ASSERT_GT(velocities.size(), 0U);
340
341    base::TimeTicks event_time = base::TimeTicks::Now();
342
343    std::vector<gfx::PointF> positions(velocities.size());
344    for (size_t i = 0; i < positions.size(); ++i)
345      positions[i] = gfx::PointF(kFakeCoordX * (i + 1), kFakeCoordY * (i + 1));
346
347    float dt = kDeltaTimeForFlingSequences.InSecondsF();
348
349    // Each pointer down should be a separate event.
350    for (size_t i = 0; i < positions.size(); ++i) {
351      const size_t pointer_count = i + 1;
352      std::vector<gfx::PointF> event_positions(pointer_count);
353      event_positions.assign(positions.begin(),
354                             positions.begin() + pointer_count);
355      MockMotionEvent event =
356          ObtainMotionEvent(event_time,
357                            pointer_count > 1 ? MotionEvent::ACTION_POINTER_DOWN
358                                              : MotionEvent::ACTION_DOWN,
359                            event_positions);
360      EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
361    }
362
363    for (size_t i = 0; i < positions.size(); ++i)
364      positions[i] += gfx::ScaleVector2d(velocities[i], dt);
365    MockMotionEvent event =
366        ObtainMotionEvent(event_time + kDeltaTimeForFlingSequences,
367                          MotionEvent::ACTION_MOVE,
368                          positions);
369    EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
370
371    for (size_t i = 0; i < positions.size(); ++i)
372      positions[i] += gfx::ScaleVector2d(velocities[i], dt);
373    event = ObtainMotionEvent(event_time + 2 * kDeltaTimeForFlingSequences,
374                              MotionEvent::ACTION_MOVE,
375                              positions);
376    EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
377
378    event = ObtainMotionEvent(event_time + 2 * kDeltaTimeForFlingSequences,
379                              MotionEvent::ACTION_POINTER_UP,
380                              positions);
381    EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
382  }
383
384  static void RunTasksAndWait(base::TimeDelta delay) {
385    base::MessageLoop::current()->PostDelayedTask(
386        FROM_HERE, base::MessageLoop::QuitClosure(), delay);
387    base::MessageLoop::current()->Run();
388  }
389
390  std::vector<GestureEventData> gestures_;
391  scoped_ptr<GestureProvider> gesture_provider_;
392  scoped_ptr<GestureEventData> active_scroll_begin_event_;
393  base::MessageLoopForUI message_loop_;
394};
395
396// Verify that a DOWN followed shortly by an UP will trigger a single tap.
397TEST_F(GestureProviderTest, GestureTap) {
398  base::TimeTicks event_time = base::TimeTicks::Now();
399  int motion_event_id = 0;
400
401  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false);
402
403  MockMotionEvent event =
404      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
405  event.SetId(++motion_event_id);
406
407  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
408  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
409  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
410  EXPECT_EQ(BoundsForSingleMockTouchAtLocation(kFakeCoordX, kFakeCoordY),
411            GetMostRecentGestureEvent().details.bounding_box());
412
413  event = ObtainMotionEvent(event_time + kOneMicrosecond,
414                            MotionEvent::ACTION_UP);
415  event.SetId(++motion_event_id);
416
417  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
418  EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
419  // Ensure tap details have been set.
420  EXPECT_EQ(1, GetMostRecentGestureEvent().details.tap_count());
421  EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
422  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
423  EXPECT_EQ(BoundsForSingleMockTouchAtLocation(kFakeCoordX, kFakeCoordY),
424            GetMostRecentGestureEvent().details.bounding_box());
425}
426
427// Verify that a DOWN followed shortly by an UP will trigger
428// a ET_GESTURE_TAP_UNCONFIRMED event if double-tap is enabled.
429TEST_F(GestureProviderTest, GestureTapWithDelay) {
430  base::TimeTicks event_time = base::TimeTicks::Now();
431  int motion_event_id = 0;
432
433  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true);
434
435  MockMotionEvent event =
436      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
437  event.SetId(++motion_event_id);
438
439  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
440  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
441  EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
442  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
443  EXPECT_EQ(BoundsForSingleMockTouchAtLocation(kFakeCoordX, kFakeCoordY),
444            GetMostRecentGestureEvent().details.bounding_box());
445
446  event = ObtainMotionEvent(event_time + kOneMicrosecond,
447                            MotionEvent::ACTION_UP);
448  event.SetId(++motion_event_id);
449
450  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
451  EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
452  // Ensure tap details have been set.
453  EXPECT_EQ(1, GetMostRecentGestureEvent().details.tap_count());
454  EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
455  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
456  EXPECT_EQ(BoundsForSingleMockTouchAtLocation(kFakeCoordX, kFakeCoordY),
457            GetMostRecentGestureEvent().details.bounding_box());
458
459  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_TAP));
460  RunTasksAndWait(GetDoubleTapTimeout());
461  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_TAP));
462}
463
464// Verify that a DOWN followed by a MOVE will trigger fling (but not LONG).
465TEST_F(GestureProviderTest, GestureFlingAndCancelLongPress) {
466  base::TimeTicks event_time = TimeTicks::Now();
467  base::TimeDelta delta_time = kDeltaTimeForFlingSequences;
468  int motion_event_id = 0;
469
470  MockMotionEvent event =
471      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
472  event.SetId(++motion_event_id);
473
474  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
475  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
476  EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
477  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
478
479  event = ObtainMotionEvent(event_time + delta_time,
480                            MotionEvent::ACTION_MOVE,
481                            kFakeCoordX * 10,
482                            kFakeCoordY * 10);
483  event.SetId(++motion_event_id);
484  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
485
486  event = ObtainMotionEvent(event_time + delta_time * 2,
487                            MotionEvent::ACTION_UP,
488                            kFakeCoordX * 10,
489                            kFakeCoordY * 10);
490  event.SetId(++motion_event_id);
491
492  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
493  EXPECT_EQ(ET_SCROLL_FLING_START, GetMostRecentGestureEventType());
494  EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
495  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
496  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_PRESS));
497  EXPECT_EQ(
498      BoundsForSingleMockTouchAtLocation(kFakeCoordX * 10, kFakeCoordY * 10),
499      GetMostRecentGestureEvent().details.bounding_box());
500}
501
502// Verify that for a normal scroll the following events are sent:
503// - ET_GESTURE_SCROLL_BEGIN
504// - ET_GESTURE_SCROLL_UPDATE
505// - ET_GESTURE_SCROLL_END
506TEST_F(GestureProviderTest, ScrollEventActionUpSequence) {
507  CheckScrollEventSequenceForEndActionType(MotionEvent::ACTION_UP);
508}
509
510// Verify that for a cancelled scroll the following events are sent:
511// - ET_GESTURE_SCROLL_BEGIN
512// - ET_GESTURE_SCROLL_UPDATE
513// - ET_GESTURE_SCROLL_END
514TEST_F(GestureProviderTest, ScrollEventActionCancelSequence) {
515  CheckScrollEventSequenceForEndActionType(MotionEvent::ACTION_CANCEL);
516}
517
518// Verify that for a normal fling (fling after scroll) the following events are
519// sent:
520// - ET_GESTURE_SCROLL_BEGIN
521// - ET_SCROLL_FLING_START
522TEST_F(GestureProviderTest, FlingEventSequence) {
523  base::TimeTicks event_time = base::TimeTicks::Now();
524  base::TimeDelta delta_time = kDeltaTimeForFlingSequences;
525  int motion_event_id = 0;
526
527  MockMotionEvent event =
528      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
529  event.SetId(++motion_event_id);
530
531  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
532
533  event = ObtainMotionEvent(event_time + delta_time,
534                            MotionEvent::ACTION_MOVE,
535                            kFakeCoordX * 5,
536                            kFakeCoordY * 5);
537  event.SetId(++motion_event_id);
538
539  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
540  EXPECT_TRUE(gesture_provider_->IsScrollInProgress());
541  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
542  EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
543  EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
544  ASSERT_EQ(3U, GetReceivedGestureCount());
545  ASSERT_EQ(ET_GESTURE_SCROLL_BEGIN, GetReceivedGesture(1).type());
546  EXPECT_EQ(motion_event_id, GetReceivedGesture(1).motion_event_id);
547
548  // We don't want to take a dependency here on exactly how hints are calculated
549  // for a fling (eg. may depend on velocity), so just validate the direction.
550  int hint_x = GetReceivedGesture(1).details.scroll_x_hint();
551  int hint_y = GetReceivedGesture(1).details.scroll_y_hint();
552  EXPECT_TRUE(hint_x > 0 && hint_y > 0 && hint_x > hint_y)
553      << "ScrollBegin hint should be in positive X axis";
554
555  event = ObtainMotionEvent(event_time + delta_time * 2,
556                            MotionEvent::ACTION_UP,
557                            kFakeCoordX * 10,
558                            kFakeCoordY * 10);
559  event.SetId(++motion_event_id);
560
561  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
562  EXPECT_FALSE(gesture_provider_->IsScrollInProgress());
563  EXPECT_EQ(ET_SCROLL_FLING_START, GetMostRecentGestureEventType());
564  EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
565  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
566  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SCROLL_END));
567  EXPECT_EQ(event_time + delta_time * 2, GetMostRecentGestureEvent().time)
568      << "FlingStart should have the time of the ACTION_UP";
569}
570
571TEST_F(GestureProviderTest, GestureCancelledWhenWindowFocusLost) {
572  const base::TimeTicks event_time = TimeTicks::Now();
573
574  MockMotionEvent event =
575      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
576  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
577  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
578
579  RunTasksAndWait(GetLongPressTimeout() + GetShowPressTimeout() +
580                  kOneMicrosecond);
581  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SHOW_PRESS));
582  EXPECT_EQ(ET_GESTURE_LONG_PRESS, GetMostRecentGestureEventType());
583
584  // The long press triggers window focus loss by opening a context menu.
585  EXPECT_TRUE(CancelActiveTouchSequence());
586  EXPECT_FALSE(HasDownEvent());
587
588  // A final ACTION_UP should have no effect.
589  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
590                            MotionEvent::ACTION_UP);
591  EXPECT_FALSE(gesture_provider_->OnTouchEvent(event));
592}
593
594TEST_F(GestureProviderTest, NoTapAfterScrollBegins) {
595  base::TimeTicks event_time = base::TimeTicks::Now();
596
597  MockMotionEvent event =
598      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
599
600  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
601
602  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
603  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
604  event = ObtainMotionEvent(event_time + kOneMicrosecond,
605                            MotionEvent::ACTION_MOVE,
606                            kFakeCoordX + 50,
607                            kFakeCoordY + 50);
608  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
609  EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
610
611  event = ObtainMotionEvent(event_time + kOneSecond,
612                            MotionEvent::ACTION_UP,
613                            kFakeCoordX + 50,
614                            kFakeCoordY + 50);
615  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
616  EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
617  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_TAP));
618}
619
620TEST_F(GestureProviderTest, DoubleTap) {
621  base::TimeTicks event_time = base::TimeTicks::Now();
622
623  MockMotionEvent event =
624      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
625  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
626
627  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
628  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
629
630  event = ObtainMotionEvent(event_time + kOneMicrosecond,
631                            MotionEvent::ACTION_UP,
632                            kFakeCoordX,
633                            kFakeCoordY);
634  gesture_provider_->OnTouchEvent(event);
635  EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
636  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
637
638  event_time += GetValidDoubleTapDelay();
639  event = ObtainMotionEvent(event_time,
640                            MotionEvent::ACTION_DOWN,
641                            kFakeCoordX,
642                            kFakeCoordY);
643  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
644  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
645  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
646
647  // Moving a very small amount of distance should not trigger the double tap
648  // drag zoom mode.
649  event = ObtainMotionEvent(event_time + kOneMicrosecond,
650                            MotionEvent::ACTION_MOVE,
651                            kFakeCoordX,
652                            kFakeCoordY + 1);
653  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
654  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
655  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
656
657  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
658                            MotionEvent::ACTION_UP,
659                            kFakeCoordX,
660                            kFakeCoordY + 1);
661  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
662
663  const GestureEventData& double_tap = GetMostRecentGestureEvent();
664  EXPECT_EQ(ET_GESTURE_DOUBLE_TAP, double_tap.type());
665  // Ensure tap details have been set.
666  EXPECT_EQ(10, double_tap.details.bounding_box().width());
667  EXPECT_EQ(10, double_tap.details.bounding_box().height());
668  EXPECT_EQ(1, double_tap.details.tap_count());
669}
670
671TEST_F(GestureProviderTest, DoubleTapDragZoomBasic) {
672  const base::TimeTicks down_time_1 = TimeTicks::Now();
673  const base::TimeTicks down_time_2 = down_time_1 + GetValidDoubleTapDelay();
674
675  MockMotionEvent event =
676      ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
677  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
678
679  event = ObtainMotionEvent(down_time_1 + kOneMicrosecond,
680                            MotionEvent::ACTION_UP,
681                            kFakeCoordX,
682                            kFakeCoordY);
683  gesture_provider_->OnTouchEvent(event);
684  EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
685  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
686
687  event = ObtainMotionEvent(
688      down_time_2, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
689  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
690  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
691  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
692
693  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
694                            MotionEvent::ACTION_MOVE,
695                            kFakeCoordX,
696                            kFakeCoordY + 100);
697  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
698  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
699  ASSERT_EQ(ET_GESTURE_PINCH_BEGIN, GetMostRecentGestureEventType());
700  EXPECT_EQ(BoundsForSingleMockTouchAtLocation(kFakeCoordX, kFakeCoordY + 100),
701            GetMostRecentGestureEvent().details.bounding_box());
702
703  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
704                            MotionEvent::ACTION_MOVE,
705                            kFakeCoordX,
706                            kFakeCoordY + 200);
707  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
708  ASSERT_EQ(ET_GESTURE_PINCH_UPDATE, GetMostRecentGestureEventType());
709  EXPECT_LT(1.f, GetMostRecentGestureEvent().details.scale());
710  EXPECT_EQ(BoundsForSingleMockTouchAtLocation(kFakeCoordX, kFakeCoordY + 200),
711            GetMostRecentGestureEvent().details.bounding_box());
712
713  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
714                            MotionEvent::ACTION_MOVE,
715                            kFakeCoordX,
716                            kFakeCoordY + 100);
717  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
718  ASSERT_EQ(ET_GESTURE_PINCH_UPDATE, GetMostRecentGestureEventType());
719  EXPECT_GT(1.f, GetMostRecentGestureEvent().details.scale());
720  EXPECT_EQ(BoundsForSingleMockTouchAtLocation(kFakeCoordX, kFakeCoordY + 100),
721            GetMostRecentGestureEvent().details.bounding_box());
722
723  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 4,
724                            MotionEvent::ACTION_UP,
725                            kFakeCoordX,
726                            kFakeCoordY - 200);
727  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
728  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_PINCH_END));
729  EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
730  EXPECT_EQ(BoundsForSingleMockTouchAtLocation(kFakeCoordX, kFakeCoordY - 200),
731            GetMostRecentGestureEvent().details.bounding_box());
732}
733
734// Generate a scroll gesture and verify that the resulting scroll motion event
735// has both absolute and relative position information.
736TEST_F(GestureProviderTest, ScrollUpdateValues) {
737  const float delta_x = 16;
738  const float delta_y = 84;
739
740  const base::TimeTicks event_time = TimeTicks::Now();
741
742  MockMotionEvent event =
743      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
744  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
745
746  // Move twice so that we get two ET_GESTURE_SCROLL_UPDATE events and can
747  // compare the relative and absolute coordinates.
748  event = ObtainMotionEvent(event_time + kOneMicrosecond,
749                            MotionEvent::ACTION_MOVE,
750                            kFakeCoordX - delta_x / 2,
751                            kFakeCoordY - delta_y / 2);
752  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
753
754  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
755                            MotionEvent::ACTION_MOVE,
756                            kFakeCoordX - delta_x,
757                            kFakeCoordY - delta_y);
758  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
759
760  // Make sure the reported gesture event has all the expected details.
761  ASSERT_LT(0U, GetReceivedGestureCount());
762  GestureEventData gesture = GetMostRecentGestureEvent();
763  EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, gesture.type());
764  EXPECT_EQ(event_time + kOneMicrosecond * 2, gesture.time);
765  EXPECT_EQ(kFakeCoordX - delta_x, gesture.x);
766  EXPECT_EQ(kFakeCoordY - delta_y, gesture.y);
767  EXPECT_EQ(1, gesture.details.touch_points());
768
769  // No horizontal delta because of snapping.
770  EXPECT_EQ(0, gesture.details.scroll_x());
771  EXPECT_EQ(-delta_y / 2, gesture.details.scroll_y());
772}
773
774// Verify that fractional scroll deltas are rounded as expected and that
775// fractional scrolling doesn't break scroll snapping.
776TEST_F(GestureProviderTest, FractionalScroll) {
777  const float delta_x = 0.4f;
778  const float delta_y = 5.2f;
779
780  const base::TimeTicks event_time = TimeTicks::Now();
781
782  MockMotionEvent event =
783      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
784  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
785
786  // Skip past the touch slop and move back.
787  event = ObtainMotionEvent(event_time,
788                            MotionEvent::ACTION_MOVE,
789                            kFakeCoordX,
790                            kFakeCoordY + 100);
791  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
792  event = ObtainMotionEvent(event_time,
793                            MotionEvent::ACTION_MOVE);
794  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
795
796  // Now move up slowly, mostly vertically but with a (fractional) bit of
797  // horizontal motion.
798  for(int i = 1; i <= 10; i++) {
799    event = ObtainMotionEvent(event_time + kOneMicrosecond * i,
800                              MotionEvent::ACTION_MOVE,
801                              kFakeCoordX + delta_x * i,
802                              kFakeCoordY + delta_y * i);
803    EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
804
805    ASSERT_LT(0U, GetReceivedGestureCount());
806    GestureEventData gesture = GetMostRecentGestureEvent();
807    EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, gesture.type());
808    EXPECT_EQ(event_time + kOneMicrosecond * i, gesture.time);
809    EXPECT_EQ(1, gesture.details.touch_points());
810
811    // Verify that the event co-ordinates are still the precise values we
812    // supplied.
813    EXPECT_EQ(kFakeCoordX + delta_x * i, gesture.x);
814    EXPECT_EQ(kFakeCoordY + delta_y * i, gesture.y);
815
816    // Verify that we're scrolling vertically by the expected amount
817    // (modulo rounding).
818    EXPECT_GE(gesture.details.scroll_y(), (int)delta_y);
819    EXPECT_LE(gesture.details.scroll_y(), ((int)delta_y) + 1);
820
821    // And that there has been no horizontal motion at all.
822    EXPECT_EQ(0, gesture.details.scroll_x());
823  }
824}
825
826// Generate a scroll gesture and verify that the resulting scroll begin event
827// has the expected hint values.
828TEST_F(GestureProviderTest, ScrollBeginValues) {
829  const float delta_x = 13;
830  const float delta_y = 89;
831
832  const base::TimeTicks event_time = TimeTicks::Now();
833
834  MockMotionEvent event =
835      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
836  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
837
838  // Move twice such that the first event isn't sufficient to start
839  // scrolling on it's own.
840  event = ObtainMotionEvent(event_time + kOneMicrosecond,
841                            MotionEvent::ACTION_MOVE,
842                            kFakeCoordX + 2,
843                            kFakeCoordY + 1);
844  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
845  EXPECT_FALSE(gesture_provider_->IsScrollInProgress());
846
847  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
848                            MotionEvent::ACTION_MOVE,
849                            kFakeCoordX + delta_x,
850                            kFakeCoordY + delta_y);
851  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
852  EXPECT_TRUE(gesture_provider_->IsScrollInProgress());
853
854  const GestureEventData* scroll_begin_gesture = GetActiveScrollBeginEvent();
855  ASSERT_TRUE(!!scroll_begin_gesture);
856  EXPECT_EQ(delta_x, scroll_begin_gesture->details.scroll_x_hint());
857  EXPECT_EQ(delta_y, scroll_begin_gesture->details.scroll_y_hint());
858}
859
860TEST_F(GestureProviderTest, LongPressAndTapCancelledWhenScrollBegins) {
861  base::TimeTicks event_time = base::TimeTicks::Now();
862
863  MockMotionEvent event =
864      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
865  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
866  event = ObtainMotionEvent(event_time + kOneMicrosecond,
867                            MotionEvent::ACTION_MOVE,
868                            kFakeCoordX * 5,
869                            kFakeCoordY * 5);
870  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
871  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
872                            MotionEvent::ACTION_MOVE,
873                            kFakeCoordX * 10,
874                            kFakeCoordY * 10);
875  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
876
877  const base::TimeDelta long_press_timeout =
878      GetLongPressTimeout() + GetShowPressTimeout() + kOneMicrosecond;
879  RunTasksAndWait(long_press_timeout);
880
881  // No LONG_TAP as the LONG_PRESS timer is cancelled.
882  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_PRESS));
883  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_TAP));
884}
885
886// Verify that LONG_TAP is triggered after LONG_PRESS followed by an UP.
887TEST_F(GestureProviderTest, GestureLongTap) {
888  base::TimeTicks event_time = base::TimeTicks::Now();
889
890  MockMotionEvent event =
891      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
892  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
893
894  const base::TimeDelta long_press_timeout =
895      GetLongPressTimeout() + GetShowPressTimeout() + kOneMicrosecond;
896  RunTasksAndWait(long_press_timeout);
897
898  EXPECT_EQ(ET_GESTURE_LONG_PRESS, GetMostRecentGestureEventType());
899  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
900  EXPECT_EQ(BoundsForSingleMockTouchAtLocation(kFakeCoordX, kFakeCoordY),
901            GetMostRecentGestureEvent().details.bounding_box());
902
903  event = ObtainMotionEvent(event_time + kOneSecond, MotionEvent::ACTION_UP);
904  gesture_provider_->OnTouchEvent(event);
905  EXPECT_EQ(ET_GESTURE_LONG_TAP, GetMostRecentGestureEventType());
906  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
907  EXPECT_EQ(BoundsForSingleMockTouchAtLocation(kFakeCoordX, kFakeCoordY),
908            GetMostRecentGestureEvent().details.bounding_box());
909}
910
911TEST_F(GestureProviderTest, GestureLongPressDoesNotPreventScrolling) {
912  base::TimeTicks event_time = base::TimeTicks::Now();
913
914  MockMotionEvent event =
915      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
916  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
917
918  const base::TimeDelta long_press_timeout =
919      GetLongPressTimeout() + GetShowPressTimeout() + kOneMicrosecond;
920  RunTasksAndWait(long_press_timeout);
921
922  EXPECT_EQ(ET_GESTURE_LONG_PRESS, GetMostRecentGestureEventType());
923  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
924  event = ObtainMotionEvent(event_time + long_press_timeout,
925                            MotionEvent::ACTION_MOVE,
926                            kFakeCoordX + 100,
927                            kFakeCoordY + 100);
928  gesture_provider_->OnTouchEvent(event);
929
930  EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
931  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
932  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
933
934  event = ObtainMotionEvent(event_time + long_press_timeout,
935                            MotionEvent::ACTION_UP);
936  gesture_provider_->OnTouchEvent(event);
937  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_TAP));
938}
939
940TEST_F(GestureProviderTest, NoGestureLongPressDuringDoubleTap) {
941  base::TimeTicks event_time = base::TimeTicks::Now();
942  int motion_event_id = 0;
943
944  MockMotionEvent event = ObtainMotionEvent(
945      event_time, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
946  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
947
948  event = ObtainMotionEvent(event_time + kOneMicrosecond,
949                            MotionEvent::ACTION_UP,
950                            kFakeCoordX,
951                            kFakeCoordY);
952  gesture_provider_->OnTouchEvent(event);
953  EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
954  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
955
956  event_time += GetValidDoubleTapDelay();
957  event = ObtainMotionEvent(event_time,
958                            MotionEvent::ACTION_DOWN,
959                            kFakeCoordX,
960                            kFakeCoordY);
961  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
962  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
963  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
964  EXPECT_TRUE(gesture_provider_->IsDoubleTapInProgress());
965
966  const base::TimeDelta long_press_timeout =
967      GetLongPressTimeout() + GetShowPressTimeout() + kOneMicrosecond;
968  RunTasksAndWait(long_press_timeout);
969  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_PRESS));
970
971  event = ObtainMotionEvent(event_time + long_press_timeout,
972                            MotionEvent::ACTION_MOVE,
973                            kFakeCoordX + 20,
974                            kFakeCoordY + 20);
975  event.SetId(++motion_event_id);
976
977  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
978  EXPECT_EQ(ET_GESTURE_PINCH_BEGIN, GetMostRecentGestureEventType());
979  EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
980  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
981  EXPECT_TRUE(gesture_provider_->IsDoubleTapInProgress());
982
983  event = ObtainMotionEvent(event_time + long_press_timeout + kOneMicrosecond,
984                            MotionEvent::ACTION_UP,
985                            kFakeCoordX,
986                            kFakeCoordY + 1);
987  event.SetId(++motion_event_id);
988  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
989  EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
990  EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
991  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
992  EXPECT_FALSE(gesture_provider_->IsDoubleTapInProgress());
993}
994
995// Verify that the touch slop region is removed from the first scroll delta to
996// avoid a jump when starting to scroll.
997TEST_F(GestureProviderTest, TouchSlopRemovedFromScroll) {
998  const float touch_slop = GetTouchSlop();
999  const float scroll_delta = 5;
1000
1001  base::TimeTicks event_time = base::TimeTicks::Now();
1002
1003  MockMotionEvent event =
1004      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
1005  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1006
1007  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
1008                            MotionEvent::ACTION_MOVE,
1009                            kFakeCoordX,
1010                            kFakeCoordY + touch_slop + scroll_delta);
1011  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1012
1013  EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
1014  GestureEventData gesture = GetMostRecentGestureEvent();
1015  EXPECT_EQ(0, gesture.details.scroll_x());
1016  EXPECT_EQ(scroll_delta, gesture.details.scroll_y());
1017  EXPECT_EQ(1, gesture.details.touch_points());
1018}
1019
1020// Verify that movement within the touch slop region does not generate a scroll,
1021// and that the slop region is correct even when using fractional coordinates.
1022TEST_F(GestureProviderTest, NoScrollWithinTouchSlop) {
1023  const float touch_slop = GetTouchSlop();
1024  const float scale_factor = 2.5f;
1025  const int touch_slop_pixels = static_cast<int>(scale_factor * touch_slop);
1026
1027  base::TimeTicks event_time = base::TimeTicks::Now();
1028
1029  MockMotionEvent event =
1030      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
1031  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1032
1033  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
1034                            MotionEvent::ACTION_MOVE,
1035                            kFakeCoordX + touch_slop_pixels / scale_factor,
1036                            kFakeCoordY);
1037  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1038  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
1039
1040  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
1041                            MotionEvent::ACTION_MOVE,
1042                            kFakeCoordX,
1043                            kFakeCoordY + touch_slop_pixels / scale_factor);
1044  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1045  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
1046
1047  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
1048                            MotionEvent::ACTION_MOVE,
1049                            kFakeCoordX - touch_slop_pixels / scale_factor,
1050                            kFakeCoordY);
1051  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1052  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
1053
1054  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
1055                            MotionEvent::ACTION_MOVE,
1056                            kFakeCoordX,
1057                            kFakeCoordY - touch_slop_pixels / scale_factor);
1058  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1059  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
1060
1061  event =
1062      ObtainMotionEvent(event_time + kOneMicrosecond * 2,
1063                        MotionEvent::ACTION_MOVE,
1064                        kFakeCoordX,
1065                        kFakeCoordY + (touch_slop_pixels + 1.f) / scale_factor);
1066  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1067  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
1068}
1069
1070TEST_F(GestureProviderTest, NoDoubleTapWhenTooRapid) {
1071  base::TimeTicks event_time = base::TimeTicks::Now();
1072
1073  MockMotionEvent event =
1074      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
1075  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1076
1077  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1078  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1079
1080  event = ObtainMotionEvent(event_time + kOneMicrosecond,
1081                            MotionEvent::ACTION_UP,
1082                            kFakeCoordX,
1083                            kFakeCoordY);
1084  gesture_provider_->OnTouchEvent(event);
1085  EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
1086  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1087
1088  // If the second tap follows the first in too short a time span, no double-tap
1089  // will occur.
1090  event_time += (GetDoubleTapMinTime() / 2);
1091  event = ObtainMotionEvent(event_time,
1092                            MotionEvent::ACTION_DOWN,
1093                            kFakeCoordX,
1094                            kFakeCoordY);
1095  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1096  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1097  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1098
1099  event = ObtainMotionEvent(event_time + kOneMicrosecond,
1100                            MotionEvent::ACTION_UP,
1101                            kFakeCoordX,
1102                            kFakeCoordY);
1103  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1104  EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
1105}
1106
1107TEST_F(GestureProviderTest, NoDoubleTapWhenExplicitlyDisabled) {
1108  // Ensure that double-tap gestures can be disabled.
1109  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false);
1110
1111  base::TimeTicks event_time = base::TimeTicks::Now();
1112  MockMotionEvent event = ObtainMotionEvent(
1113      event_time, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
1114  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1115  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1116
1117  event = ObtainMotionEvent(event_time + kOneMicrosecond,
1118                            MotionEvent::ACTION_UP,
1119                            kFakeCoordX,
1120                            kFakeCoordY);
1121  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1122  EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
1123
1124  event_time += GetValidDoubleTapDelay();
1125  event = ObtainMotionEvent(event_time,
1126                            MotionEvent::ACTION_DOWN,
1127                            kFakeCoordX,
1128                            kFakeCoordY);
1129  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1130  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1131
1132  event = ObtainMotionEvent(event_time + kOneMicrosecond,
1133                            MotionEvent::ACTION_UP,
1134                            kFakeCoordX,
1135                            kFakeCoordY);
1136  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1137  EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
1138
1139  // Ensure that double-tap gestures can be interrupted.
1140  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true);
1141
1142  event_time = base::TimeTicks::Now();
1143  event = ObtainMotionEvent(
1144      event_time, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
1145  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1146  EXPECT_EQ(5U, GetReceivedGestureCount());
1147
1148  event = ObtainMotionEvent(event_time + kOneMicrosecond,
1149                            MotionEvent::ACTION_UP,
1150                            kFakeCoordX,
1151                            kFakeCoordY);
1152  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1153  EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
1154
1155  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false);
1156  EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
1157
1158  // Ensure that double-tap gestures can be resumed.
1159  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true);
1160
1161  event_time += GetValidDoubleTapDelay();
1162  event = ObtainMotionEvent(event_time,
1163                            MotionEvent::ACTION_DOWN,
1164                            kFakeCoordX,
1165                            kFakeCoordY);
1166  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1167  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1168
1169  event = ObtainMotionEvent(event_time + kOneMicrosecond,
1170                            MotionEvent::ACTION_UP,
1171                            kFakeCoordX,
1172                            kFakeCoordY);
1173  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1174  EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
1175
1176  event_time += GetValidDoubleTapDelay();
1177  event = ObtainMotionEvent(event_time,
1178                            MotionEvent::ACTION_DOWN,
1179                            kFakeCoordX,
1180                            kFakeCoordY);
1181  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1182  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1183
1184  event = ObtainMotionEvent(event_time + kOneMicrosecond,
1185                            MotionEvent::ACTION_UP,
1186                            kFakeCoordX,
1187                            kFakeCoordY);
1188  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1189  EXPECT_EQ(ET_GESTURE_DOUBLE_TAP, GetMostRecentGestureEventType());
1190}
1191
1192TEST_F(GestureProviderTest, NoDelayedTapWhenDoubleTapSupportToggled) {
1193  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true);
1194
1195  base::TimeTicks event_time = base::TimeTicks::Now();
1196  MockMotionEvent event = ObtainMotionEvent(
1197      event_time, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
1198  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1199  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1200  EXPECT_EQ(1U, GetReceivedGestureCount());
1201
1202  event = ObtainMotionEvent(event_time + kOneMicrosecond,
1203                            MotionEvent::ACTION_UP,
1204                            kFakeCoordX,
1205                            kFakeCoordY);
1206  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1207  EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
1208  EXPECT_EQ(2U, GetReceivedGestureCount());
1209
1210  // Disabling double-tap during the tap timeout should flush the delayed tap.
1211  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false);
1212  EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
1213  EXPECT_EQ(3U, GetReceivedGestureCount());
1214
1215  // No further timeout gestures should arrive.
1216  const base::TimeDelta long_press_timeout =
1217      GetLongPressTimeout() + GetShowPressTimeout() + kOneMicrosecond;
1218  RunTasksAndWait(long_press_timeout);
1219  EXPECT_EQ(3U, GetReceivedGestureCount());
1220}
1221
1222TEST_F(GestureProviderTest, NoDoubleTapDragZoomWhenDisabledOnPlatform) {
1223  const base::TimeTicks down_time_1 = TimeTicks::Now();
1224  const base::TimeTicks down_time_2 = down_time_1 + GetValidDoubleTapDelay();
1225
1226  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false);
1227
1228  MockMotionEvent event =
1229      ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
1230  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1231
1232  event = ObtainMotionEvent(down_time_1 + kOneMicrosecond,
1233                            MotionEvent::ACTION_UP,
1234                            kFakeCoordX,
1235                            kFakeCoordY);
1236  gesture_provider_->OnTouchEvent(event);
1237
1238  event = ObtainMotionEvent(
1239      down_time_2, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
1240  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1241
1242  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
1243                            MotionEvent::ACTION_MOVE,
1244                            kFakeCoordX,
1245                            kFakeCoordY + 100);
1246
1247  // The move should become a scroll, as doubletap drag zoom is disabled.
1248  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1249  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
1250  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_BEGIN));
1251
1252  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
1253                            MotionEvent::ACTION_MOVE,
1254                            kFakeCoordX,
1255                            kFakeCoordY + 200);
1256  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1257  EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
1258  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1259  EXPECT_EQ(down_time_2 + kOneMicrosecond * 2,
1260            GetMostRecentGestureEvent().time);
1261  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_UPDATE));
1262
1263  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
1264                            MotionEvent::ACTION_UP,
1265                            kFakeCoordX,
1266                            kFakeCoordY + 200);
1267  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1268  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_END));
1269}
1270
1271// Verify that double tap drag zoom feature is not invoked when the gesture
1272// handler is told to disable double tap gesture detection.
1273// The second tap sequence should be treated just as the first would be.
1274TEST_F(GestureProviderTest, NoDoubleTapDragZoomWhenDisabledOnPage) {
1275  const base::TimeTicks down_time_1 = TimeTicks::Now();
1276  const base::TimeTicks down_time_2 = down_time_1 + GetValidDoubleTapDelay();
1277
1278  gesture_provider_->SetDoubleTapSupportForPageEnabled(false);
1279
1280  MockMotionEvent event =
1281      ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
1282  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1283
1284  event = ObtainMotionEvent(down_time_1 + kOneMicrosecond,
1285                            MotionEvent::ACTION_UP,
1286                            kFakeCoordX,
1287                            kFakeCoordY);
1288  gesture_provider_->OnTouchEvent(event);
1289
1290  event = ObtainMotionEvent(
1291      down_time_2, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
1292  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1293
1294  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
1295                            MotionEvent::ACTION_MOVE,
1296                            kFakeCoordX,
1297                            kFakeCoordY + 100);
1298
1299  // The move should become a scroll, as double tap drag zoom is disabled.
1300  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1301  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
1302  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_BEGIN));
1303
1304  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
1305                            MotionEvent::ACTION_MOVE,
1306                            kFakeCoordX,
1307                            kFakeCoordY + 200);
1308  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1309  EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
1310  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1311  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_UPDATE));
1312
1313  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
1314                            MotionEvent::ACTION_UP,
1315                            kFakeCoordX,
1316                            kFakeCoordY + 200);
1317  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1318  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_END));
1319}
1320
1321// Verify that updating double tap support during a double tap drag zoom
1322// disables double tap detection after the gesture has ended.
1323TEST_F(GestureProviderTest, FixedPageScaleDuringDoubleTapDragZoom) {
1324  base::TimeTicks down_time_1 = TimeTicks::Now();
1325  base::TimeTicks down_time_2 = down_time_1 + GetValidDoubleTapDelay();
1326
1327  gesture_provider_->SetDoubleTapSupportForPageEnabled(true);
1328  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true);
1329
1330  // Start a double-tap drag gesture.
1331  MockMotionEvent event =
1332      ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
1333  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1334  event = ObtainMotionEvent(down_time_1 + kOneMicrosecond,
1335                            MotionEvent::ACTION_UP,
1336                            kFakeCoordX,
1337                            kFakeCoordY);
1338  gesture_provider_->OnTouchEvent(event);
1339  event = ObtainMotionEvent(
1340      down_time_2, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
1341  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1342  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
1343                            MotionEvent::ACTION_MOVE,
1344                            kFakeCoordX,
1345                            kFakeCoordY + 100);
1346  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1347  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
1348  EXPECT_EQ(ET_GESTURE_PINCH_BEGIN, GetMostRecentGestureEventType());
1349  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1350
1351  // Simulate setting a fixed page scale (or a mobile viewport);
1352  // this should not disrupt the current double-tap gesture.
1353  gesture_provider_->SetDoubleTapSupportForPageEnabled(false);
1354
1355  // Double tap zoom updates should continue.
1356  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
1357                            MotionEvent::ACTION_MOVE,
1358                            kFakeCoordX,
1359                            kFakeCoordY + 200);
1360  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1361  EXPECT_EQ(ET_GESTURE_PINCH_UPDATE, GetMostRecentGestureEventType());
1362  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1363  EXPECT_LT(1.f, GetMostRecentGestureEvent().details.scale());
1364  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
1365                            MotionEvent::ACTION_UP,
1366                            kFakeCoordX,
1367                            kFakeCoordY + 200);
1368  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1369  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_PINCH_END));
1370  EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
1371  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1372
1373  // The double-tap gesture has finished, but the page scale is fixed.
1374  // The same event sequence should not generate any double tap getsures.
1375  gestures_.clear();
1376  down_time_1 += kOneMicrosecond * 40;
1377  down_time_2 += kOneMicrosecond * 40;
1378
1379  // Start a double-tap drag gesture.
1380  event = ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
1381  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1382  event = ObtainMotionEvent(down_time_1 + kOneMicrosecond,
1383                            MotionEvent::ACTION_UP,
1384                            kFakeCoordX,
1385                            kFakeCoordY);
1386  gesture_provider_->OnTouchEvent(event);
1387  event = ObtainMotionEvent(
1388      down_time_2, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
1389  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1390  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
1391                            MotionEvent::ACTION_MOVE,
1392                            kFakeCoordX,
1393                            kFakeCoordY + 100);
1394  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1395  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
1396  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_BEGIN));
1397
1398  // Double tap zoom updates should not be sent.
1399  // Instead, the second tap drag becomes a scroll gesture sequence.
1400  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
1401                            MotionEvent::ACTION_MOVE,
1402                            kFakeCoordX,
1403                            kFakeCoordY + 200);
1404  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1405  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_UPDATE));
1406  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_UPDATE));
1407  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
1408                            MotionEvent::ACTION_UP,
1409                            kFakeCoordX,
1410                            kFakeCoordY + 200);
1411  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1412  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_END));
1413}
1414
1415// Verify that pinch zoom sends the proper event sequence.
1416TEST_F(GestureProviderTest, PinchZoom) {
1417  base::TimeTicks event_time = base::TimeTicks::Now();
1418  const float touch_slop = GetTouchSlop();
1419  int motion_event_id = 0;
1420
1421  gesture_provider_->SetDoubleTapSupportForPageEnabled(false);
1422  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true);
1423  gesture_provider_->SetMultiTouchZoomSupportEnabled(true);
1424
1425  int secondary_coord_x = kFakeCoordX + 20 * touch_slop;
1426  int secondary_coord_y = kFakeCoordY + 20 * touch_slop;
1427
1428  MockMotionEvent event =
1429      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
1430  event.SetId(++motion_event_id);
1431  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1432  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1433  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1434  EXPECT_EQ(BoundsForSingleMockTouchAtLocation(kFakeCoordX, kFakeCoordY),
1435            GetMostRecentGestureEvent().details.bounding_box());
1436
1437  // Toggling double-tap support should not take effect until the next sequence.
1438  gesture_provider_->SetDoubleTapSupportForPageEnabled(true);
1439
1440  event = ObtainMotionEvent(event_time,
1441                            MotionEvent::ACTION_POINTER_DOWN,
1442                            kFakeCoordX,
1443                            kFakeCoordY,
1444                            secondary_coord_x,
1445                            secondary_coord_y);
1446  event.SetId(++motion_event_id);
1447
1448  gesture_provider_->OnTouchEvent(event);
1449  EXPECT_EQ(1U, GetReceivedGestureCount());
1450  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1451  EXPECT_EQ(BoundsForSingleMockTouchAtLocation(kFakeCoordX, kFakeCoordY),
1452            GetMostRecentGestureEvent().details.bounding_box());
1453
1454  secondary_coord_x += 5 * touch_slop;
1455  secondary_coord_y += 5 * touch_slop;
1456  event = ObtainMotionEvent(event_time,
1457                            MotionEvent::ACTION_MOVE,
1458                            kFakeCoordX,
1459                            kFakeCoordY,
1460                            secondary_coord_x,
1461                            secondary_coord_y);
1462  event.SetId(++motion_event_id);
1463
1464  // Toggling double-tap support should not take effect until the next sequence.
1465  gesture_provider_->SetDoubleTapSupportForPageEnabled(false);
1466
1467  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1468  EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
1469  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
1470  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_PINCH_BEGIN));
1471  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
1472  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_UPDATE));
1473
1474  EXPECT_EQ((kFakeCoordX + secondary_coord_x) / 2, GetReceivedGesture(3).x);
1475  EXPECT_EQ((kFakeCoordY + secondary_coord_y) / 2, GetReceivedGesture(3).y);
1476
1477  EXPECT_EQ(
1478      gfx::RectF(kFakeCoordX - kMockTouchRadius,
1479                 kFakeCoordY - kMockTouchRadius,
1480                 secondary_coord_x - kFakeCoordX + kMockTouchRadius * 2,
1481                 secondary_coord_y - kFakeCoordY + kMockTouchRadius * 2),
1482      GetMostRecentGestureEvent().details.bounding_box());
1483
1484  secondary_coord_x += 2 * touch_slop;
1485  secondary_coord_y += 2 * touch_slop;
1486  event = ObtainMotionEvent(event_time,
1487                            MotionEvent::ACTION_MOVE,
1488                            kFakeCoordX,
1489                            kFakeCoordY,
1490                            secondary_coord_x,
1491                            secondary_coord_y);
1492  event.SetId(++motion_event_id);
1493
1494  // Toggling double-tap support should not take effect until the next sequence.
1495  gesture_provider_->SetDoubleTapSupportForPageEnabled(true);
1496
1497  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1498  EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
1499  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_UPDATE));
1500  EXPECT_EQ(ET_GESTURE_PINCH_UPDATE, GetMostRecentGestureEventType());
1501  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
1502  EXPECT_LT(1.f, GetMostRecentGestureEvent().details.scale());
1503  EXPECT_EQ(
1504      gfx::RectF(kFakeCoordX - kMockTouchRadius,
1505                 kFakeCoordY - kMockTouchRadius,
1506                 secondary_coord_x - kFakeCoordX + kMockTouchRadius * 2,
1507                 secondary_coord_y - kFakeCoordY + kMockTouchRadius * 2),
1508      GetMostRecentGestureEvent().details.bounding_box());
1509
1510  event = ObtainMotionEvent(event_time,
1511                            MotionEvent::ACTION_POINTER_UP,
1512                            kFakeCoordX,
1513                            kFakeCoordY,
1514                            secondary_coord_x,
1515                            secondary_coord_y);
1516  event.SetId(++motion_event_id);
1517
1518  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1519  EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
1520  EXPECT_EQ(ET_GESTURE_PINCH_END, GetMostRecentGestureEventType());
1521  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
1522  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SCROLL_END));
1523  EXPECT_EQ(
1524      gfx::RectF(kFakeCoordX - kMockTouchRadius,
1525                 kFakeCoordY - kMockTouchRadius,
1526                 secondary_coord_x - kFakeCoordX + kMockTouchRadius * 2,
1527                 secondary_coord_y - kFakeCoordY + kMockTouchRadius * 2),
1528      GetMostRecentGestureEvent().details.bounding_box());
1529
1530  event = ObtainMotionEvent(event_time, MotionEvent::ACTION_UP);
1531  gesture_provider_->OnTouchEvent(event);
1532  EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
1533  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1534  EXPECT_EQ(gfx::RectF(kFakeCoordX - kMockTouchRadius,
1535                       kFakeCoordY - kMockTouchRadius,
1536                       kMockTouchRadius * 2,
1537                       kMockTouchRadius * 2),
1538            GetMostRecentGestureEvent().details.bounding_box());
1539}
1540
1541// Verify that no accidental pinching occurs if the touch size is large relative
1542// to the min scaling span.
1543TEST_F(GestureProviderTest, NoPinchZoomWithFatFinger) {
1544  base::TimeTicks event_time = base::TimeTicks::Now();
1545  const float kFatFingerSize = GetMinScalingSpan() * 3.f;
1546
1547  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false);
1548  gesture_provider_->SetMultiTouchZoomSupportEnabled(true);
1549
1550  MockMotionEvent event =
1551      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
1552  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1553  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1554  EXPECT_EQ(1U, GetReceivedGestureCount());
1555
1556  event = ObtainMotionEvent(event_time + kOneSecond,
1557                            MotionEvent::ACTION_MOVE);
1558  event.SetTouchMajor(0.1f);
1559  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1560  EXPECT_EQ(1U, GetReceivedGestureCount());
1561
1562  event = ObtainMotionEvent(event_time + kOneSecond * 2,
1563                            MotionEvent::ACTION_MOVE,
1564                            kFakeCoordX + 1.f,
1565                            kFakeCoordY);
1566  event.SetTouchMajor(1.f);
1567  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1568  EXPECT_EQ(1U, GetReceivedGestureCount());
1569
1570  event = ObtainMotionEvent(event_time + kOneSecond * 3,
1571                            MotionEvent::ACTION_MOVE);
1572  event.SetTouchMajor(kFatFingerSize * 3.5f);
1573  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1574  EXPECT_EQ(1U, GetReceivedGestureCount());
1575
1576  event = ObtainMotionEvent(event_time + kOneSecond * 4,
1577                            MotionEvent::ACTION_MOVE);
1578  event.SetTouchMajor(kFatFingerSize * 5.f);
1579  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1580  EXPECT_EQ(1U, GetReceivedGestureCount());
1581}
1582
1583// Verify that multi-finger swipe sends the proper event sequence.
1584TEST_F(GestureProviderTest, MultiFingerSwipe) {
1585  EnableSwipe();
1586  gesture_provider_->SetMultiTouchZoomSupportEnabled(false);
1587  const float min_swipe_velocity = GetMinSwipeVelocity();
1588
1589  // One finger - swipe right
1590  OneFingerSwipe(2 * min_swipe_velocity, 0);
1591  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SWIPE));
1592  EXPECT_TRUE(GetMostRecentGestureEvent().details.swipe_right());
1593  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1594  ResetGestureDetection();
1595
1596  // One finger - swipe left
1597  OneFingerSwipe(-2 * min_swipe_velocity, 0);
1598  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SWIPE));
1599  EXPECT_TRUE(GetMostRecentGestureEvent().details.swipe_left());
1600  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1601  ResetGestureDetection();
1602
1603  // One finger - swipe down
1604  OneFingerSwipe(0, 2 * min_swipe_velocity);
1605  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SWIPE));
1606  EXPECT_TRUE(GetMostRecentGestureEvent().details.swipe_down());
1607  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1608  ResetGestureDetection();
1609
1610  // One finger - swipe up
1611  OneFingerSwipe(0, -2 * min_swipe_velocity);
1612  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SWIPE));
1613  EXPECT_TRUE(GetMostRecentGestureEvent().details.swipe_up());
1614  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1615  ResetGestureDetection();
1616
1617  // Two fingers
1618  // Swipe right.
1619  TwoFingerSwipe(min_swipe_velocity * 2, 0, min_swipe_velocity * 2, 0);
1620  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SWIPE));
1621  EXPECT_TRUE(GetMostRecentGestureEvent().details.swipe_right());
1622  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
1623  ResetGestureDetection();
1624
1625  // Swipe left.
1626  TwoFingerSwipe(-min_swipe_velocity * 2, 0, -min_swipe_velocity * 2, 0);
1627  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SWIPE));
1628  EXPECT_TRUE(GetMostRecentGestureEvent().details.swipe_left());
1629  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
1630  ResetGestureDetection();
1631
1632  // No swipe with different touch directions.
1633  TwoFingerSwipe(min_swipe_velocity * 2, 0, -min_swipe_velocity * 2, 0);
1634  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SWIPE));
1635  ResetGestureDetection();
1636
1637  // No swipe without a dominant direction.
1638  TwoFingerSwipe(min_swipe_velocity * 2,
1639                 min_swipe_velocity * 2,
1640                 min_swipe_velocity * 2,
1641                 min_swipe_velocity * 2);
1642  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SWIPE));
1643  ResetGestureDetection();
1644
1645  // Swipe down with non-zero velocities on both axes and dominant direction.
1646  TwoFingerSwipe(-min_swipe_velocity,
1647                 min_swipe_velocity * 4,
1648                 -min_swipe_velocity,
1649                 min_swipe_velocity * 4);
1650  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SWIPE));
1651  EXPECT_TRUE(GetMostRecentGestureEvent().details.swipe_down());
1652  EXPECT_FALSE(GetMostRecentGestureEvent().details.swipe_left());
1653  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
1654  ResetGestureDetection();
1655
1656  // Swipe up with non-zero velocities on both axes.
1657  TwoFingerSwipe(min_swipe_velocity,
1658                 -min_swipe_velocity * 4,
1659                 min_swipe_velocity,
1660                 -min_swipe_velocity * 4);
1661  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SWIPE));
1662  EXPECT_TRUE(GetMostRecentGestureEvent().details.swipe_up());
1663  EXPECT_FALSE(GetMostRecentGestureEvent().details.swipe_right());
1664  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
1665  ResetGestureDetection();
1666
1667  // No swipe without sufficient velocity.
1668  TwoFingerSwipe(min_swipe_velocity / 2, 0, 0, 0);
1669  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SWIPE));
1670  ResetGestureDetection();
1671
1672  // Swipe up with one small and one medium velocity in slightly different but
1673  // not opposing directions.
1674  TwoFingerSwipe(min_swipe_velocity / 2,
1675                 min_swipe_velocity / 2,
1676                 0,
1677                 min_swipe_velocity * 2);
1678  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SWIPE));
1679  EXPECT_TRUE(GetMostRecentGestureEvent().details.swipe_down());
1680  EXPECT_FALSE(GetMostRecentGestureEvent().details.swipe_right());
1681  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
1682  ResetGestureDetection();
1683
1684  // No swipe in orthogonal directions.
1685  TwoFingerSwipe(min_swipe_velocity * 2, 0, 0, min_swipe_velocity * 7);
1686  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SWIPE));
1687  ResetGestureDetection();
1688
1689  // Three finger swipe in same directions.
1690  ThreeFingerSwipe(min_swipe_velocity * 2,
1691                   0,
1692                   min_swipe_velocity * 3,
1693                   0,
1694                   min_swipe_velocity * 4,
1695                   0);
1696  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SWIPE));
1697  EXPECT_TRUE(GetMostRecentGestureEvent().details.swipe_right());
1698  EXPECT_EQ(3, GetMostRecentGestureEvent().details.touch_points());
1699  ResetGestureDetection();
1700
1701  // No three finger swipe in different directions.
1702  ThreeFingerSwipe(min_swipe_velocity * 2,
1703                   0,
1704                   0,
1705                   min_swipe_velocity * 3,
1706                   min_swipe_velocity * 4,
1707                   0);
1708  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SWIPE));
1709}
1710
1711// Verify that the timer of LONG_PRESS will be cancelled when scrolling begins
1712// so LONG_PRESS and LONG_TAP won't be triggered.
1713TEST_F(GestureProviderTest, GesturesCancelledAfterLongPressCausesLostFocus) {
1714  base::TimeTicks event_time = base::TimeTicks::Now();
1715
1716  MockMotionEvent event =
1717      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
1718  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1719
1720  const base::TimeDelta long_press_timeout =
1721      GetLongPressTimeout() + GetShowPressTimeout() + kOneMicrosecond;
1722  RunTasksAndWait(long_press_timeout);
1723  EXPECT_EQ(ET_GESTURE_LONG_PRESS, GetMostRecentGestureEventType());
1724  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1725
1726  EXPECT_TRUE(CancelActiveTouchSequence());
1727  EXPECT_FALSE(HasDownEvent());
1728
1729  event = ObtainMotionEvent(event_time + long_press_timeout,
1730                            MotionEvent::ACTION_UP);
1731  gesture_provider_->OnTouchEvent(event);
1732  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_TAP));
1733}
1734
1735// Verify that inserting a touch cancel event will trigger proper touch and
1736// gesture sequence cancellation.
1737TEST_F(GestureProviderTest, CancelActiveTouchSequence) {
1738  base::TimeTicks event_time = base::TimeTicks::Now();
1739  int motion_event_id = 0;
1740
1741  EXPECT_FALSE(CancelActiveTouchSequence());
1742  EXPECT_EQ(0U, GetReceivedGestureCount());
1743
1744  MockMotionEvent event =
1745      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
1746  event.SetId(++motion_event_id);
1747  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1748  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1749  EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
1750  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1751
1752  ASSERT_TRUE(CancelActiveTouchSequence());
1753  EXPECT_FALSE(HasDownEvent());
1754
1755  // Subsequent MotionEvent's are dropped until ACTION_DOWN.
1756  event = ObtainMotionEvent(event_time + kOneMicrosecond,
1757                            MotionEvent::ACTION_MOVE);
1758  EXPECT_FALSE(gesture_provider_->OnTouchEvent(event));
1759
1760  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
1761                            MotionEvent::ACTION_UP);
1762  EXPECT_FALSE(gesture_provider_->OnTouchEvent(event));
1763
1764  event = ObtainMotionEvent(event_time + kOneMicrosecond * 3,
1765                            MotionEvent::ACTION_DOWN);
1766  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1767  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1768  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1769}
1770
1771TEST_F(GestureProviderTest, DoubleTapDragZoomCancelledOnSecondaryPointerDown) {
1772  const base::TimeTicks down_time_1 = TimeTicks::Now();
1773  const base::TimeTicks down_time_2 = down_time_1 + GetValidDoubleTapDelay();
1774
1775  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true);
1776
1777  MockMotionEvent event =
1778      ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
1779  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1780  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1781  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1782
1783  event =
1784      ObtainMotionEvent(down_time_1 + kOneMicrosecond, MotionEvent::ACTION_UP);
1785  gesture_provider_->OnTouchEvent(event);
1786  EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
1787  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1788
1789  event = ObtainMotionEvent(down_time_2, MotionEvent::ACTION_DOWN);
1790  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1791  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1792  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1793
1794  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
1795                            MotionEvent::ACTION_MOVE,
1796                            kFakeCoordX,
1797                            kFakeCoordY - 30);
1798  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1799  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
1800  EXPECT_EQ(ET_GESTURE_PINCH_BEGIN, GetMostRecentGestureEventType());
1801  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1802
1803  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
1804                            MotionEvent::ACTION_POINTER_DOWN,
1805                            kFakeCoordX,
1806                            kFakeCoordY - 30,
1807                            kFakeCoordX + 50,
1808                            kFakeCoordY + 50);
1809  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1810  EXPECT_EQ(ET_GESTURE_PINCH_END, GetMostRecentGestureEventType());
1811  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
1812
1813  const size_t gesture_count = GetReceivedGestureCount();
1814  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
1815                            MotionEvent::ACTION_POINTER_UP,
1816                            kFakeCoordX,
1817                            kFakeCoordY - 30,
1818                            kFakeCoordX + 50,
1819                            kFakeCoordY + 50);
1820  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1821  EXPECT_EQ(gesture_count, GetReceivedGestureCount());
1822
1823  event = ObtainMotionEvent(down_time_2 + kOneSecond,
1824                            MotionEvent::ACTION_UP);
1825  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1826  EXPECT_EQ(gesture_count + 1, GetReceivedGestureCount());
1827  EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
1828  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1829}
1830
1831// Verify that gesture begin and gesture end events are dispatched correctly.
1832TEST_F(GestureProviderTest, GestureBeginAndEnd) {
1833  EnableBeginEndTypes();
1834  base::TimeTicks event_time = base::TimeTicks::Now();
1835
1836  EXPECT_EQ(0U, GetReceivedGestureCount());
1837  MockMotionEvent event =
1838      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN, 1, 1);
1839  event.pointer_count = 1;
1840  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1841  EXPECT_EQ(ET_GESTURE_BEGIN, GetReceivedGesture(0).type());
1842  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1843  EXPECT_EQ(2U, GetReceivedGestureCount());
1844  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1845  EXPECT_EQ(1, GetMostRecentGestureEvent().x);
1846  EXPECT_EQ(1, GetMostRecentGestureEvent().y);
1847  EXPECT_EQ(gfx::RectF(1 - kMockTouchRadius,
1848                       1 - kMockTouchRadius,
1849                       kMockTouchRadius * 2,
1850                       kMockTouchRadius * 2),
1851            GetMostRecentGestureEvent().details.bounding_box());
1852
1853  event = ObtainMotionEvent(
1854      event_time, MotionEvent::ACTION_POINTER_DOWN, 1, 1, 2, 2);
1855  event.pointer_count = 2;
1856  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1857  EXPECT_EQ(ET_GESTURE_BEGIN, GetMostRecentGestureEventType());
1858  EXPECT_EQ(3U, GetReceivedGestureCount());
1859  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
1860  EXPECT_EQ(2, GetMostRecentGestureEvent().x);
1861  EXPECT_EQ(2, GetMostRecentGestureEvent().y);
1862
1863  event = ObtainMotionEvent(
1864      event_time, MotionEvent::ACTION_POINTER_DOWN, 1, 1, 2, 2, 3, 3);
1865  event.pointer_count = 3;
1866  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1867  EXPECT_EQ(ET_GESTURE_BEGIN, GetMostRecentGestureEventType());
1868  EXPECT_EQ(4U, GetReceivedGestureCount());
1869  EXPECT_EQ(3, GetMostRecentGestureEvent().details.touch_points());
1870  EXPECT_EQ(3, GetMostRecentGestureEvent().x);
1871  EXPECT_EQ(3, GetMostRecentGestureEvent().y);
1872
1873  event = ObtainMotionEvent(
1874      event_time, MotionEvent::ACTION_POINTER_UP, 1, 1, 2, 2, 3, 3);
1875  event.pointer_count = 2;
1876  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1877  EXPECT_EQ(ET_GESTURE_END, GetMostRecentGestureEventType());
1878  EXPECT_EQ(5U, GetReceivedGestureCount());
1879  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
1880  EXPECT_EQ(1, GetMostRecentGestureEvent().x);
1881  EXPECT_EQ(1, GetMostRecentGestureEvent().y);
1882
1883  event = ObtainMotionEvent(
1884      event_time, MotionEvent::ACTION_POINTER_DOWN, 2, 2, 3, 3, 4, 4);
1885  event.pointer_count = 3;
1886  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1887  EXPECT_EQ(ET_GESTURE_BEGIN, GetMostRecentGestureEventType());
1888  EXPECT_EQ(6U, GetReceivedGestureCount());
1889  EXPECT_EQ(3, GetMostRecentGestureEvent().details.touch_points());
1890  EXPECT_EQ(4, GetMostRecentGestureEvent().x);
1891  EXPECT_EQ(4, GetMostRecentGestureEvent().y);
1892
1893  event = ObtainMotionEvent(
1894      event_time, MotionEvent::ACTION_POINTER_UP, 2, 2, 3, 3, 4, 4);
1895  event.pointer_count = 2;
1896  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1897  EXPECT_EQ(ET_GESTURE_END, GetMostRecentGestureEventType());
1898  EXPECT_EQ(7U, GetReceivedGestureCount());
1899  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
1900  EXPECT_EQ(2, GetMostRecentGestureEvent().x);
1901  EXPECT_EQ(2, GetMostRecentGestureEvent().y);
1902
1903  event =
1904      ObtainMotionEvent(event_time, MotionEvent::ACTION_POINTER_UP, 3, 3, 4, 4);
1905  event.pointer_count = 1;
1906  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1907  EXPECT_EQ(ET_GESTURE_END, GetMostRecentGestureEventType());
1908  EXPECT_EQ(8U, GetReceivedGestureCount());
1909  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1910  EXPECT_EQ(3, GetMostRecentGestureEvent().x);
1911  EXPECT_EQ(3, GetMostRecentGestureEvent().y);
1912
1913
1914  event = ObtainMotionEvent(event_time, MotionEvent::ACTION_UP, 4, 4);
1915  event.pointer_count = 1;
1916  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1917  EXPECT_EQ(ET_GESTURE_END, GetMostRecentGestureEventType());
1918  EXPECT_EQ(9U, GetReceivedGestureCount());
1919  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1920  EXPECT_EQ(4, GetMostRecentGestureEvent().x);
1921  EXPECT_EQ(4, GetMostRecentGestureEvent().y);
1922}
1923
1924// Verify that gesture begin and gesture end events are dispatched correctly
1925// when an ACTION_CANCEL is received.
1926TEST_F(GestureProviderTest, GestureBeginAndEndOnCancel) {
1927  EnableBeginEndTypes();
1928  base::TimeTicks event_time = base::TimeTicks::Now();
1929
1930  EXPECT_EQ(0U, GetReceivedGestureCount());
1931  MockMotionEvent event =
1932      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN, 1, 1);
1933  event.pointer_count = 1;
1934  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1935  EXPECT_EQ(ET_GESTURE_BEGIN, GetReceivedGesture(0).type());
1936  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1937  EXPECT_EQ(2U, GetReceivedGestureCount());
1938  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1939  EXPECT_EQ(gfx::RectF(1 - kMockTouchRadius,
1940                       1 - kMockTouchRadius,
1941                       kMockTouchRadius * 2,
1942                       kMockTouchRadius * 2),
1943            GetMostRecentGestureEvent().details.bounding_box());
1944  EXPECT_EQ(1, GetMostRecentGestureEvent().x);
1945  EXPECT_EQ(1, GetMostRecentGestureEvent().y);
1946
1947  event = ObtainMotionEvent(
1948      event_time, MotionEvent::ACTION_POINTER_DOWN, 1, 1, 2, 2);
1949  event.pointer_count = 2;
1950  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1951  EXPECT_EQ(ET_GESTURE_BEGIN, GetMostRecentGestureEventType());
1952  EXPECT_EQ(3U, GetReceivedGestureCount());
1953  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
1954  EXPECT_EQ(2, GetMostRecentGestureEvent().x);
1955  EXPECT_EQ(2, GetMostRecentGestureEvent().y);
1956
1957
1958  event = ObtainMotionEvent(
1959      event_time, MotionEvent::ACTION_POINTER_DOWN, 1, 1, 2, 2, 3, 3);
1960  event.pointer_count = 3;
1961  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1962  EXPECT_EQ(ET_GESTURE_BEGIN, GetMostRecentGestureEventType());
1963  EXPECT_EQ(4U, GetReceivedGestureCount());
1964  EXPECT_EQ(3, GetMostRecentGestureEvent().details.touch_points());
1965  EXPECT_EQ(3, GetMostRecentGestureEvent().x);
1966  EXPECT_EQ(3, GetMostRecentGestureEvent().y);
1967
1968  event = ObtainMotionEvent(
1969      event_time, MotionEvent::ACTION_CANCEL, 1, 1, 2, 2, 3, 3);
1970  event.pointer_count = 3;
1971  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1972  EXPECT_EQ(7U, GetReceivedGestureCount());
1973  EXPECT_EQ(3, GetReceivedGesture(4).details.touch_points());
1974  EXPECT_EQ(ET_GESTURE_END, GetReceivedGesture(4).type());
1975  EXPECT_EQ(2, GetReceivedGesture(5).details.touch_points());
1976  EXPECT_EQ(ET_GESTURE_END, GetReceivedGesture(5).type());
1977  EXPECT_EQ(1, GetReceivedGesture(6).details.touch_points());
1978  EXPECT_EQ(ET_GESTURE_END, GetReceivedGesture(6).type());
1979  EXPECT_EQ(1, GetReceivedGesture(4).x);
1980  EXPECT_EQ(1, GetReceivedGesture(4).y);
1981  EXPECT_EQ(2, GetReceivedGesture(5).x);
1982  EXPECT_EQ(2, GetReceivedGesture(5).y);
1983  EXPECT_EQ(3, GetReceivedGesture(6).x);
1984  EXPECT_EQ(3, GetReceivedGesture(6).y);
1985}
1986
1987// Test a simple two finger tap
1988TEST_F(GestureProviderTest, TwoFingerTap) {
1989  // The time between ACTION_POINTER_DOWN and ACTION_POINTER_UP must be <= the
1990  // two finger tap delay.
1991  EnableTwoFingerTap(kMaxTwoFingerTapSeparation, base::TimeDelta());
1992  const float scaled_touch_slop = GetTouchSlop();
1993
1994  base::TimeTicks event_time = base::TimeTicks::Now();
1995
1996  MockMotionEvent event =
1997      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN, 0, 0);
1998  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1999
2000  event = ObtainMotionEvent(event_time,
2001                            MotionEvent::ACTION_MOVE,
2002                            0,
2003                            scaled_touch_slop / 2);
2004
2005  event = ObtainMotionEvent(event_time,
2006                            MotionEvent::ACTION_POINTER_DOWN,
2007                            0,
2008                            0,
2009                            kMaxTwoFingerTapSeparation / 2,
2010                            0);
2011  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2012
2013  event =
2014      ObtainMotionEvent(event_time,
2015                        MotionEvent::ACTION_MOVE,
2016                        0,
2017                        -scaled_touch_slop / 2,
2018                        kMaxTwoFingerTapSeparation / 2 + scaled_touch_slop / 2,
2019                        0);
2020  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2021
2022  event = ObtainMotionEvent(event_time,
2023                            MotionEvent::ACTION_POINTER_UP,
2024                            0,
2025                            0,
2026                            kMaxTwoFingerTapSeparation,
2027                            0);
2028  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2029
2030  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetReceivedGesture(0).type());
2031  EXPECT_EQ(ET_GESTURE_SCROLL_BEGIN, GetReceivedGesture(1).type());
2032  EXPECT_EQ(ET_GESTURE_TWO_FINGER_TAP, GetReceivedGesture(2).type());
2033  EXPECT_EQ(3U, GetReceivedGestureCount());
2034
2035  EXPECT_EQ(kMockTouchRadius * 2,
2036            GetReceivedGesture(2).details.first_finger_width());
2037  EXPECT_EQ(kMockTouchRadius * 2,
2038            GetReceivedGesture(2).details.first_finger_height());
2039}
2040
2041// Test preventing a two finger tap via finger movement.
2042TEST_F(GestureProviderTest, TwoFingerTapCancelledByFingerMovement) {
2043  EnableTwoFingerTap(kMaxTwoFingerTapSeparation, base::TimeDelta());
2044  const float scaled_touch_slop = GetTouchSlop();
2045  base::TimeTicks event_time = base::TimeTicks::Now();
2046
2047  MockMotionEvent event = ObtainMotionEvent(
2048      event_time, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
2049  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2050
2051  event = ObtainMotionEvent(event_time,
2052                            MotionEvent::ACTION_POINTER_DOWN,
2053                            kFakeCoordX,
2054                            kFakeCoordY,
2055                            kFakeCoordX,
2056                            kFakeCoordY);
2057  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2058
2059  event = ObtainMotionEvent(event_time,
2060                            MotionEvent::ACTION_MOVE,
2061                            kFakeCoordX,
2062                            kFakeCoordY,
2063                            kFakeCoordX + scaled_touch_slop + 0.1,
2064                            kFakeCoordY);
2065  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2066
2067  event = ObtainMotionEvent(event_time,
2068                            MotionEvent::ACTION_POINTER_UP,
2069                            kFakeCoordX,
2070                            kFakeCoordY,
2071                            kFakeCoordX,
2072                            kFakeCoordY);
2073  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2074
2075  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetReceivedGesture(0).type());
2076  EXPECT_EQ(ET_GESTURE_SCROLL_BEGIN, GetReceivedGesture(1).type());
2077  EXPECT_EQ(2U, GetReceivedGestureCount());
2078}
2079
2080// Test preventing a two finger tap by waiting too long before releasing the
2081// secondary pointer.
2082TEST_F(GestureProviderTest, TwoFingerTapCancelledByDelay) {
2083  base::TimeDelta two_finger_tap_timeout = kOneSecond;
2084  EnableTwoFingerTap(kMaxTwoFingerTapSeparation, two_finger_tap_timeout);
2085  base::TimeTicks event_time = base::TimeTicks::Now();
2086
2087  MockMotionEvent event = ObtainMotionEvent(
2088      event_time, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
2089  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2090
2091  event = ObtainMotionEvent(event_time,
2092                            MotionEvent::ACTION_MOVE,
2093                            kFakeCoordX,
2094                            kFakeCoordY);
2095
2096  event = ObtainMotionEvent(event_time,
2097                            MotionEvent::ACTION_POINTER_DOWN,
2098                            kFakeCoordX,
2099                            kFakeCoordY,
2100                            kFakeCoordX + kMaxTwoFingerTapSeparation / 2,
2101                            kFakeCoordY);
2102  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2103
2104  event = ObtainMotionEvent(event_time + kOneSecond + kOneMicrosecond,
2105                            MotionEvent::ACTION_POINTER_UP,
2106                            kFakeCoordX,
2107                            kFakeCoordY,
2108                            kFakeCoordX + kMaxTwoFingerTapSeparation / 2,
2109                            kFakeCoordY);
2110  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2111
2112  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetReceivedGesture(0).type());
2113  EXPECT_EQ(1U, GetReceivedGestureCount());
2114}
2115
2116// Test preventing a two finger tap by pressing the secondary pointer too far
2117// from the first
2118TEST_F(GestureProviderTest, TwoFingerTapCancelledByDistanceBetweenPointers) {
2119  EnableTwoFingerTap(kMaxTwoFingerTapSeparation, base::TimeDelta());
2120  base::TimeTicks event_time = base::TimeTicks::Now();
2121
2122  MockMotionEvent event = ObtainMotionEvent(
2123      event_time, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
2124  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2125
2126  event = ObtainMotionEvent(event_time,
2127                            MotionEvent::ACTION_POINTER_DOWN,
2128                            kFakeCoordX,
2129                            kFakeCoordY,
2130                            kFakeCoordX + kMaxTwoFingerTapSeparation,
2131                            kFakeCoordY);
2132  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2133
2134  event = ObtainMotionEvent(event_time,
2135                            MotionEvent::ACTION_POINTER_UP,
2136                            kFakeCoordX,
2137                            kFakeCoordY,
2138                            kFakeCoordX + kMaxTwoFingerTapSeparation,
2139                            kFakeCoordY);
2140  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2141
2142  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetReceivedGesture(0).type());
2143  EXPECT_EQ(1U, GetReceivedGestureCount());
2144}
2145
2146// Verify that pinch zoom only sends updates which exceed the
2147// min_pinch_update_span_delta.
2148TEST_F(GestureProviderTest, PinchZoomWithThreshold) {
2149  const float kMinPinchUpdateDistance = 5;
2150
2151  base::TimeTicks event_time = base::TimeTicks::Now();
2152  const float touch_slop = GetTouchSlop();
2153
2154  SetMinPinchUpdateSpanDelta(kMinPinchUpdateDistance);
2155  gesture_provider_->SetDoubleTapSupportForPageEnabled(false);
2156  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true);
2157  gesture_provider_->SetMultiTouchZoomSupportEnabled(true);
2158
2159  int secondary_coord_x = kFakeCoordX + 20 * touch_slop;
2160  int secondary_coord_y = kFakeCoordY + 20 * touch_slop;
2161
2162  // First finger down.
2163  MockMotionEvent event =
2164      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
2165  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2166  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
2167  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
2168
2169  // Second finger down.
2170  event = ObtainMotionEvent(event_time,
2171                            MotionEvent::ACTION_POINTER_DOWN,
2172                            kFakeCoordX,
2173                            kFakeCoordY,
2174                            secondary_coord_x,
2175                            secondary_coord_y);
2176
2177  gesture_provider_->OnTouchEvent(event);
2178  EXPECT_EQ(1U, GetReceivedGestureCount());
2179  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
2180
2181  // Move second finger.
2182  secondary_coord_x += 5 * touch_slop;
2183  secondary_coord_y += 5 * touch_slop;
2184  event = ObtainMotionEvent(event_time,
2185                            MotionEvent::ACTION_MOVE,
2186                            kFakeCoordX,
2187                            kFakeCoordY,
2188                            secondary_coord_x,
2189                            secondary_coord_y);
2190
2191  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2192  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
2193  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_PINCH_BEGIN));
2194  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_UPDATE));
2195  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
2196  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_UPDATE));
2197
2198  // Small move, shouldn't trigger pinch.
2199  event = ObtainMotionEvent(event_time,
2200                            MotionEvent::ACTION_MOVE,
2201                            kFakeCoordX,
2202                            kFakeCoordY,
2203                            secondary_coord_x + kMinPinchUpdateDistance,
2204                            secondary_coord_y);
2205
2206  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2207  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_UPDATE));
2208  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
2209
2210  // Small move, but combined with the previous move, should trigger pinch. We
2211  // need to overshoot kMinPinchUpdateDistance by a fair bit, as the span
2212  // calculation factors in touch radius.
2213  const float kOvershootMinPinchUpdateDistance = 3;
2214  event = ObtainMotionEvent(event_time,
2215                            MotionEvent::ACTION_MOVE,
2216                            kFakeCoordX,
2217                            kFakeCoordY,
2218                            secondary_coord_x + kMinPinchUpdateDistance +
2219                                kOvershootMinPinchUpdateDistance,
2220                            secondary_coord_y);
2221
2222  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2223  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_PINCH_UPDATE));
2224  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
2225}
2226
2227// Verify that the min gesture bound setting is honored.
2228TEST_F(GestureProviderTest, MinGestureBoundsLength) {
2229  const float kMinGestureBoundsLength = 10.f * kMockTouchRadius;
2230  SetMinGestureBoundsLength(kMinGestureBoundsLength);
2231  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false);
2232
2233  base::TimeTicks event_time = base::TimeTicks::Now();
2234  MockMotionEvent event =
2235      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
2236  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2237
2238  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
2239  EXPECT_EQ(kMinGestureBoundsLength,
2240            GetMostRecentGestureEvent().details.bounding_box_f().width());
2241  EXPECT_EQ(kMinGestureBoundsLength,
2242            GetMostRecentGestureEvent().details.bounding_box_f().height());
2243
2244  event =
2245      ObtainMotionEvent(event_time + kOneMicrosecond, MotionEvent::ACTION_UP);
2246  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2247  EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
2248  EXPECT_EQ(kMinGestureBoundsLength,
2249            GetMostRecentGestureEvent().details.bounding_box_f().width());
2250  EXPECT_EQ(kMinGestureBoundsLength,
2251            GetMostRecentGestureEvent().details.bounding_box_f().height());
2252}
2253
2254}  // namespace ui
2255