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