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