Store the id of a contributing motion event in GestureEventData
[chromium-blink-merge.git] / ui / events / gesture_detection / gesture_provider_unittest.cc
blob5934b5bc0c08c20e58d1cea016322b81d09200b7
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.
5 #include "base/basictypes.h"
6 #include "base/logging.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/time/time.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "ui/events/event_constants.h"
12 #include "ui/events/gesture_detection/gesture_event_data.h"
13 #include "ui/events/gesture_detection/gesture_provider.h"
14 #include "ui/events/gesture_detection/mock_motion_event.h"
15 #include "ui/events/gesture_detection/motion_event.h"
16 #include "ui/gfx/geometry/point_f.h"
18 using base::TimeDelta;
19 using base::TimeTicks;
21 namespace ui {
22 namespace {
24 const float kFakeCoordX = 42.f;
25 const float kFakeCoordY = 24.f;
26 const TimeDelta kOneSecond = TimeDelta::FromSeconds(1);
27 const TimeDelta kOneMicrosecond = TimeDelta::FromMicroseconds(1);
28 const TimeDelta kDeltaTimeForFlingSequences = TimeDelta::FromMilliseconds(5);
30 GestureProvider::Config CreateDefaultConfig() {
31 GestureProvider::Config sConfig;
32 // The longpress timeout is non-zero only to indicate ordering with respect to
33 // the showpress timeout.
34 sConfig.gesture_detector_config.showpress_timeout = base::TimeDelta();
35 sConfig.gesture_detector_config.longpress_timeout = kOneMicrosecond;
37 // A valid doubletap timeout should always be non-zero. The value is used not
38 // only to trigger the timeout that confirms the tap event, but also to gate
39 // whether the second tap is in fact a double-tap (using a strict inequality
40 // between times for the first up and the second down events). We use 4
41 // microseconds simply to allow several intermediate events to occur before
42 // the second tap at microsecond intervals.
43 sConfig.gesture_detector_config.double_tap_timeout = kOneMicrosecond * 4;
44 return sConfig;
47 } // namespace
49 class GestureProviderTest : public testing::Test, public GestureProviderClient {
50 public:
51 GestureProviderTest() {}
52 virtual ~GestureProviderTest() {}
54 static MockMotionEvent ObtainMotionEvent(base::TimeTicks event_time,
55 MotionEvent::Action action,
56 float x,
57 float y) {
58 return MockMotionEvent(action, event_time, x, y);
61 static MockMotionEvent ObtainMotionEvent(base::TimeTicks event_time,
62 MotionEvent::Action action,
63 float x0,
64 float y0,
65 float x1,
66 float y1) {
67 return MockMotionEvent(action, event_time, x0, y0, x1, y1);
70 static MockMotionEvent ObtainMotionEvent(base::TimeTicks event_time,
71 MotionEvent::Action action) {
72 return ObtainMotionEvent(event_time, action, kFakeCoordX, kFakeCoordY);
75 // Test
76 virtual void SetUp() OVERRIDE {
77 gesture_provider_.reset(new GestureProvider(GetDefaultConfig(), this));
78 gesture_provider_->SetMultiTouchSupportEnabled(false);
81 virtual void TearDown() OVERRIDE {
82 gestures_.clear();
83 gesture_provider_.reset();
86 // GestureProviderClient
87 virtual void OnGestureEvent(const GestureEventData& gesture) OVERRIDE {
88 if (gesture.type == ET_GESTURE_SCROLL_BEGIN)
89 active_scroll_begin_event_.reset(new GestureEventData(gesture));
90 gestures_.push_back(gesture);
93 bool CancelActiveTouchSequence() {
94 if (!gesture_provider_->current_down_event())
95 return false;
96 return gesture_provider_->OnTouchEvent(
97 *gesture_provider_->current_down_event()->Cancel());
100 bool HasReceivedGesture(EventType type) const {
101 for (size_t i = 0; i < gestures_.size(); ++i) {
102 if (gestures_[i].type == type)
103 return true;
105 return false;
108 const GestureEventData& GetMostRecentGestureEvent() const {
109 EXPECT_FALSE(gestures_.empty());
110 return gestures_.back();
113 const EventType GetMostRecentGestureEventType() const {
114 EXPECT_FALSE(gestures_.empty());
115 return gestures_.back().type;
118 size_t GetReceivedGestureCount() const { return gestures_.size(); }
120 const GestureEventData& GetReceivedGesture(size_t index) const {
121 EXPECT_LT(index, GetReceivedGestureCount());
122 return gestures_[index];
125 const GestureEventData* GetActiveScrollBeginEvent() const {
126 return active_scroll_begin_event_ ? active_scroll_begin_event_.get() : NULL;
129 const GestureProvider::Config& GetDefaultConfig() const {
130 static GestureProvider::Config sConfig = CreateDefaultConfig();
131 return sConfig;
134 int GetTouchSlop() const {
135 return GetDefaultConfig().gesture_detector_config.scaled_touch_slop;
138 base::TimeDelta GetLongPressTimeout() const {
139 return GetDefaultConfig().gesture_detector_config.longpress_timeout;
142 base::TimeDelta GetShowPressTimeout() const {
143 return GetDefaultConfig().gesture_detector_config.showpress_timeout;
146 protected:
147 void CheckScrollEventSequenceForEndActionType(
148 MotionEvent::Action end_action_type) {
149 base::TimeTicks event_time = base::TimeTicks::Now();
150 const int scroll_to_x = kFakeCoordX + 100;
151 const int scroll_to_y = kFakeCoordY + 100;
152 int motion_event_id = 0;
154 MockMotionEvent event =
155 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
156 event.SetId(++motion_event_id);
158 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
160 event = ObtainMotionEvent(event_time + kOneSecond,
161 MotionEvent::ACTION_MOVE,
162 scroll_to_x,
163 scroll_to_y);
164 event.SetId(++motion_event_id);
166 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
167 EXPECT_TRUE(gesture_provider_->IsScrollInProgress());
168 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
169 EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
170 EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
171 ASSERT_EQ(4U, GetReceivedGestureCount()) << "Only TapDown, TapCancel, "
172 "ScrollBegin and ScrollBy "
173 "should have been sent";
175 EXPECT_EQ(ET_GESTURE_TAP_CANCEL, GetReceivedGesture(1).type);
176 EXPECT_EQ(motion_event_id, GetReceivedGesture(1).motion_event_id);
177 EXPECT_EQ(ET_GESTURE_SCROLL_BEGIN, GetReceivedGesture(2).type);
178 EXPECT_EQ(motion_event_id, GetReceivedGesture(2).motion_event_id);
179 EXPECT_EQ(event_time + kOneSecond, GetReceivedGesture(2).time)
180 << "ScrollBegin should have the time of the ACTION_MOVE";
182 event = ObtainMotionEvent(
183 event_time + kOneSecond, end_action_type, scroll_to_x, scroll_to_y);
184 event.SetId(++motion_event_id);
186 gesture_provider_->OnTouchEvent(event);
187 EXPECT_FALSE(gesture_provider_->IsScrollInProgress());
188 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_END));
189 EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
190 EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
193 static void RunTasksAndWait(base::TimeDelta delay) {
194 base::MessageLoop::current()->PostDelayedTask(
195 FROM_HERE, base::MessageLoop::QuitClosure(), delay);
196 base::MessageLoop::current()->Run();
199 std::vector<GestureEventData> gestures_;
200 scoped_ptr<GestureProvider> gesture_provider_;
201 scoped_ptr<GestureEventData> active_scroll_begin_event_;
202 base::MessageLoopForUI message_loop_;
205 // Verify that a DOWN followed shortly by an UP will trigger a single tap.
206 TEST_F(GestureProviderTest, GestureTapTap) {
207 base::TimeTicks event_time = base::TimeTicks::Now();
208 int motion_event_id = 0;
210 gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false);
212 MockMotionEvent event =
213 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
214 event.SetId(++motion_event_id);
216 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
217 EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
219 event = ObtainMotionEvent(event_time + kOneMicrosecond,
220 MotionEvent::ACTION_UP);
221 event.SetId(++motion_event_id);
223 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
224 EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
225 // Ensure tap details have been set.
226 EXPECT_EQ(10, GetMostRecentGestureEvent().details.bounding_box().width());
227 EXPECT_EQ(10, GetMostRecentGestureEvent().details.bounding_box().height());
228 EXPECT_EQ(1, GetMostRecentGestureEvent().details.tap_count());
229 EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
232 // Verify that a DOWN followed shortly by an UP will trigger
233 // a ET_GESTURE_TAP_UNCONFIRMED event if double-tap is enabled.
234 TEST_F(GestureProviderTest, GestureTapTapWithDelay) {
235 base::TimeTicks event_time = base::TimeTicks::Now();
236 int motion_event_id = 0;
238 gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true);
240 MockMotionEvent event =
241 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
242 event.SetId(++motion_event_id);
244 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
245 EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
246 EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
248 event = ObtainMotionEvent(event_time + kOneMicrosecond,
249 MotionEvent::ACTION_UP);
250 event.SetId(++motion_event_id);
252 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
253 EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
254 // Ensure tap details have been set.
255 EXPECT_EQ(10, GetMostRecentGestureEvent().details.bounding_box().width());
256 EXPECT_EQ(10, GetMostRecentGestureEvent().details.bounding_box().height());
257 EXPECT_EQ(1, GetMostRecentGestureEvent().details.tap_count());
258 EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
260 EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_TAP));
263 // Verify that a DOWN followed by a MOVE will trigger fling (but not LONG).
264 TEST_F(GestureProviderTest, GestureFlingAndCancelLongPress) {
265 base::TimeTicks event_time = TimeTicks::Now();
266 base::TimeDelta delta_time = kDeltaTimeForFlingSequences;
267 int motion_event_id = 0;
269 MockMotionEvent event =
270 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
271 event.SetId(++motion_event_id);
273 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
274 EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
275 EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
277 event = ObtainMotionEvent(event_time + delta_time,
278 MotionEvent::ACTION_MOVE,
279 kFakeCoordX * 10,
280 kFakeCoordY * 10);
281 event.SetId(++motion_event_id);
282 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
284 event = ObtainMotionEvent(event_time + delta_time * 2,
285 MotionEvent::ACTION_UP,
286 kFakeCoordX * 10,
287 kFakeCoordY * 10);
288 event.SetId(++motion_event_id);
290 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
291 EXPECT_EQ(ET_SCROLL_FLING_START, GetMostRecentGestureEventType());
292 EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
293 EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_PRESS));
296 // Verify that for a normal scroll the following events are sent:
297 // - ET_GESTURE_SCROLL_BEGIN
298 // - ET_GESTURE_SCROLL_UPDATE
299 // - ET_GESTURE_SCROLL_END
300 TEST_F(GestureProviderTest, ScrollEventActionUpSequence) {
301 CheckScrollEventSequenceForEndActionType(MotionEvent::ACTION_UP);
304 // Verify that for a cancelled scroll the following events are sent:
305 // - ET_GESTURE_SCROLL_BEGIN
306 // - ET_GESTURE_SCROLL_UPDATE
307 // - ET_GESTURE_SCROLL_END
308 TEST_F(GestureProviderTest, ScrollEventActionCancelSequence) {
309 CheckScrollEventSequenceForEndActionType(MotionEvent::ACTION_CANCEL);
312 // Verify that for a normal fling (fling after scroll) the following events are
313 // sent:
314 // - ET_GESTURE_SCROLL_BEGIN
315 // - ET_SCROLL_FLING_START
316 TEST_F(GestureProviderTest, FlingEventSequence) {
317 base::TimeTicks event_time = base::TimeTicks::Now();
318 base::TimeDelta delta_time = kDeltaTimeForFlingSequences;
319 int motion_event_id = 0;
321 MockMotionEvent event =
322 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
323 event.SetId(++motion_event_id);
325 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
327 event = ObtainMotionEvent(event_time + delta_time,
328 MotionEvent::ACTION_MOVE,
329 kFakeCoordX * 5,
330 kFakeCoordY * 5);
331 event.SetId(++motion_event_id);
333 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
334 EXPECT_TRUE(gesture_provider_->IsScrollInProgress());
335 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
336 EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
337 EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
338 ASSERT_EQ(4U, GetReceivedGestureCount());
339 ASSERT_EQ(ET_GESTURE_SCROLL_BEGIN, GetReceivedGesture(2).type);
340 EXPECT_EQ(motion_event_id, GetReceivedGesture(2).motion_event_id);
342 // We don't want to take a dependency here on exactly how hints are calculated
343 // for a fling (eg. may depend on velocity), so just validate the direction.
344 int hint_x = GetReceivedGesture(2).details.scroll_x_hint();
345 int hint_y = GetReceivedGesture(2).details.scroll_y_hint();
346 EXPECT_TRUE(hint_x > 0 && hint_y > 0 && hint_x > hint_y)
347 << "ScrollBegin hint should be in positive X axis";
349 event = ObtainMotionEvent(event_time + delta_time * 2,
350 MotionEvent::ACTION_UP,
351 kFakeCoordX * 10,
352 kFakeCoordY * 10);
353 event.SetId(++motion_event_id);
355 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
356 EXPECT_FALSE(gesture_provider_->IsScrollInProgress());
357 EXPECT_EQ(ET_SCROLL_FLING_START, GetMostRecentGestureEventType());
358 EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
359 EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SCROLL_END));
360 EXPECT_EQ(event_time + delta_time * 2, GetMostRecentGestureEvent().time)
361 << "FlingStart should have the time of the ACTION_UP";
364 TEST_F(GestureProviderTest, TapCancelledWhenWindowFocusLost) {
365 const base::TimeTicks event_time = TimeTicks::Now();
367 MockMotionEvent event =
368 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
369 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
370 EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
372 RunTasksAndWait(GetLongPressTimeout() + GetShowPressTimeout() +
373 kOneMicrosecond);
374 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SHOW_PRESS));
375 EXPECT_EQ(ET_GESTURE_LONG_PRESS, GetMostRecentGestureEventType());
377 // The long press triggers window focus loss by opening a context menu
378 EXPECT_TRUE(CancelActiveTouchSequence());
379 EXPECT_EQ(ET_GESTURE_TAP_CANCEL, GetMostRecentGestureEventType());
382 TEST_F(GestureProviderTest, TapCancelledWhenScrollBegins) {
383 base::TimeTicks event_time = base::TimeTicks::Now();
385 MockMotionEvent event =
386 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
388 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
390 EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
391 event = ObtainMotionEvent(event_time + kOneMicrosecond,
392 MotionEvent::ACTION_MOVE,
393 kFakeCoordX + 50,
394 kFakeCoordY + 50);
395 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
397 EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
398 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_TAP_CANCEL));
401 TEST_F(GestureProviderTest, DoubleTap) {
402 base::TimeTicks event_time = base::TimeTicks::Now();
404 MockMotionEvent event =
405 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
406 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
408 EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
410 event = ObtainMotionEvent(event_time + kOneMicrosecond,
411 MotionEvent::ACTION_UP,
412 kFakeCoordX,
413 kFakeCoordY);
414 gesture_provider_->OnTouchEvent(event);
415 EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
417 event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
418 MotionEvent::ACTION_DOWN,
419 kFakeCoordX,
420 kFakeCoordY);
421 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
422 EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
424 // Moving a very small amount of distance should not trigger the double tap
425 // drag zoom mode.
426 event = ObtainMotionEvent(event_time + kOneMicrosecond * 3,
427 MotionEvent::ACTION_MOVE,
428 kFakeCoordX,
429 kFakeCoordY + 1);
430 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
431 EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
433 event = ObtainMotionEvent(event_time + kOneMicrosecond * 3,
434 MotionEvent::ACTION_UP,
435 kFakeCoordX,
436 kFakeCoordY + 1);
437 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
439 const GestureEventData& double_tap = GetMostRecentGestureEvent();
440 EXPECT_EQ(ET_GESTURE_DOUBLE_TAP, double_tap.type);
441 // Ensure tap details have been set.
442 EXPECT_EQ(10, double_tap.details.bounding_box().width());
443 EXPECT_EQ(10, double_tap.details.bounding_box().height());
444 EXPECT_EQ(1, double_tap.details.tap_count());
447 TEST_F(GestureProviderTest, DoubleTapDragZoomBasic) {
448 const base::TimeTicks down_time_1 = TimeTicks::Now();
449 const base::TimeTicks down_time_2 = down_time_1 + kOneMicrosecond * 2;
451 MockMotionEvent event =
452 ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
453 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
455 event = ObtainMotionEvent(down_time_1 + kOneMicrosecond,
456 MotionEvent::ACTION_UP,
457 kFakeCoordX,
458 kFakeCoordY);
459 gesture_provider_->OnTouchEvent(event);
460 EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
462 event = ObtainMotionEvent(
463 down_time_2, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
464 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
465 EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
467 event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
468 MotionEvent::ACTION_MOVE,
469 kFakeCoordX,
470 kFakeCoordY + 100);
471 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
472 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
473 ASSERT_EQ(ET_GESTURE_PINCH_BEGIN, GetMostRecentGestureEventType());
475 event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
476 MotionEvent::ACTION_MOVE,
477 kFakeCoordX,
478 kFakeCoordY + 200);
479 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
480 ASSERT_EQ(ET_GESTURE_PINCH_UPDATE, GetMostRecentGestureEventType());
481 EXPECT_LT(1.f, GetMostRecentGestureEvent().details.scale());
483 event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
484 MotionEvent::ACTION_MOVE,
485 kFakeCoordX,
486 kFakeCoordY + 100);
487 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
488 ASSERT_EQ(ET_GESTURE_PINCH_UPDATE, GetMostRecentGestureEventType());
489 EXPECT_GT(1.f, GetMostRecentGestureEvent().details.scale());
491 event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 4,
492 MotionEvent::ACTION_UP,
493 kFakeCoordX,
494 kFakeCoordY - 200);
495 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
496 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_PINCH_END));
497 EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
500 // Generate a scroll gesture and verify that the resulting scroll motion event
501 // has both absolute and relative position information.
502 TEST_F(GestureProviderTest, ScrollUpdateValues) {
503 const int delta_x = 16;
504 const int delta_y = 84;
506 const base::TimeTicks event_time = TimeTicks::Now();
508 MockMotionEvent event =
509 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
510 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
512 // Move twice so that we get two ET_GESTURE_SCROLL_UPDATE events and can
513 // compare the relative and absolute coordinates.
514 event = ObtainMotionEvent(event_time + kOneMicrosecond,
515 MotionEvent::ACTION_MOVE,
516 kFakeCoordX - delta_x / 2,
517 kFakeCoordY - delta_y / 2);
518 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
520 event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
521 MotionEvent::ACTION_MOVE,
522 kFakeCoordX - delta_x,
523 kFakeCoordY - delta_y);
524 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
526 // Make sure the reported gesture event has all the expected details.
527 ASSERT_LT(0U, GetReceivedGestureCount());
528 GestureEventData gesture = GetMostRecentGestureEvent();
529 EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, gesture.type);
530 EXPECT_EQ(event_time + kOneMicrosecond * 2, gesture.time);
531 EXPECT_EQ(kFakeCoordX - delta_x, gesture.x);
532 EXPECT_EQ(kFakeCoordY - delta_y, gesture.y);
534 // No horizontal delta because of snapping.
535 EXPECT_EQ(0, gesture.details.scroll_x());
536 EXPECT_EQ(-delta_y / 2, gesture.details.scroll_y());
539 // Verify that fractional scroll deltas are rounded as expected and that
540 // fractional scrolling doesn't break scroll snapping.
541 TEST_F(GestureProviderTest, FractionalScroll) {
542 const float delta_x = 0.4f;
543 const float delta_y = 5.2f;
545 const base::TimeTicks event_time = TimeTicks::Now();
547 MockMotionEvent event =
548 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
549 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
551 // Skip past the touch slop and move back.
552 event = ObtainMotionEvent(event_time,
553 MotionEvent::ACTION_MOVE,
554 kFakeCoordX,
555 kFakeCoordY + 100);
556 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
557 event = ObtainMotionEvent(event_time,
558 MotionEvent::ACTION_MOVE);
559 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
561 // Now move up slowly, mostly vertically but with a (fractional) bit of
562 // horizontal motion.
563 for(int i = 1; i <= 10; i++) {
564 event = ObtainMotionEvent(event_time + kOneMicrosecond * i,
565 MotionEvent::ACTION_MOVE,
566 kFakeCoordX + delta_x * i,
567 kFakeCoordY + delta_y * i);
568 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
570 ASSERT_LT(0U, GetReceivedGestureCount());
571 GestureEventData gesture = GetMostRecentGestureEvent();
572 EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, gesture.type);
573 EXPECT_EQ(event_time + kOneMicrosecond * i, gesture.time);
575 // Verify that the event co-ordinates are still the precise values we
576 // supplied.
577 EXPECT_EQ(kFakeCoordX + delta_x * i, gesture.x);
578 EXPECT_EQ(kFakeCoordY + delta_y * i, gesture.y);
580 // Verify that we're scrolling vertically by the expected amount
581 // (modulo rounding).
582 EXPECT_GE(gesture.details.scroll_y(), (int)delta_y);
583 EXPECT_LE(gesture.details.scroll_y(), ((int)delta_y) + 1);
585 // And that there has been no horizontal motion at all.
586 EXPECT_EQ(0, gesture.details.scroll_x());
590 // Generate a scroll gesture and verify that the resulting scroll begin event
591 // has the expected hint values.
592 TEST_F(GestureProviderTest, ScrollBeginValues) {
593 const int delta_x = 13;
594 const int delta_y = 89;
596 const base::TimeTicks event_time = TimeTicks::Now();
598 MockMotionEvent event =
599 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
600 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
602 // Move twice such that the first event isn't sufficient to start
603 // scrolling on it's own.
604 event = ObtainMotionEvent(event_time + kOneMicrosecond,
605 MotionEvent::ACTION_MOVE,
606 kFakeCoordX + 2,
607 kFakeCoordY + 1);
608 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
609 EXPECT_FALSE(gesture_provider_->IsScrollInProgress());
611 event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
612 MotionEvent::ACTION_MOVE,
613 kFakeCoordX + delta_x,
614 kFakeCoordY + delta_y);
615 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
616 EXPECT_TRUE(gesture_provider_->IsScrollInProgress());
618 const GestureEventData* scroll_begin_gesture = GetActiveScrollBeginEvent();
619 ASSERT_TRUE(!!scroll_begin_gesture);
620 EXPECT_EQ(delta_x, scroll_begin_gesture->details.scroll_x_hint());
621 EXPECT_EQ(delta_y, scroll_begin_gesture->details.scroll_y_hint());
624 TEST_F(GestureProviderTest, LongPressAndTapCancelledWhenScrollBegins) {
625 base::TimeTicks event_time = base::TimeTicks::Now();
627 MockMotionEvent event =
628 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
629 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
630 event = ObtainMotionEvent(event_time + kOneMicrosecond,
631 MotionEvent::ACTION_MOVE,
632 kFakeCoordX * 5,
633 kFakeCoordY * 5);
634 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
635 event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
636 MotionEvent::ACTION_MOVE,
637 kFakeCoordX * 10,
638 kFakeCoordY * 10);
639 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
641 const base::TimeDelta long_press_timeout =
642 GetLongPressTimeout() + GetShowPressTimeout() + kOneMicrosecond;
643 RunTasksAndWait(long_press_timeout);
645 // No LONG_TAP as the LONG_PRESS timer is cancelled.
646 EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_PRESS));
647 EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_TAP));
650 // Verify that LONG_TAP is triggered after LONG_PRESS followed by an UP.
651 TEST_F(GestureProviderTest, GestureLongTap) {
652 base::TimeTicks event_time = base::TimeTicks::Now();
654 MockMotionEvent event =
655 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
656 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
658 const base::TimeDelta long_press_timeout =
659 GetLongPressTimeout() + GetShowPressTimeout() + kOneMicrosecond;
660 RunTasksAndWait(long_press_timeout);
662 EXPECT_EQ(ET_GESTURE_LONG_PRESS, GetMostRecentGestureEventType());
664 event = ObtainMotionEvent(event_time + kOneSecond, MotionEvent::ACTION_UP);
665 gesture_provider_->OnTouchEvent(event);
666 EXPECT_EQ(ET_GESTURE_LONG_TAP, GetMostRecentGestureEventType());
669 TEST_F(GestureProviderTest, GestureLongPressDoesNotPreventScrolling) {
670 base::TimeTicks event_time = base::TimeTicks::Now();
672 MockMotionEvent event =
673 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
674 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
676 const base::TimeDelta long_press_timeout =
677 GetLongPressTimeout() + GetShowPressTimeout() + kOneMicrosecond;
678 RunTasksAndWait(long_press_timeout);
680 EXPECT_EQ(ET_GESTURE_LONG_PRESS, GetMostRecentGestureEventType());
681 event = ObtainMotionEvent(event_time + long_press_timeout,
682 MotionEvent::ACTION_MOVE,
683 kFakeCoordX + 100,
684 kFakeCoordY + 100);
685 gesture_provider_->OnTouchEvent(event);
687 EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
688 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
689 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_TAP_CANCEL));
691 event = ObtainMotionEvent(event_time + long_press_timeout,
692 MotionEvent::ACTION_UP);
693 gesture_provider_->OnTouchEvent(event);
694 EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_TAP));
697 TEST_F(GestureProviderTest, NoGestureLongPressDuringDoubleTap) {
698 base::TimeTicks event_time = base::TimeTicks::Now();
699 int motion_event_id = 0;
701 MockMotionEvent event = ObtainMotionEvent(
702 event_time, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
703 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
705 event = ObtainMotionEvent(event_time + kOneMicrosecond,
706 MotionEvent::ACTION_UP,
707 kFakeCoordX,
708 kFakeCoordY);
709 gesture_provider_->OnTouchEvent(event);
710 EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
712 event = ObtainMotionEvent(event_time + kOneMicrosecond,
713 MotionEvent::ACTION_DOWN,
714 kFakeCoordX,
715 kFakeCoordY);
716 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
717 EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
718 EXPECT_TRUE(gesture_provider_->IsDoubleTapInProgress());
720 const base::TimeDelta long_press_timeout =
721 GetLongPressTimeout() + GetShowPressTimeout() + kOneMicrosecond;
722 RunTasksAndWait(long_press_timeout);
723 EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_PRESS));
725 event = ObtainMotionEvent(event_time + long_press_timeout,
726 MotionEvent::ACTION_MOVE,
727 kFakeCoordX + 20,
728 kFakeCoordY + 20);
729 event.SetId(++motion_event_id);
731 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
732 EXPECT_EQ(ET_GESTURE_PINCH_BEGIN, GetMostRecentGestureEventType());
733 EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
734 EXPECT_TRUE(gesture_provider_->IsDoubleTapInProgress());
736 event = ObtainMotionEvent(event_time + long_press_timeout + kOneMicrosecond,
737 MotionEvent::ACTION_UP,
738 kFakeCoordX,
739 kFakeCoordY + 1);
740 event.SetId(++motion_event_id);
741 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
742 EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
743 EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
744 EXPECT_FALSE(gesture_provider_->IsDoubleTapInProgress());
747 // Verify that the touch slop region is removed from the first scroll delta to
748 // avoid a jump when starting to scroll.
749 TEST_F(GestureProviderTest, TouchSlopRemovedFromScroll) {
750 const int scaled_touch_slop = GetTouchSlop();
751 const int scroll_delta = 5;
753 base::TimeTicks event_time = base::TimeTicks::Now();
755 MockMotionEvent event =
756 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
757 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
759 event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
760 MotionEvent::ACTION_MOVE,
761 kFakeCoordX,
762 kFakeCoordY + scaled_touch_slop + scroll_delta);
763 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
765 EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
766 GestureEventData gesture = GetMostRecentGestureEvent();
767 EXPECT_EQ(0, gesture.details.scroll_x());
768 EXPECT_EQ(scroll_delta, gesture.details.scroll_y());
771 TEST_F(GestureProviderTest, NoDoubleTapWhenExplicitlyDisabled) {
772 gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false);
774 base::TimeTicks event_time = base::TimeTicks::Now();
775 MockMotionEvent event = ObtainMotionEvent(
776 event_time, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
777 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
778 EXPECT_EQ(1U, GetReceivedGestureCount());
779 EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
781 event = ObtainMotionEvent(event_time + kOneMicrosecond,
782 MotionEvent::ACTION_UP,
783 kFakeCoordX,
784 kFakeCoordY);
785 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
786 EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
788 event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
789 MotionEvent::ACTION_DOWN,
790 kFakeCoordX,
791 kFakeCoordY);
792 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
793 EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
795 event = ObtainMotionEvent(event_time + kOneMicrosecond * 3,
796 MotionEvent::ACTION_UP,
797 kFakeCoordX,
798 kFakeCoordY);
799 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
800 EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
803 TEST_F(GestureProviderTest, NoDoubleTapDragZoomWhenDisabledOnPlatform) {
804 const base::TimeTicks down_time_1 = TimeTicks::Now();
805 const base::TimeTicks down_time_2 = down_time_1 + kOneMicrosecond * 2;
807 gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false);
809 MockMotionEvent event =
810 ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
811 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
813 event = ObtainMotionEvent(down_time_1 + kOneMicrosecond,
814 MotionEvent::ACTION_UP,
815 kFakeCoordX,
816 kFakeCoordY);
817 gesture_provider_->OnTouchEvent(event);
819 event = ObtainMotionEvent(
820 down_time_2, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
821 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
823 event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
824 MotionEvent::ACTION_MOVE,
825 kFakeCoordX,
826 kFakeCoordY + 100);
828 // The move should become a scroll, as doubletap drag zoom is disabled.
829 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
830 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
831 EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_BEGIN));
833 event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
834 MotionEvent::ACTION_MOVE,
835 kFakeCoordX,
836 kFakeCoordY + 200);
837 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
838 EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
839 EXPECT_EQ(down_time_2 + kOneMicrosecond * 2,
840 GetMostRecentGestureEvent().time);
841 EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_UPDATE));
843 event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
844 MotionEvent::ACTION_UP,
845 kFakeCoordX,
846 kFakeCoordY + 200);
847 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
848 EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_END));
851 // Verify that double tap drag zoom feature is not invoked when the gesture
852 // handler is told to disable double tap gesture detection.
853 // The second tap sequence should be treated just as the first would be.
854 TEST_F(GestureProviderTest, NoDoubleTapDragZoomWhenDisabledOnPage) {
855 const base::TimeTicks down_time_1 = TimeTicks::Now();
856 const base::TimeTicks down_time_2 = down_time_1 + kOneMicrosecond * 2;
858 gesture_provider_->SetDoubleTapSupportForPageEnabled(false);
860 MockMotionEvent event =
861 ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
862 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
864 event = ObtainMotionEvent(down_time_1 + kOneMicrosecond,
865 MotionEvent::ACTION_UP,
866 kFakeCoordX,
867 kFakeCoordY);
868 gesture_provider_->OnTouchEvent(event);
870 event = ObtainMotionEvent(
871 down_time_2, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
872 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
874 event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
875 MotionEvent::ACTION_MOVE,
876 kFakeCoordX,
877 kFakeCoordY + 100);
879 // The move should become a scroll, as double tap drag zoom is disabled.
880 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
881 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
882 EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_BEGIN));
884 event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
885 MotionEvent::ACTION_MOVE,
886 kFakeCoordX,
887 kFakeCoordY + 200);
888 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
889 EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
890 EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_UPDATE));
892 event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
893 MotionEvent::ACTION_UP,
894 kFakeCoordX,
895 kFakeCoordY + 200);
896 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
897 EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_END));
900 // Verify that updating double tap support during a double tap drag zoom
901 // disables double tap detection after the gesture has ended.
902 TEST_F(GestureProviderTest, FixedPageScaleDuringDoubleTapDragZoom) {
903 base::TimeTicks down_time_1 = TimeTicks::Now();
904 base::TimeTicks down_time_2 = down_time_1 + kOneMicrosecond * 2;
906 // Start a double-tap drag gesture.
907 MockMotionEvent event =
908 ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
909 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
910 event = ObtainMotionEvent(down_time_1 + kOneMicrosecond,
911 MotionEvent::ACTION_UP,
912 kFakeCoordX,
913 kFakeCoordY);
914 gesture_provider_->OnTouchEvent(event);
915 event = ObtainMotionEvent(
916 down_time_2, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
917 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
918 event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
919 MotionEvent::ACTION_MOVE,
920 kFakeCoordX,
921 kFakeCoordY + 100);
922 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
923 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
924 EXPECT_EQ(ET_GESTURE_PINCH_BEGIN, GetMostRecentGestureEventType());
926 // Simulate setting a fixed page scale (or a mobile viewport);
927 // this should not disrupt the current double-tap gesture.
928 gesture_provider_->SetDoubleTapSupportForPageEnabled(false);
930 // Double tap zoom updates should continue.
931 event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
932 MotionEvent::ACTION_MOVE,
933 kFakeCoordX,
934 kFakeCoordY + 200);
935 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
936 EXPECT_EQ(ET_GESTURE_PINCH_UPDATE, GetMostRecentGestureEventType());
937 EXPECT_LT(1.f, GetMostRecentGestureEvent().details.scale());
938 event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
939 MotionEvent::ACTION_UP,
940 kFakeCoordX,
941 kFakeCoordY + 200);
942 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
943 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_PINCH_END));
944 EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
946 // The double-tap gesture has finished, but the page scale is fixed.
947 // The same event sequence should not generate any double tap getsures.
948 gestures_.clear();
949 down_time_1 += kOneMicrosecond * 40;
950 down_time_2 += kOneMicrosecond * 40;
952 // Start a double-tap drag gesture.
953 event = ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
954 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
955 event = ObtainMotionEvent(down_time_1 + kOneMicrosecond,
956 MotionEvent::ACTION_UP,
957 kFakeCoordX,
958 kFakeCoordY);
959 gesture_provider_->OnTouchEvent(event);
960 event = ObtainMotionEvent(
961 down_time_2, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
962 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
963 event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
964 MotionEvent::ACTION_MOVE,
965 kFakeCoordX,
966 kFakeCoordY + 100);
967 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
968 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
969 EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_BEGIN));
971 // Double tap zoom updates should not be sent.
972 // Instead, the second tap drag becomes a scroll gesture sequence.
973 event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
974 MotionEvent::ACTION_MOVE,
975 kFakeCoordX,
976 kFakeCoordY + 200);
977 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
978 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_UPDATE));
979 EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_UPDATE));
980 event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
981 MotionEvent::ACTION_UP,
982 kFakeCoordX,
983 kFakeCoordY + 200);
984 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
985 EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_END));
988 // Verify that pinch zoom sends the proper event sequence.
989 TEST_F(GestureProviderTest, PinchZoom) {
990 base::TimeTicks event_time = base::TimeTicks::Now();
991 const int scaled_touch_slop = GetTouchSlop();
992 int motion_event_id = 0;
994 gesture_provider_->SetMultiTouchSupportEnabled(true);
996 int secondary_coord_x = kFakeCoordX + 20 * scaled_touch_slop;
997 int secondary_coord_y = kFakeCoordY + 20 * scaled_touch_slop;
999 MockMotionEvent event =
1000 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
1001 event.SetId(++motion_event_id);
1002 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1003 EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1005 event = ObtainMotionEvent(event_time,
1006 MotionEvent::ACTION_POINTER_DOWN,
1007 kFakeCoordX,
1008 kFakeCoordY,
1009 secondary_coord_x,
1010 secondary_coord_y);
1011 event.SetId(++motion_event_id);
1013 gesture_provider_->OnTouchEvent(event);
1014 EXPECT_EQ(1U, GetReceivedGestureCount());
1016 secondary_coord_x += 5 * scaled_touch_slop;
1017 secondary_coord_y += 5 * scaled_touch_slop;
1018 event = ObtainMotionEvent(event_time,
1019 MotionEvent::ACTION_MOVE,
1020 kFakeCoordX,
1021 kFakeCoordY,
1022 secondary_coord_x,
1023 secondary_coord_y);
1024 event.SetId(++motion_event_id);
1026 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1027 EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
1028 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_PINCH_BEGIN));
1029 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
1030 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_UPDATE));
1032 secondary_coord_x += 2 * scaled_touch_slop;
1033 secondary_coord_y += 2 * scaled_touch_slop;
1034 event = ObtainMotionEvent(event_time,
1035 MotionEvent::ACTION_MOVE,
1036 kFakeCoordX,
1037 kFakeCoordY,
1038 secondary_coord_x,
1039 secondary_coord_y);
1040 event.SetId(++motion_event_id);
1042 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1043 EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
1044 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_UPDATE));
1045 EXPECT_EQ(ET_GESTURE_PINCH_UPDATE, GetMostRecentGestureEventType());
1046 EXPECT_LT(1.f, GetMostRecentGestureEvent().details.scale());
1048 event = ObtainMotionEvent(event_time,
1049 MotionEvent::ACTION_POINTER_UP,
1050 kFakeCoordX,
1051 kFakeCoordY,
1052 secondary_coord_x,
1053 secondary_coord_y);
1054 event.SetId(++motion_event_id);
1056 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1057 EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
1058 EXPECT_EQ(ET_GESTURE_PINCH_END, GetMostRecentGestureEventType());
1059 EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SCROLL_END));
1061 event = ObtainMotionEvent(event_time, MotionEvent::ACTION_UP);
1062 gesture_provider_->OnTouchEvent(event);
1063 EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
1066 // Verify that the timer of LONG_PRESS will be cancelled when scrolling begins
1067 // so LONG_PRESS and LONG_TAP won't be triggered.
1068 TEST_F(GestureProviderTest, GesturesCancelledAfterLongPressCausesLostFocus) {
1069 base::TimeTicks event_time = base::TimeTicks::Now();
1071 MockMotionEvent event =
1072 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
1073 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1075 const base::TimeDelta long_press_timeout =
1076 GetLongPressTimeout() + GetShowPressTimeout() + kOneMicrosecond;
1077 RunTasksAndWait(long_press_timeout);
1078 EXPECT_EQ(ET_GESTURE_LONG_PRESS, GetMostRecentGestureEventType());
1080 EXPECT_TRUE(CancelActiveTouchSequence());
1081 EXPECT_EQ(ET_GESTURE_TAP_CANCEL, GetMostRecentGestureEventType());
1083 event = ObtainMotionEvent(event_time + long_press_timeout,
1084 MotionEvent::ACTION_UP);
1085 gesture_provider_->OnTouchEvent(event);
1086 EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_TAP));
1089 // Verify that inserting a touch cancel event will trigger proper touch and
1090 // gesture sequence cancellation.
1091 TEST_F(GestureProviderTest, CancelActiveTouchSequence) {
1092 base::TimeTicks event_time = base::TimeTicks::Now();
1093 int motion_event_id = 0;
1095 EXPECT_FALSE(CancelActiveTouchSequence());
1096 EXPECT_EQ(0U, GetReceivedGestureCount());
1098 MockMotionEvent event =
1099 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
1100 event.SetId(++motion_event_id);
1101 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1102 EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1103 EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
1105 ASSERT_TRUE(CancelActiveTouchSequence());
1106 EXPECT_EQ(ET_GESTURE_TAP_CANCEL, GetMostRecentGestureEventType());
1107 EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
1109 // Subsequent MotionEvent's are dropped until ACTION_DOWN.
1110 event = ObtainMotionEvent(event_time + kOneMicrosecond,
1111 MotionEvent::ACTION_MOVE);
1112 EXPECT_FALSE(gesture_provider_->OnTouchEvent(event));
1114 event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
1115 MotionEvent::ACTION_UP);
1116 EXPECT_FALSE(gesture_provider_->OnTouchEvent(event));
1118 event = ObtainMotionEvent(event_time + kOneMicrosecond * 3,
1119 MotionEvent::ACTION_DOWN);
1120 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
1121 EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
1124 } // namespace ui