gesture_provider_unittest.cc revision 6d86b77056ed63eb6871182f42a9fd5f07550f90
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  const float raw_offset_x = 17.3f;
740  const float raw_offset_y = 13.7f;
741
742  const base::TimeTicks event_time = TimeTicks::Now();
743
744  MockMotionEvent event =
745      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
746  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
747
748  // Move twice so that we get two ET_GESTURE_SCROLL_UPDATE events and can
749  // compare the relative and absolute coordinates.
750  event = ObtainMotionEvent(event_time + kOneMicrosecond,
751                            MotionEvent::ACTION_MOVE,
752                            kFakeCoordX - delta_x / 2,
753                            kFakeCoordY - delta_y / 2);
754  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
755
756  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
757                            MotionEvent::ACTION_MOVE,
758                            kFakeCoordX - delta_x,
759                            kFakeCoordY - delta_y);
760  event.SetRawOffset(raw_offset_x, raw_offset_y);
761  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
762
763  // Make sure the reported gesture event has all the expected details.
764  ASSERT_LT(0U, GetReceivedGestureCount());
765  GestureEventData gesture = GetMostRecentGestureEvent();
766  EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, gesture.type());
767  EXPECT_EQ(event_time + kOneMicrosecond * 2, gesture.time);
768  EXPECT_EQ(kFakeCoordX - delta_x, gesture.x);
769  EXPECT_EQ(kFakeCoordY - delta_y, gesture.y);
770  EXPECT_EQ(kFakeCoordX - delta_x + raw_offset_x, gesture.raw_x);
771  EXPECT_EQ(kFakeCoordY - delta_y + raw_offset_y, gesture.raw_y);
772  EXPECT_EQ(1, gesture.details.touch_points());
773
774  // No horizontal delta because of snapping.
775  EXPECT_EQ(0, gesture.details.scroll_x());
776  EXPECT_EQ(-delta_y / 2, gesture.details.scroll_y());
777}
778
779// Verify that fractional scroll deltas are rounded as expected and that
780// fractional scrolling doesn't break scroll snapping.
781TEST_F(GestureProviderTest, FractionalScroll) {
782  const float delta_x = 0.4f;
783  const float delta_y = 5.2f;
784
785  const base::TimeTicks event_time = TimeTicks::Now();
786
787  MockMotionEvent event =
788      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
789  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
790
791  // Skip past the touch slop and move back.
792  event = ObtainMotionEvent(event_time,
793                            MotionEvent::ACTION_MOVE,
794                            kFakeCoordX,
795                            kFakeCoordY + 100);
796  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
797  event = ObtainMotionEvent(event_time,
798                            MotionEvent::ACTION_MOVE);
799  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
800
801  // Now move up slowly, mostly vertically but with a (fractional) bit of
802  // horizontal motion.
803  for(int i = 1; i <= 10; i++) {
804    event = ObtainMotionEvent(event_time + kOneMicrosecond * i,
805                              MotionEvent::ACTION_MOVE,
806                              kFakeCoordX + delta_x * i,
807                              kFakeCoordY + delta_y * i);
808    EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
809
810    ASSERT_LT(0U, GetReceivedGestureCount());
811    GestureEventData gesture = GetMostRecentGestureEvent();
812    EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, gesture.type());
813    EXPECT_EQ(event_time + kOneMicrosecond * i, gesture.time);
814    EXPECT_EQ(1, gesture.details.touch_points());
815
816    // Verify that the event co-ordinates are still the precise values we
817    // supplied.
818    EXPECT_EQ(kFakeCoordX + delta_x * i, gesture.x);
819    EXPECT_EQ(kFakeCoordY + delta_y * i, gesture.y);
820
821    // Verify that we're scrolling vertically by the expected amount
822    // (modulo rounding).
823    EXPECT_GE(gesture.details.scroll_y(), (int)delta_y);
824    EXPECT_LE(gesture.details.scroll_y(), ((int)delta_y) + 1);
825
826    // And that there has been no horizontal motion at all.
827    EXPECT_EQ(0, gesture.details.scroll_x());
828  }
829}
830
831// Generate a scroll gesture and verify that the resulting scroll begin event
832// has the expected hint values.
833TEST_F(GestureProviderTest, ScrollBeginValues) {
834  const float delta_x = 13;
835  const float delta_y = 89;
836
837  const base::TimeTicks event_time = TimeTicks::Now();
838
839  MockMotionEvent event =
840      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
841  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
842
843  // Move twice such that the first event isn't sufficient to start
844  // scrolling on it's own.
845  event = ObtainMotionEvent(event_time + kOneMicrosecond,
846                            MotionEvent::ACTION_MOVE,
847                            kFakeCoordX + 2,
848                            kFakeCoordY + 1);
849  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
850  EXPECT_FALSE(gesture_provider_->IsScrollInProgress());
851
852  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
853                            MotionEvent::ACTION_MOVE,
854                            kFakeCoordX + delta_x,
855                            kFakeCoordY + delta_y);
856  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
857  EXPECT_TRUE(gesture_provider_->IsScrollInProgress());
858
859  const GestureEventData* scroll_begin_gesture = GetActiveScrollBeginEvent();
860  ASSERT_TRUE(!!scroll_begin_gesture);
861  EXPECT_EQ(delta_x, scroll_begin_gesture->details.scroll_x_hint());
862  EXPECT_EQ(delta_y, scroll_begin_gesture->details.scroll_y_hint());
863}
864
865TEST_F(GestureProviderTest, LongPressAndTapCancelledWhenScrollBegins) {
866  base::TimeTicks event_time = base::TimeTicks::Now();
867
868  MockMotionEvent event =
869      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
870  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
871  event = ObtainMotionEvent(event_time + kOneMicrosecond,
872                            MotionEvent::ACTION_MOVE,
873                            kFakeCoordX * 5,
874                            kFakeCoordY * 5);
875  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
876  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
877                            MotionEvent::ACTION_MOVE,
878                            kFakeCoordX * 10,
879                            kFakeCoordY * 10);
880  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
881
882  const base::TimeDelta long_press_timeout =
883      GetLongPressTimeout() + GetShowPressTimeout() + kOneMicrosecond;
884  RunTasksAndWait(long_press_timeout);
885
886  // No LONG_TAP as the LONG_PRESS timer is cancelled.
887  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_PRESS));
888  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_TAP));
889}
890
891// Verify that LONG_TAP is triggered after LONG_PRESS followed by an UP.
892TEST_F(GestureProviderTest, GestureLongTap) {
893  base::TimeTicks event_time = base::TimeTicks::Now();
894
895  MockMotionEvent event =
896      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
897  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
898
899  const base::TimeDelta long_press_timeout =
900      GetLongPressTimeout() + GetShowPressTimeout() + kOneMicrosecond;
901  RunTasksAndWait(long_press_timeout);
902
903  EXPECT_EQ(ET_GESTURE_LONG_PRESS, GetMostRecentGestureEventType());
904  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
905  EXPECT_EQ(BoundsForSingleMockTouchAtLocation(kFakeCoordX, kFakeCoordY),
906            GetMostRecentGestureEvent().details.bounding_box());
907
908  event = ObtainMotionEvent(event_time + kOneSecond, MotionEvent::ACTION_UP);
909  gesture_provider_->OnTouchEvent(event);
910  EXPECT_EQ(ET_GESTURE_LONG_TAP, GetMostRecentGestureEventType());
911  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
912  EXPECT_EQ(BoundsForSingleMockTouchAtLocation(kFakeCoordX, kFakeCoordY),
913            GetMostRecentGestureEvent().details.bounding_box());
914}
915
916TEST_F(GestureProviderTest, GestureLongPressDoesNotPreventScrolling) {
917  base::TimeTicks event_time = base::TimeTicks::Now();
918
919  MockMotionEvent event =
920      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
921  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
922
923  const base::TimeDelta long_press_timeout =
924      GetLongPressTimeout() + GetShowPressTimeout() + kOneMicrosecond;
925  RunTasksAndWait(long_press_timeout);
926
927  EXPECT_EQ(ET_GESTURE_LONG_PRESS, GetMostRecentGestureEventType());
928  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
929  event = ObtainMotionEvent(event_time + long_press_timeout,
930                            MotionEvent::ACTION_MOVE,
931                            kFakeCoordX + 100,
932                            kFakeCoordY + 100);
933  gesture_provider_->OnTouchEvent(event);
934
935  EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
936  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
937  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
938
939  event = ObtainMotionEvent(event_time + long_press_timeout,
940                            MotionEvent::ACTION_UP);
941  gesture_provider_->OnTouchEvent(event);
942  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_TAP));
943}
944
945TEST_F(GestureProviderTest, NoGestureLongPressDuringDoubleTap) {
946  base::TimeTicks event_time = base::TimeTicks::Now();
947  int motion_event_id = 0;
948
949  MockMotionEvent event = ObtainMotionEvent(
950      event_time, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
951  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
952
953  event = ObtainMotionEvent(event_time + kOneMicrosecond,
954                            MotionEvent::ACTION_UP,
955                            kFakeCoordX,
956                            kFakeCoordY);
957  gesture_provider_->OnTouchEvent(event);
958  EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
959  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
960
961  event_time += GetValidDoubleTapDelay();
962  event = ObtainMotionEvent(event_time,
963                            MotionEvent::ACTION_DOWN,
964                            kFakeCoordX,
965                            kFakeCoordY);
966  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
967  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
968  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
969  EXPECT_TRUE(gesture_provider_->IsDoubleTapInProgress());
970
971  const base::TimeDelta long_press_timeout =
972      GetLongPressTimeout() + GetShowPressTimeout() + kOneMicrosecond;
973  RunTasksAndWait(long_press_timeout);
974  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_PRESS));
975
976  event = ObtainMotionEvent(event_time + long_press_timeout,
977                            MotionEvent::ACTION_MOVE,
978                            kFakeCoordX + 20,
979                            kFakeCoordY + 20);
980  event.SetId(++motion_event_id);
981
982  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
983  EXPECT_EQ(ET_GESTURE_PINCH_BEGIN, GetMostRecentGestureEventType());
984  EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
985  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
986  EXPECT_TRUE(gesture_provider_->IsDoubleTapInProgress());
987
988  event = ObtainMotionEvent(event_time + long_press_timeout + kOneMicrosecond,
989                            MotionEvent::ACTION_UP,
990                            kFakeCoordX,
991                            kFakeCoordY + 1);
992  event.SetId(++motion_event_id);
993  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
994  EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
995  EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
996  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
997  EXPECT_FALSE(gesture_provider_->IsDoubleTapInProgress());
998}
999
1000// Verify that the touch slop region is removed from the first scroll delta to
1001// avoid a jump when starting to scroll.
1002TEST_F(GestureProviderTest, TouchSlopRemovedFromScroll) {
1003  const float touch_slop = GetTouchSlop();
1004  const float scroll_delta = 5;
1005
1006  base::TimeTicks event_time = base::TimeTicks::Now();
1007
1008  MockMotionEvent event =
1009      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
1010  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1011
1012  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
1013                            MotionEvent::ACTION_MOVE,
1014                            kFakeCoordX,
1015                            kFakeCoordY + touch_slop + scroll_delta);
1016  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1017
1018  EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
1019  GestureEventData gesture = GetMostRecentGestureEvent();
1020  EXPECT_EQ(0, gesture.details.scroll_x());
1021  EXPECT_EQ(scroll_delta, gesture.details.scroll_y());
1022  EXPECT_EQ(1, gesture.details.touch_points());
1023}
1024
1025// Verify that movement within the touch slop region does not generate a scroll,
1026// and that the slop region is correct even when using fractional coordinates.
1027TEST_F(GestureProviderTest, NoScrollWithinTouchSlop) {
1028  const float touch_slop = GetTouchSlop();
1029  const float scale_factor = 2.5f;
1030  const int touch_slop_pixels = static_cast<int>(scale_factor * touch_slop);
1031
1032  base::TimeTicks event_time = base::TimeTicks::Now();
1033
1034  MockMotionEvent event =
1035      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
1036  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1037
1038  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
1039                            MotionEvent::ACTION_MOVE,
1040                            kFakeCoordX + touch_slop_pixels / scale_factor,
1041                            kFakeCoordY);
1042  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1043  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
1044
1045  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
1046                            MotionEvent::ACTION_MOVE,
1047                            kFakeCoordX,
1048                            kFakeCoordY + touch_slop_pixels / scale_factor);
1049  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1050  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
1051
1052  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
1053                            MotionEvent::ACTION_MOVE,
1054                            kFakeCoordX - touch_slop_pixels / scale_factor,
1055                            kFakeCoordY);
1056  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1057  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
1058
1059  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
1060                            MotionEvent::ACTION_MOVE,
1061                            kFakeCoordX,
1062                            kFakeCoordY - touch_slop_pixels / scale_factor);
1063  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1064  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
1065
1066  event =
1067      ObtainMotionEvent(event_time + kOneMicrosecond * 2,
1068                        MotionEvent::ACTION_MOVE,
1069                        kFakeCoordX,
1070                        kFakeCoordY + (touch_slop_pixels + 1.f) / scale_factor);
1071  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1072  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
1073}
1074
1075TEST_F(GestureProviderTest, NoDoubleTapWhenTooRapid) {
1076  base::TimeTicks event_time = base::TimeTicks::Now();
1077
1078  MockMotionEvent event =
1079      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
1080  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1081
1082  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1083  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1084
1085  event = ObtainMotionEvent(event_time + kOneMicrosecond,
1086                            MotionEvent::ACTION_UP,
1087                            kFakeCoordX,
1088                            kFakeCoordY);
1089  gesture_provider_->OnTouchEvent(event);
1090  EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
1091  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1092
1093  // If the second tap follows the first in too short a time span, no double-tap
1094  // will occur.
1095  event_time += (GetDoubleTapMinTime() / 2);
1096  event = ObtainMotionEvent(event_time,
1097                            MotionEvent::ACTION_DOWN,
1098                            kFakeCoordX,
1099                            kFakeCoordY);
1100  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1101  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1102  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1103
1104  event = ObtainMotionEvent(event_time + kOneMicrosecond,
1105                            MotionEvent::ACTION_UP,
1106                            kFakeCoordX,
1107                            kFakeCoordY);
1108  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1109  EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
1110}
1111
1112TEST_F(GestureProviderTest, NoDoubleTapWhenExplicitlyDisabled) {
1113  // Ensure that double-tap gestures can be disabled.
1114  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false);
1115
1116  base::TimeTicks event_time = base::TimeTicks::Now();
1117  MockMotionEvent event = ObtainMotionEvent(
1118      event_time, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
1119  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1120  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1121
1122  event = ObtainMotionEvent(event_time + kOneMicrosecond,
1123                            MotionEvent::ACTION_UP,
1124                            kFakeCoordX,
1125                            kFakeCoordY);
1126  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1127  EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
1128
1129  event_time += GetValidDoubleTapDelay();
1130  event = ObtainMotionEvent(event_time,
1131                            MotionEvent::ACTION_DOWN,
1132                            kFakeCoordX,
1133                            kFakeCoordY);
1134  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1135  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1136
1137  event = ObtainMotionEvent(event_time + kOneMicrosecond,
1138                            MotionEvent::ACTION_UP,
1139                            kFakeCoordX,
1140                            kFakeCoordY);
1141  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1142  EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
1143
1144  // Ensure that double-tap gestures can be interrupted.
1145  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true);
1146
1147  event_time = base::TimeTicks::Now();
1148  event = ObtainMotionEvent(
1149      event_time, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
1150  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1151  EXPECT_EQ(5U, GetReceivedGestureCount());
1152
1153  event = ObtainMotionEvent(event_time + kOneMicrosecond,
1154                            MotionEvent::ACTION_UP,
1155                            kFakeCoordX,
1156                            kFakeCoordY);
1157  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1158  EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
1159
1160  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false);
1161  EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
1162
1163  // Ensure that double-tap gestures can be resumed.
1164  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true);
1165
1166  event_time += GetValidDoubleTapDelay();
1167  event = ObtainMotionEvent(event_time,
1168                            MotionEvent::ACTION_DOWN,
1169                            kFakeCoordX,
1170                            kFakeCoordY);
1171  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1172  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1173
1174  event = ObtainMotionEvent(event_time + kOneMicrosecond,
1175                            MotionEvent::ACTION_UP,
1176                            kFakeCoordX,
1177                            kFakeCoordY);
1178  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1179  EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
1180
1181  event_time += GetValidDoubleTapDelay();
1182  event = ObtainMotionEvent(event_time,
1183                            MotionEvent::ACTION_DOWN,
1184                            kFakeCoordX,
1185                            kFakeCoordY);
1186  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1187  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1188
1189  event = ObtainMotionEvent(event_time + kOneMicrosecond,
1190                            MotionEvent::ACTION_UP,
1191                            kFakeCoordX,
1192                            kFakeCoordY);
1193  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1194  EXPECT_EQ(ET_GESTURE_DOUBLE_TAP, GetMostRecentGestureEventType());
1195}
1196
1197TEST_F(GestureProviderTest, NoDelayedTapWhenDoubleTapSupportToggled) {
1198  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true);
1199
1200  base::TimeTicks event_time = base::TimeTicks::Now();
1201  MockMotionEvent event = ObtainMotionEvent(
1202      event_time, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
1203  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1204  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1205  EXPECT_EQ(1U, GetReceivedGestureCount());
1206
1207  event = ObtainMotionEvent(event_time + kOneMicrosecond,
1208                            MotionEvent::ACTION_UP,
1209                            kFakeCoordX,
1210                            kFakeCoordY);
1211  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1212  EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
1213  EXPECT_EQ(2U, GetReceivedGestureCount());
1214
1215  // Disabling double-tap during the tap timeout should flush the delayed tap.
1216  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false);
1217  EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
1218  EXPECT_EQ(3U, GetReceivedGestureCount());
1219
1220  // No further timeout gestures should arrive.
1221  const base::TimeDelta long_press_timeout =
1222      GetLongPressTimeout() + GetShowPressTimeout() + kOneMicrosecond;
1223  RunTasksAndWait(long_press_timeout);
1224  EXPECT_EQ(3U, GetReceivedGestureCount());
1225}
1226
1227TEST_F(GestureProviderTest, NoDoubleTapDragZoomWhenDisabledOnPlatform) {
1228  const base::TimeTicks down_time_1 = TimeTicks::Now();
1229  const base::TimeTicks down_time_2 = down_time_1 + GetValidDoubleTapDelay();
1230
1231  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false);
1232
1233  MockMotionEvent event =
1234      ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
1235  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1236
1237  event = ObtainMotionEvent(down_time_1 + kOneMicrosecond,
1238                            MotionEvent::ACTION_UP,
1239                            kFakeCoordX,
1240                            kFakeCoordY);
1241  gesture_provider_->OnTouchEvent(event);
1242
1243  event = ObtainMotionEvent(
1244      down_time_2, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
1245  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1246
1247  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
1248                            MotionEvent::ACTION_MOVE,
1249                            kFakeCoordX,
1250                            kFakeCoordY + 100);
1251
1252  // The move should become a scroll, as doubletap drag zoom is disabled.
1253  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1254  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
1255  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_BEGIN));
1256
1257  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
1258                            MotionEvent::ACTION_MOVE,
1259                            kFakeCoordX,
1260                            kFakeCoordY + 200);
1261  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1262  EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
1263  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1264  EXPECT_EQ(down_time_2 + kOneMicrosecond * 2,
1265            GetMostRecentGestureEvent().time);
1266  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_UPDATE));
1267
1268  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
1269                            MotionEvent::ACTION_UP,
1270                            kFakeCoordX,
1271                            kFakeCoordY + 200);
1272  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1273  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_END));
1274}
1275
1276// Verify that double tap drag zoom feature is not invoked when the gesture
1277// handler is told to disable double tap gesture detection.
1278// The second tap sequence should be treated just as the first would be.
1279TEST_F(GestureProviderTest, NoDoubleTapDragZoomWhenDisabledOnPage) {
1280  const base::TimeTicks down_time_1 = TimeTicks::Now();
1281  const base::TimeTicks down_time_2 = down_time_1 + GetValidDoubleTapDelay();
1282
1283  gesture_provider_->SetDoubleTapSupportForPageEnabled(false);
1284
1285  MockMotionEvent event =
1286      ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
1287  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1288
1289  event = ObtainMotionEvent(down_time_1 + kOneMicrosecond,
1290                            MotionEvent::ACTION_UP,
1291                            kFakeCoordX,
1292                            kFakeCoordY);
1293  gesture_provider_->OnTouchEvent(event);
1294
1295  event = ObtainMotionEvent(
1296      down_time_2, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
1297  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1298
1299  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
1300                            MotionEvent::ACTION_MOVE,
1301                            kFakeCoordX,
1302                            kFakeCoordY + 100);
1303
1304  // The move should become a scroll, as double tap drag zoom is disabled.
1305  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1306  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
1307  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_BEGIN));
1308
1309  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
1310                            MotionEvent::ACTION_MOVE,
1311                            kFakeCoordX,
1312                            kFakeCoordY + 200);
1313  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1314  EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
1315  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1316  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_UPDATE));
1317
1318  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
1319                            MotionEvent::ACTION_UP,
1320                            kFakeCoordX,
1321                            kFakeCoordY + 200);
1322  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1323  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_END));
1324}
1325
1326// Verify that updating double tap support during a double tap drag zoom
1327// disables double tap detection after the gesture has ended.
1328TEST_F(GestureProviderTest, FixedPageScaleDuringDoubleTapDragZoom) {
1329  base::TimeTicks down_time_1 = TimeTicks::Now();
1330  base::TimeTicks down_time_2 = down_time_1 + GetValidDoubleTapDelay();
1331
1332  gesture_provider_->SetDoubleTapSupportForPageEnabled(true);
1333  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true);
1334
1335  // Start a double-tap drag gesture.
1336  MockMotionEvent event =
1337      ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
1338  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1339  event = ObtainMotionEvent(down_time_1 + kOneMicrosecond,
1340                            MotionEvent::ACTION_UP,
1341                            kFakeCoordX,
1342                            kFakeCoordY);
1343  gesture_provider_->OnTouchEvent(event);
1344  event = ObtainMotionEvent(
1345      down_time_2, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
1346  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1347  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
1348                            MotionEvent::ACTION_MOVE,
1349                            kFakeCoordX,
1350                            kFakeCoordY + 100);
1351  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1352  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
1353  EXPECT_EQ(ET_GESTURE_PINCH_BEGIN, GetMostRecentGestureEventType());
1354  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1355
1356  // Simulate setting a fixed page scale (or a mobile viewport);
1357  // this should not disrupt the current double-tap gesture.
1358  gesture_provider_->SetDoubleTapSupportForPageEnabled(false);
1359
1360  // Double tap zoom updates should continue.
1361  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
1362                            MotionEvent::ACTION_MOVE,
1363                            kFakeCoordX,
1364                            kFakeCoordY + 200);
1365  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1366  EXPECT_EQ(ET_GESTURE_PINCH_UPDATE, GetMostRecentGestureEventType());
1367  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1368  EXPECT_LT(1.f, GetMostRecentGestureEvent().details.scale());
1369  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
1370                            MotionEvent::ACTION_UP,
1371                            kFakeCoordX,
1372                            kFakeCoordY + 200);
1373  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1374  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_PINCH_END));
1375  EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
1376  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1377
1378  // The double-tap gesture has finished, but the page scale is fixed.
1379  // The same event sequence should not generate any double tap getsures.
1380  gestures_.clear();
1381  down_time_1 += kOneMicrosecond * 40;
1382  down_time_2 += kOneMicrosecond * 40;
1383
1384  // Start a double-tap drag gesture.
1385  event = ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
1386  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1387  event = ObtainMotionEvent(down_time_1 + kOneMicrosecond,
1388                            MotionEvent::ACTION_UP,
1389                            kFakeCoordX,
1390                            kFakeCoordY);
1391  gesture_provider_->OnTouchEvent(event);
1392  event = ObtainMotionEvent(
1393      down_time_2, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
1394  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1395  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
1396                            MotionEvent::ACTION_MOVE,
1397                            kFakeCoordX,
1398                            kFakeCoordY + 100);
1399  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1400  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
1401  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_BEGIN));
1402
1403  // Double tap zoom updates should not be sent.
1404  // Instead, the second tap drag becomes a scroll gesture sequence.
1405  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
1406                            MotionEvent::ACTION_MOVE,
1407                            kFakeCoordX,
1408                            kFakeCoordY + 200);
1409  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1410  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_UPDATE));
1411  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_UPDATE));
1412  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
1413                            MotionEvent::ACTION_UP,
1414                            kFakeCoordX,
1415                            kFakeCoordY + 200);
1416  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1417  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_END));
1418}
1419
1420// Verify that pinch zoom sends the proper event sequence.
1421TEST_F(GestureProviderTest, PinchZoom) {
1422  base::TimeTicks event_time = base::TimeTicks::Now();
1423  const float touch_slop = GetTouchSlop();
1424  const float raw_offset_x = 3.2f;
1425  const float raw_offset_y = 4.3f;
1426  int motion_event_id = 0;
1427
1428  gesture_provider_->SetDoubleTapSupportForPageEnabled(false);
1429  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true);
1430  gesture_provider_->SetMultiTouchZoomSupportEnabled(true);
1431
1432  int secondary_coord_x = kFakeCoordX + 20 * touch_slop;
1433  int secondary_coord_y = kFakeCoordY + 20 * touch_slop;
1434
1435  MockMotionEvent event =
1436      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
1437  event.SetId(++motion_event_id);
1438  event.SetRawOffset(raw_offset_x, raw_offset_y);
1439  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1440  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1441  EXPECT_EQ(kFakeCoordX, GetMostRecentGestureEvent().x);
1442  EXPECT_EQ(kFakeCoordY, GetMostRecentGestureEvent().y);
1443  EXPECT_EQ(kFakeCoordX + raw_offset_x, GetMostRecentGestureEvent().raw_x);
1444  EXPECT_EQ(kFakeCoordY + raw_offset_y, GetMostRecentGestureEvent().raw_y);
1445  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1446  EXPECT_EQ(BoundsForSingleMockTouchAtLocation(kFakeCoordX, kFakeCoordY),
1447            GetMostRecentGestureEvent().details.bounding_box());
1448
1449  // Toggling double-tap support should not take effect until the next sequence.
1450  gesture_provider_->SetDoubleTapSupportForPageEnabled(true);
1451
1452  event = ObtainMotionEvent(event_time,
1453                            MotionEvent::ACTION_POINTER_DOWN,
1454                            kFakeCoordX,
1455                            kFakeCoordY,
1456                            secondary_coord_x,
1457                            secondary_coord_y);
1458  event.SetId(++motion_event_id);
1459  event.SetRawOffset(raw_offset_x, raw_offset_y);
1460
1461  gesture_provider_->OnTouchEvent(event);
1462  EXPECT_EQ(1U, GetReceivedGestureCount());
1463  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1464  EXPECT_EQ(BoundsForSingleMockTouchAtLocation(kFakeCoordX, kFakeCoordY),
1465            GetMostRecentGestureEvent().details.bounding_box());
1466
1467  secondary_coord_x += 5 * touch_slop;
1468  secondary_coord_y += 5 * touch_slop;
1469  event = ObtainMotionEvent(event_time,
1470                            MotionEvent::ACTION_MOVE,
1471                            kFakeCoordX,
1472                            kFakeCoordY,
1473                            secondary_coord_x,
1474                            secondary_coord_y);
1475  event.SetId(++motion_event_id);
1476  event.SetRawOffset(raw_offset_x, raw_offset_y);
1477
1478  // Toggling double-tap support should not take effect until the next sequence.
1479  gesture_provider_->SetDoubleTapSupportForPageEnabled(false);
1480
1481  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1482  EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
1483  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
1484  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_PINCH_BEGIN));
1485  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
1486  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_UPDATE));
1487
1488  EXPECT_EQ((kFakeCoordX + secondary_coord_x) / 2, GetReceivedGesture(3).x);
1489  EXPECT_EQ((kFakeCoordY + secondary_coord_y) / 2, GetReceivedGesture(3).y);
1490  EXPECT_EQ((kFakeCoordX + secondary_coord_x) / 2 + raw_offset_x,
1491            GetReceivedGesture(3).raw_x);
1492  EXPECT_EQ((kFakeCoordY + secondary_coord_y) / 2 + raw_offset_y,
1493            GetReceivedGesture(3).raw_y);
1494
1495  EXPECT_EQ(
1496      gfx::RectF(kFakeCoordX - kMockTouchRadius,
1497                 kFakeCoordY - kMockTouchRadius,
1498                 secondary_coord_x - kFakeCoordX + kMockTouchRadius * 2,
1499                 secondary_coord_y - kFakeCoordY + kMockTouchRadius * 2),
1500      GetMostRecentGestureEvent().details.bounding_box());
1501
1502  secondary_coord_x += 2 * touch_slop;
1503  secondary_coord_y += 2 * touch_slop;
1504  event = ObtainMotionEvent(event_time,
1505                            MotionEvent::ACTION_MOVE,
1506                            kFakeCoordX,
1507                            kFakeCoordY,
1508                            secondary_coord_x,
1509                            secondary_coord_y);
1510  event.SetId(++motion_event_id);
1511
1512  // Toggling double-tap support should not take effect until the next sequence.
1513  gesture_provider_->SetDoubleTapSupportForPageEnabled(true);
1514
1515  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1516  EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
1517  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_UPDATE));
1518  EXPECT_EQ(ET_GESTURE_PINCH_UPDATE, GetMostRecentGestureEventType());
1519  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
1520  EXPECT_LT(1.f, GetMostRecentGestureEvent().details.scale());
1521  EXPECT_EQ(
1522      gfx::RectF(kFakeCoordX - kMockTouchRadius,
1523                 kFakeCoordY - kMockTouchRadius,
1524                 secondary_coord_x - kFakeCoordX + kMockTouchRadius * 2,
1525                 secondary_coord_y - kFakeCoordY + kMockTouchRadius * 2),
1526      GetMostRecentGestureEvent().details.bounding_box());
1527
1528  event = ObtainMotionEvent(event_time,
1529                            MotionEvent::ACTION_POINTER_UP,
1530                            kFakeCoordX,
1531                            kFakeCoordY,
1532                            secondary_coord_x,
1533                            secondary_coord_y);
1534  event.SetId(++motion_event_id);
1535
1536  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1537  EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
1538  EXPECT_EQ(ET_GESTURE_PINCH_END, GetMostRecentGestureEventType());
1539  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
1540  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SCROLL_END));
1541  EXPECT_EQ(
1542      gfx::RectF(kFakeCoordX - kMockTouchRadius,
1543                 kFakeCoordY - kMockTouchRadius,
1544                 secondary_coord_x - kFakeCoordX + kMockTouchRadius * 2,
1545                 secondary_coord_y - kFakeCoordY + kMockTouchRadius * 2),
1546      GetMostRecentGestureEvent().details.bounding_box());
1547
1548  event = ObtainMotionEvent(event_time, MotionEvent::ACTION_UP);
1549  gesture_provider_->OnTouchEvent(event);
1550  EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
1551  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1552  EXPECT_EQ(gfx::RectF(kFakeCoordX - kMockTouchRadius,
1553                       kFakeCoordY - kMockTouchRadius,
1554                       kMockTouchRadius * 2,
1555                       kMockTouchRadius * 2),
1556            GetMostRecentGestureEvent().details.bounding_box());
1557}
1558
1559// Verify that no accidental pinching occurs if the touch size is large relative
1560// to the min scaling span.
1561TEST_F(GestureProviderTest, NoPinchZoomWithFatFinger) {
1562  base::TimeTicks event_time = base::TimeTicks::Now();
1563  const float kFatFingerSize = GetMinScalingSpan() * 3.f;
1564
1565  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false);
1566  gesture_provider_->SetMultiTouchZoomSupportEnabled(true);
1567
1568  MockMotionEvent event =
1569      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
1570  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1571  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1572  EXPECT_EQ(1U, GetReceivedGestureCount());
1573
1574  event = ObtainMotionEvent(event_time + kOneSecond,
1575                            MotionEvent::ACTION_MOVE);
1576  event.SetTouchMajor(0.1f);
1577  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1578  EXPECT_EQ(1U, GetReceivedGestureCount());
1579
1580  event = ObtainMotionEvent(event_time + kOneSecond * 2,
1581                            MotionEvent::ACTION_MOVE,
1582                            kFakeCoordX + 1.f,
1583                            kFakeCoordY);
1584  event.SetTouchMajor(1.f);
1585  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1586  EXPECT_EQ(1U, GetReceivedGestureCount());
1587
1588  event = ObtainMotionEvent(event_time + kOneSecond * 3,
1589                            MotionEvent::ACTION_MOVE);
1590  event.SetTouchMajor(kFatFingerSize * 3.5f);
1591  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1592  EXPECT_EQ(1U, GetReceivedGestureCount());
1593
1594  event = ObtainMotionEvent(event_time + kOneSecond * 4,
1595                            MotionEvent::ACTION_MOVE);
1596  event.SetTouchMajor(kFatFingerSize * 5.f);
1597  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1598  EXPECT_EQ(1U, GetReceivedGestureCount());
1599}
1600
1601// Verify that multi-finger swipe sends the proper event sequence.
1602TEST_F(GestureProviderTest, MultiFingerSwipe) {
1603  EnableSwipe();
1604  gesture_provider_->SetMultiTouchZoomSupportEnabled(false);
1605  const float min_swipe_velocity = GetMinSwipeVelocity();
1606
1607  // One finger - swipe right
1608  OneFingerSwipe(2 * min_swipe_velocity, 0);
1609  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SWIPE));
1610  EXPECT_TRUE(GetMostRecentGestureEvent().details.swipe_right());
1611  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1612  ResetGestureDetection();
1613
1614  // One finger - swipe left
1615  OneFingerSwipe(-2 * min_swipe_velocity, 0);
1616  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SWIPE));
1617  EXPECT_TRUE(GetMostRecentGestureEvent().details.swipe_left());
1618  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1619  ResetGestureDetection();
1620
1621  // One finger - swipe down
1622  OneFingerSwipe(0, 2 * min_swipe_velocity);
1623  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SWIPE));
1624  EXPECT_TRUE(GetMostRecentGestureEvent().details.swipe_down());
1625  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1626  ResetGestureDetection();
1627
1628  // One finger - swipe up
1629  OneFingerSwipe(0, -2 * min_swipe_velocity);
1630  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SWIPE));
1631  EXPECT_TRUE(GetMostRecentGestureEvent().details.swipe_up());
1632  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1633  ResetGestureDetection();
1634
1635  // Two fingers
1636  // Swipe right.
1637  TwoFingerSwipe(min_swipe_velocity * 2, 0, min_swipe_velocity * 2, 0);
1638  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SWIPE));
1639  EXPECT_TRUE(GetMostRecentGestureEvent().details.swipe_right());
1640  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
1641  ResetGestureDetection();
1642
1643  // Swipe left.
1644  TwoFingerSwipe(-min_swipe_velocity * 2, 0, -min_swipe_velocity * 2, 0);
1645  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SWIPE));
1646  EXPECT_TRUE(GetMostRecentGestureEvent().details.swipe_left());
1647  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
1648  ResetGestureDetection();
1649
1650  // No swipe with different touch directions.
1651  TwoFingerSwipe(min_swipe_velocity * 2, 0, -min_swipe_velocity * 2, 0);
1652  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SWIPE));
1653  ResetGestureDetection();
1654
1655  // No swipe without a dominant direction.
1656  TwoFingerSwipe(min_swipe_velocity * 2,
1657                 min_swipe_velocity * 2,
1658                 min_swipe_velocity * 2,
1659                 min_swipe_velocity * 2);
1660  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SWIPE));
1661  ResetGestureDetection();
1662
1663  // Swipe down with non-zero velocities on both axes and dominant direction.
1664  TwoFingerSwipe(-min_swipe_velocity,
1665                 min_swipe_velocity * 4,
1666                 -min_swipe_velocity,
1667                 min_swipe_velocity * 4);
1668  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SWIPE));
1669  EXPECT_TRUE(GetMostRecentGestureEvent().details.swipe_down());
1670  EXPECT_FALSE(GetMostRecentGestureEvent().details.swipe_left());
1671  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
1672  ResetGestureDetection();
1673
1674  // Swipe up with non-zero velocities on both axes.
1675  TwoFingerSwipe(min_swipe_velocity,
1676                 -min_swipe_velocity * 4,
1677                 min_swipe_velocity,
1678                 -min_swipe_velocity * 4);
1679  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SWIPE));
1680  EXPECT_TRUE(GetMostRecentGestureEvent().details.swipe_up());
1681  EXPECT_FALSE(GetMostRecentGestureEvent().details.swipe_right());
1682  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
1683  ResetGestureDetection();
1684
1685  // No swipe without sufficient velocity.
1686  TwoFingerSwipe(min_swipe_velocity / 2, 0, 0, 0);
1687  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SWIPE));
1688  ResetGestureDetection();
1689
1690  // Swipe up with one small and one medium velocity in slightly different but
1691  // not opposing directions.
1692  TwoFingerSwipe(min_swipe_velocity / 2,
1693                 min_swipe_velocity / 2,
1694                 0,
1695                 min_swipe_velocity * 2);
1696  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SWIPE));
1697  EXPECT_TRUE(GetMostRecentGestureEvent().details.swipe_down());
1698  EXPECT_FALSE(GetMostRecentGestureEvent().details.swipe_right());
1699  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
1700  ResetGestureDetection();
1701
1702  // No swipe in orthogonal directions.
1703  TwoFingerSwipe(min_swipe_velocity * 2, 0, 0, min_swipe_velocity * 7);
1704  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SWIPE));
1705  ResetGestureDetection();
1706
1707  // Three finger swipe in same directions.
1708  ThreeFingerSwipe(min_swipe_velocity * 2,
1709                   0,
1710                   min_swipe_velocity * 3,
1711                   0,
1712                   min_swipe_velocity * 4,
1713                   0);
1714  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SWIPE));
1715  EXPECT_TRUE(GetMostRecentGestureEvent().details.swipe_right());
1716  EXPECT_EQ(3, GetMostRecentGestureEvent().details.touch_points());
1717  ResetGestureDetection();
1718
1719  // No three finger swipe in different directions.
1720  ThreeFingerSwipe(min_swipe_velocity * 2,
1721                   0,
1722                   0,
1723                   min_swipe_velocity * 3,
1724                   min_swipe_velocity * 4,
1725                   0);
1726  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SWIPE));
1727}
1728
1729// Verify that the timer of LONG_PRESS will be cancelled when scrolling begins
1730// so LONG_PRESS and LONG_TAP won't be triggered.
1731TEST_F(GestureProviderTest, GesturesCancelledAfterLongPressCausesLostFocus) {
1732  base::TimeTicks event_time = base::TimeTicks::Now();
1733
1734  MockMotionEvent event =
1735      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
1736  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1737
1738  const base::TimeDelta long_press_timeout =
1739      GetLongPressTimeout() + GetShowPressTimeout() + kOneMicrosecond;
1740  RunTasksAndWait(long_press_timeout);
1741  EXPECT_EQ(ET_GESTURE_LONG_PRESS, GetMostRecentGestureEventType());
1742  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1743
1744  EXPECT_TRUE(CancelActiveTouchSequence());
1745  EXPECT_FALSE(HasDownEvent());
1746
1747  event = ObtainMotionEvent(event_time + long_press_timeout,
1748                            MotionEvent::ACTION_UP);
1749  gesture_provider_->OnTouchEvent(event);
1750  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_TAP));
1751}
1752
1753// Verify that inserting a touch cancel event will trigger proper touch and
1754// gesture sequence cancellation.
1755TEST_F(GestureProviderTest, CancelActiveTouchSequence) {
1756  base::TimeTicks event_time = base::TimeTicks::Now();
1757  int motion_event_id = 0;
1758
1759  EXPECT_FALSE(CancelActiveTouchSequence());
1760  EXPECT_EQ(0U, GetReceivedGestureCount());
1761
1762  MockMotionEvent event =
1763      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
1764  event.SetId(++motion_event_id);
1765  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1766  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1767  EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
1768  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1769
1770  ASSERT_TRUE(CancelActiveTouchSequence());
1771  EXPECT_FALSE(HasDownEvent());
1772
1773  // Subsequent MotionEvent's are dropped until ACTION_DOWN.
1774  event = ObtainMotionEvent(event_time + kOneMicrosecond,
1775                            MotionEvent::ACTION_MOVE);
1776  EXPECT_FALSE(gesture_provider_->OnTouchEvent(event));
1777
1778  event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
1779                            MotionEvent::ACTION_UP);
1780  EXPECT_FALSE(gesture_provider_->OnTouchEvent(event));
1781
1782  event = ObtainMotionEvent(event_time + kOneMicrosecond * 3,
1783                            MotionEvent::ACTION_DOWN);
1784  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1785  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1786  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1787}
1788
1789TEST_F(GestureProviderTest, DoubleTapDragZoomCancelledOnSecondaryPointerDown) {
1790  const base::TimeTicks down_time_1 = TimeTicks::Now();
1791  const base::TimeTicks down_time_2 = down_time_1 + GetValidDoubleTapDelay();
1792
1793  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true);
1794
1795  MockMotionEvent event =
1796      ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
1797  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1798  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1799  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1800
1801  event =
1802      ObtainMotionEvent(down_time_1 + kOneMicrosecond, MotionEvent::ACTION_UP);
1803  gesture_provider_->OnTouchEvent(event);
1804  EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
1805  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1806
1807  event = ObtainMotionEvent(down_time_2, MotionEvent::ACTION_DOWN);
1808  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1809  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1810  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1811
1812  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
1813                            MotionEvent::ACTION_MOVE,
1814                            kFakeCoordX,
1815                            kFakeCoordY - 30);
1816  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1817  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
1818  EXPECT_EQ(ET_GESTURE_PINCH_BEGIN, GetMostRecentGestureEventType());
1819  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1820
1821  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
1822                            MotionEvent::ACTION_POINTER_DOWN,
1823                            kFakeCoordX,
1824                            kFakeCoordY - 30,
1825                            kFakeCoordX + 50,
1826                            kFakeCoordY + 50);
1827  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1828  EXPECT_EQ(ET_GESTURE_PINCH_END, GetMostRecentGestureEventType());
1829  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
1830
1831  const size_t gesture_count = GetReceivedGestureCount();
1832  event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
1833                            MotionEvent::ACTION_POINTER_UP,
1834                            kFakeCoordX,
1835                            kFakeCoordY - 30,
1836                            kFakeCoordX + 50,
1837                            kFakeCoordY + 50);
1838  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1839  EXPECT_EQ(gesture_count, GetReceivedGestureCount());
1840
1841  event = ObtainMotionEvent(down_time_2 + kOneSecond,
1842                            MotionEvent::ACTION_UP);
1843  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1844  EXPECT_EQ(gesture_count + 1, GetReceivedGestureCount());
1845  EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
1846  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1847}
1848
1849// Verify that gesture begin and gesture end events are dispatched correctly.
1850TEST_F(GestureProviderTest, GestureBeginAndEnd) {
1851  EnableBeginEndTypes();
1852  base::TimeTicks event_time = base::TimeTicks::Now();
1853  const float raw_offset_x = 7.5f;
1854  const float raw_offset_y = 5.7f;
1855
1856  EXPECT_EQ(0U, GetReceivedGestureCount());
1857  MockMotionEvent event =
1858      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN, 1, 1);
1859  event.pointer_count = 1;
1860  event.SetRawOffset(raw_offset_x, raw_offset_y);
1861  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1862  EXPECT_EQ(ET_GESTURE_BEGIN, GetReceivedGesture(0).type());
1863  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1864  EXPECT_EQ(2U, GetReceivedGestureCount());
1865  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1866  EXPECT_EQ(1, GetMostRecentGestureEvent().x);
1867  EXPECT_EQ(1, GetMostRecentGestureEvent().y);
1868  EXPECT_EQ(1 + raw_offset_x, GetMostRecentGestureEvent().raw_x);
1869  EXPECT_EQ(1 + raw_offset_y, GetMostRecentGestureEvent().raw_y);
1870  EXPECT_EQ(gfx::RectF(1 - kMockTouchRadius,
1871                       1 - kMockTouchRadius,
1872                       kMockTouchRadius * 2,
1873                       kMockTouchRadius * 2),
1874            GetMostRecentGestureEvent().details.bounding_box());
1875
1876  event = ObtainMotionEvent(
1877      event_time, MotionEvent::ACTION_POINTER_DOWN, 1, 1, 2, 2);
1878  event.pointer_count = 2;
1879  event.SetRawOffset(raw_offset_x, raw_offset_y);
1880  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1881  EXPECT_EQ(ET_GESTURE_BEGIN, GetMostRecentGestureEventType());
1882  EXPECT_EQ(3U, GetReceivedGestureCount());
1883  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
1884  EXPECT_EQ(2, GetMostRecentGestureEvent().x);
1885  EXPECT_EQ(2, GetMostRecentGestureEvent().y);
1886  EXPECT_EQ(2 + raw_offset_x, GetMostRecentGestureEvent().raw_x);
1887  EXPECT_EQ(2 + raw_offset_y, GetMostRecentGestureEvent().raw_y);
1888
1889  event = ObtainMotionEvent(
1890      event_time, MotionEvent::ACTION_POINTER_DOWN, 1, 1, 2, 2, 3, 3);
1891  event.pointer_count = 3;
1892  event.SetRawOffset(raw_offset_x, raw_offset_y);
1893  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1894  EXPECT_EQ(ET_GESTURE_BEGIN, GetMostRecentGestureEventType());
1895  EXPECT_EQ(4U, GetReceivedGestureCount());
1896  EXPECT_EQ(3, GetMostRecentGestureEvent().details.touch_points());
1897  EXPECT_EQ(3, GetMostRecentGestureEvent().x);
1898  EXPECT_EQ(3, GetMostRecentGestureEvent().y);
1899  EXPECT_EQ(3 + raw_offset_x, GetMostRecentGestureEvent().raw_x);
1900  EXPECT_EQ(3 + raw_offset_y, GetMostRecentGestureEvent().raw_y);
1901
1902  event = ObtainMotionEvent(
1903      event_time, MotionEvent::ACTION_POINTER_UP, 1, 1, 2, 2, 3, 3);
1904  event.pointer_count = 2;
1905  event.SetRawOffset(raw_offset_x, raw_offset_y);
1906  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1907  EXPECT_EQ(ET_GESTURE_END, GetMostRecentGestureEventType());
1908  EXPECT_EQ(5U, GetReceivedGestureCount());
1909  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
1910  EXPECT_EQ(1, GetMostRecentGestureEvent().x);
1911  EXPECT_EQ(1, GetMostRecentGestureEvent().y);
1912  EXPECT_EQ(1 + raw_offset_x, GetMostRecentGestureEvent().raw_x);
1913  EXPECT_EQ(1 + raw_offset_y, GetMostRecentGestureEvent().raw_y);
1914
1915  event = ObtainMotionEvent(
1916      event_time, MotionEvent::ACTION_POINTER_DOWN, 2, 2, 3, 3, 4, 4);
1917  event.SetRawOffset(raw_offset_x, raw_offset_y);
1918  event.pointer_count = 3;
1919  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1920  EXPECT_EQ(ET_GESTURE_BEGIN, GetMostRecentGestureEventType());
1921  EXPECT_EQ(6U, GetReceivedGestureCount());
1922  EXPECT_EQ(3, GetMostRecentGestureEvent().details.touch_points());
1923  EXPECT_EQ(4, GetMostRecentGestureEvent().x);
1924  EXPECT_EQ(4, GetMostRecentGestureEvent().y);
1925  EXPECT_EQ(4 + raw_offset_x, GetMostRecentGestureEvent().raw_x);
1926  EXPECT_EQ(4 + raw_offset_y, GetMostRecentGestureEvent().raw_y);
1927
1928  event = ObtainMotionEvent(
1929      event_time, MotionEvent::ACTION_POINTER_UP, 2, 2, 3, 3, 4, 4);
1930  event.pointer_count = 2;
1931  event.SetRawOffset(raw_offset_x, raw_offset_y);
1932  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1933  EXPECT_EQ(ET_GESTURE_END, GetMostRecentGestureEventType());
1934  EXPECT_EQ(7U, GetReceivedGestureCount());
1935  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
1936  EXPECT_EQ(2, GetMostRecentGestureEvent().x);
1937  EXPECT_EQ(2, GetMostRecentGestureEvent().y);
1938  EXPECT_EQ(2 + raw_offset_x, GetMostRecentGestureEvent().raw_x);
1939  EXPECT_EQ(2 + raw_offset_y, GetMostRecentGestureEvent().raw_y);
1940
1941  event =
1942      ObtainMotionEvent(event_time, MotionEvent::ACTION_POINTER_UP, 3, 3, 4, 4);
1943  event.pointer_count = 1;
1944  event.SetRawOffset(raw_offset_x, raw_offset_y);
1945  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1946  EXPECT_EQ(ET_GESTURE_END, GetMostRecentGestureEventType());
1947  EXPECT_EQ(8U, GetReceivedGestureCount());
1948  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1949  EXPECT_EQ(3, GetMostRecentGestureEvent().x);
1950  EXPECT_EQ(3, GetMostRecentGestureEvent().y);
1951  EXPECT_EQ(3 + raw_offset_x, GetMostRecentGestureEvent().raw_x);
1952  EXPECT_EQ(3 + raw_offset_y, GetMostRecentGestureEvent().raw_y);
1953
1954
1955  event = ObtainMotionEvent(event_time, MotionEvent::ACTION_UP, 4, 4);
1956  event.pointer_count = 1;
1957  event.SetRawOffset(raw_offset_x, raw_offset_y);
1958  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1959  EXPECT_EQ(ET_GESTURE_END, GetMostRecentGestureEventType());
1960  EXPECT_EQ(9U, GetReceivedGestureCount());
1961  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1962  EXPECT_EQ(4, GetMostRecentGestureEvent().x);
1963  EXPECT_EQ(4, GetMostRecentGestureEvent().y);
1964  EXPECT_EQ(4 + raw_offset_x, GetMostRecentGestureEvent().raw_x);
1965  EXPECT_EQ(4 + raw_offset_y, GetMostRecentGestureEvent().raw_y);
1966}
1967
1968// Verify that gesture begin and gesture end events are dispatched correctly
1969// when an ACTION_CANCEL is received.
1970TEST_F(GestureProviderTest, GestureBeginAndEndOnCancel) {
1971  EnableBeginEndTypes();
1972  base::TimeTicks event_time = base::TimeTicks::Now();
1973
1974  EXPECT_EQ(0U, GetReceivedGestureCount());
1975  MockMotionEvent event =
1976      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN, 1, 1);
1977  event.pointer_count = 1;
1978  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1979  EXPECT_EQ(ET_GESTURE_BEGIN, GetReceivedGesture(0).type());
1980  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1981  EXPECT_EQ(2U, GetReceivedGestureCount());
1982  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
1983  EXPECT_EQ(gfx::RectF(1 - kMockTouchRadius,
1984                       1 - kMockTouchRadius,
1985                       kMockTouchRadius * 2,
1986                       kMockTouchRadius * 2),
1987            GetMostRecentGestureEvent().details.bounding_box());
1988  EXPECT_EQ(1, GetMostRecentGestureEvent().x);
1989  EXPECT_EQ(1, GetMostRecentGestureEvent().y);
1990
1991  event = ObtainMotionEvent(
1992      event_time, MotionEvent::ACTION_POINTER_DOWN, 1, 1, 2, 2);
1993  event.pointer_count = 2;
1994  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1995  EXPECT_EQ(ET_GESTURE_BEGIN, GetMostRecentGestureEventType());
1996  EXPECT_EQ(3U, GetReceivedGestureCount());
1997  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
1998  EXPECT_EQ(2, GetMostRecentGestureEvent().x);
1999  EXPECT_EQ(2, GetMostRecentGestureEvent().y);
2000
2001
2002  event = ObtainMotionEvent(
2003      event_time, MotionEvent::ACTION_POINTER_DOWN, 1, 1, 2, 2, 3, 3);
2004  event.pointer_count = 3;
2005  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2006  EXPECT_EQ(ET_GESTURE_BEGIN, GetMostRecentGestureEventType());
2007  EXPECT_EQ(4U, GetReceivedGestureCount());
2008  EXPECT_EQ(3, GetMostRecentGestureEvent().details.touch_points());
2009  EXPECT_EQ(3, GetMostRecentGestureEvent().x);
2010  EXPECT_EQ(3, GetMostRecentGestureEvent().y);
2011
2012  event = ObtainMotionEvent(
2013      event_time, MotionEvent::ACTION_CANCEL, 1, 1, 2, 2, 3, 3);
2014  event.pointer_count = 3;
2015  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2016  EXPECT_EQ(7U, GetReceivedGestureCount());
2017  EXPECT_EQ(3, GetReceivedGesture(4).details.touch_points());
2018  EXPECT_EQ(ET_GESTURE_END, GetReceivedGesture(4).type());
2019  EXPECT_EQ(2, GetReceivedGesture(5).details.touch_points());
2020  EXPECT_EQ(ET_GESTURE_END, GetReceivedGesture(5).type());
2021  EXPECT_EQ(1, GetReceivedGesture(6).details.touch_points());
2022  EXPECT_EQ(ET_GESTURE_END, GetReceivedGesture(6).type());
2023  EXPECT_EQ(1, GetReceivedGesture(4).x);
2024  EXPECT_EQ(1, GetReceivedGesture(4).y);
2025  EXPECT_EQ(2, GetReceivedGesture(5).x);
2026  EXPECT_EQ(2, GetReceivedGesture(5).y);
2027  EXPECT_EQ(3, GetReceivedGesture(6).x);
2028  EXPECT_EQ(3, GetReceivedGesture(6).y);
2029}
2030
2031// Test a simple two finger tap
2032TEST_F(GestureProviderTest, TwoFingerTap) {
2033  // The time between ACTION_POINTER_DOWN and ACTION_POINTER_UP must be <= the
2034  // two finger tap delay.
2035  EnableTwoFingerTap(kMaxTwoFingerTapSeparation, base::TimeDelta());
2036  const float scaled_touch_slop = GetTouchSlop();
2037
2038  base::TimeTicks event_time = base::TimeTicks::Now();
2039
2040  MockMotionEvent event =
2041      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN, 0, 0);
2042  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2043
2044  event = ObtainMotionEvent(event_time,
2045                            MotionEvent::ACTION_MOVE,
2046                            0,
2047                            scaled_touch_slop / 2);
2048
2049  event = ObtainMotionEvent(event_time,
2050                            MotionEvent::ACTION_POINTER_DOWN,
2051                            0,
2052                            0,
2053                            kMaxTwoFingerTapSeparation / 2,
2054                            0);
2055  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2056
2057  event =
2058      ObtainMotionEvent(event_time,
2059                        MotionEvent::ACTION_MOVE,
2060                        0,
2061                        -scaled_touch_slop / 2,
2062                        kMaxTwoFingerTapSeparation / 2 + scaled_touch_slop / 2,
2063                        0);
2064  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2065
2066  event = ObtainMotionEvent(event_time,
2067                            MotionEvent::ACTION_POINTER_UP,
2068                            0,
2069                            0,
2070                            kMaxTwoFingerTapSeparation,
2071                            0);
2072  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2073
2074  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetReceivedGesture(0).type());
2075  EXPECT_EQ(ET_GESTURE_SCROLL_BEGIN, GetReceivedGesture(1).type());
2076  EXPECT_EQ(ET_GESTURE_TWO_FINGER_TAP, GetReceivedGesture(2).type());
2077  EXPECT_EQ(3U, GetReceivedGestureCount());
2078
2079  EXPECT_EQ(kMockTouchRadius * 2,
2080            GetReceivedGesture(2).details.first_finger_width());
2081  EXPECT_EQ(kMockTouchRadius * 2,
2082            GetReceivedGesture(2).details.first_finger_height());
2083}
2084
2085// Test preventing a two finger tap via finger movement.
2086TEST_F(GestureProviderTest, TwoFingerTapCancelledByFingerMovement) {
2087  EnableTwoFingerTap(kMaxTwoFingerTapSeparation, base::TimeDelta());
2088  const float scaled_touch_slop = GetTouchSlop();
2089  base::TimeTicks event_time = base::TimeTicks::Now();
2090
2091  MockMotionEvent event = ObtainMotionEvent(
2092      event_time, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
2093  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2094
2095  event = ObtainMotionEvent(event_time,
2096                            MotionEvent::ACTION_POINTER_DOWN,
2097                            kFakeCoordX,
2098                            kFakeCoordY,
2099                            kFakeCoordX,
2100                            kFakeCoordY);
2101  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2102
2103  event = ObtainMotionEvent(event_time,
2104                            MotionEvent::ACTION_MOVE,
2105                            kFakeCoordX,
2106                            kFakeCoordY,
2107                            kFakeCoordX + scaled_touch_slop + 0.1,
2108                            kFakeCoordY);
2109  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2110
2111  event = ObtainMotionEvent(event_time,
2112                            MotionEvent::ACTION_POINTER_UP,
2113                            kFakeCoordX,
2114                            kFakeCoordY,
2115                            kFakeCoordX,
2116                            kFakeCoordY);
2117  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2118
2119  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetReceivedGesture(0).type());
2120  EXPECT_EQ(ET_GESTURE_SCROLL_BEGIN, GetReceivedGesture(1).type());
2121  EXPECT_EQ(2U, GetReceivedGestureCount());
2122}
2123
2124// Test preventing a two finger tap by waiting too long before releasing the
2125// secondary pointer.
2126TEST_F(GestureProviderTest, TwoFingerTapCancelledByDelay) {
2127  base::TimeDelta two_finger_tap_timeout = kOneSecond;
2128  EnableTwoFingerTap(kMaxTwoFingerTapSeparation, two_finger_tap_timeout);
2129  base::TimeTicks event_time = base::TimeTicks::Now();
2130
2131  MockMotionEvent event = ObtainMotionEvent(
2132      event_time, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
2133  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2134
2135  event = ObtainMotionEvent(event_time,
2136                            MotionEvent::ACTION_MOVE,
2137                            kFakeCoordX,
2138                            kFakeCoordY);
2139
2140  event = ObtainMotionEvent(event_time,
2141                            MotionEvent::ACTION_POINTER_DOWN,
2142                            kFakeCoordX,
2143                            kFakeCoordY,
2144                            kFakeCoordX + kMaxTwoFingerTapSeparation / 2,
2145                            kFakeCoordY);
2146  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2147
2148  event = ObtainMotionEvent(event_time + kOneSecond + kOneMicrosecond,
2149                            MotionEvent::ACTION_POINTER_UP,
2150                            kFakeCoordX,
2151                            kFakeCoordY,
2152                            kFakeCoordX + kMaxTwoFingerTapSeparation / 2,
2153                            kFakeCoordY);
2154  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2155
2156  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetReceivedGesture(0).type());
2157  EXPECT_EQ(1U, GetReceivedGestureCount());
2158}
2159
2160// Test preventing a two finger tap by pressing the secondary pointer too far
2161// from the first
2162TEST_F(GestureProviderTest, TwoFingerTapCancelledByDistanceBetweenPointers) {
2163  EnableTwoFingerTap(kMaxTwoFingerTapSeparation, base::TimeDelta());
2164  base::TimeTicks event_time = base::TimeTicks::Now();
2165
2166  MockMotionEvent event = ObtainMotionEvent(
2167      event_time, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
2168  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2169
2170  event = ObtainMotionEvent(event_time,
2171                            MotionEvent::ACTION_POINTER_DOWN,
2172                            kFakeCoordX,
2173                            kFakeCoordY,
2174                            kFakeCoordX + kMaxTwoFingerTapSeparation,
2175                            kFakeCoordY);
2176  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2177
2178  event = ObtainMotionEvent(event_time,
2179                            MotionEvent::ACTION_POINTER_UP,
2180                            kFakeCoordX,
2181                            kFakeCoordY,
2182                            kFakeCoordX + kMaxTwoFingerTapSeparation,
2183                            kFakeCoordY);
2184  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2185
2186  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetReceivedGesture(0).type());
2187  EXPECT_EQ(1U, GetReceivedGestureCount());
2188}
2189
2190// Verify that pinch zoom only sends updates which exceed the
2191// min_pinch_update_span_delta.
2192TEST_F(GestureProviderTest, PinchZoomWithThreshold) {
2193  const float kMinPinchUpdateDistance = 5;
2194
2195  base::TimeTicks event_time = base::TimeTicks::Now();
2196  const float touch_slop = GetTouchSlop();
2197
2198  SetMinPinchUpdateSpanDelta(kMinPinchUpdateDistance);
2199  gesture_provider_->SetDoubleTapSupportForPageEnabled(false);
2200  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true);
2201  gesture_provider_->SetMultiTouchZoomSupportEnabled(true);
2202
2203  int secondary_coord_x = kFakeCoordX + 20 * touch_slop;
2204  int secondary_coord_y = kFakeCoordY + 20 * touch_slop;
2205
2206  // First finger down.
2207  MockMotionEvent event =
2208      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
2209  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2210  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
2211  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
2212
2213  // Second finger down.
2214  event = ObtainMotionEvent(event_time,
2215                            MotionEvent::ACTION_POINTER_DOWN,
2216                            kFakeCoordX,
2217                            kFakeCoordY,
2218                            secondary_coord_x,
2219                            secondary_coord_y);
2220
2221  gesture_provider_->OnTouchEvent(event);
2222  EXPECT_EQ(1U, GetReceivedGestureCount());
2223  EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
2224
2225  // Move second finger.
2226  secondary_coord_x += 5 * touch_slop;
2227  secondary_coord_y += 5 * touch_slop;
2228  event = ObtainMotionEvent(event_time,
2229                            MotionEvent::ACTION_MOVE,
2230                            kFakeCoordX,
2231                            kFakeCoordY,
2232                            secondary_coord_x,
2233                            secondary_coord_y);
2234
2235  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2236  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
2237  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_PINCH_BEGIN));
2238  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_UPDATE));
2239  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
2240  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_UPDATE));
2241
2242  // Small move, shouldn't trigger pinch.
2243  event = ObtainMotionEvent(event_time,
2244                            MotionEvent::ACTION_MOVE,
2245                            kFakeCoordX,
2246                            kFakeCoordY,
2247                            secondary_coord_x + kMinPinchUpdateDistance,
2248                            secondary_coord_y);
2249
2250  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2251  EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_UPDATE));
2252  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
2253
2254  // Small move, but combined with the previous move, should trigger pinch. We
2255  // need to overshoot kMinPinchUpdateDistance by a fair bit, as the span
2256  // calculation factors in touch radius.
2257  const float kOvershootMinPinchUpdateDistance = 3;
2258  event = ObtainMotionEvent(event_time,
2259                            MotionEvent::ACTION_MOVE,
2260                            kFakeCoordX,
2261                            kFakeCoordY,
2262                            secondary_coord_x + kMinPinchUpdateDistance +
2263                                kOvershootMinPinchUpdateDistance,
2264                            secondary_coord_y);
2265
2266  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2267  EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_PINCH_UPDATE));
2268  EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
2269}
2270
2271// Verify that the min gesture bound setting is honored.
2272TEST_F(GestureProviderTest, MinGestureBoundsLength) {
2273  const float kMinGestureBoundsLength = 10.f * kMockTouchRadius;
2274  SetMinGestureBoundsLength(kMinGestureBoundsLength);
2275  gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false);
2276
2277  base::TimeTicks event_time = base::TimeTicks::Now();
2278  MockMotionEvent event =
2279      ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
2280  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2281
2282  EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
2283  EXPECT_EQ(kMinGestureBoundsLength,
2284            GetMostRecentGestureEvent().details.bounding_box_f().width());
2285  EXPECT_EQ(kMinGestureBoundsLength,
2286            GetMostRecentGestureEvent().details.bounding_box_f().height());
2287
2288  event =
2289      ObtainMotionEvent(event_time + kOneMicrosecond, MotionEvent::ACTION_UP);
2290  EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
2291  EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
2292  EXPECT_EQ(kMinGestureBoundsLength,
2293            GetMostRecentGestureEvent().details.bounding_box_f().width());
2294  EXPECT_EQ(kMinGestureBoundsLength,
2295            GetMostRecentGestureEvent().details.bounding_box_f().height());
2296}
2297
2298}  // namespace ui
2299