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