gesture_provider_unittest.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "base/basictypes.h" 6#include "base/logging.h" 7#include "base/memory/scoped_ptr.h" 8#include "base/message_loop/message_loop.h" 9#include "base/time/time.h" 10#include "testing/gtest/include/gtest/gtest.h" 11#include "ui/events/event_constants.h" 12#include "ui/events/gesture_detection/gesture_event_data.h" 13#include "ui/events/gesture_detection/gesture_provider.h" 14#include "ui/events/gesture_detection/mock_motion_event.h" 15#include "ui/events/gesture_detection/motion_event.h" 16#include "ui/gfx/geometry/point_f.h" 17 18using base::TimeDelta; 19using base::TimeTicks; 20 21namespace ui { 22namespace { 23 24const float kFakeCoordX = 42.f; 25const float kFakeCoordY = 24.f; 26const TimeDelta kOneSecond = TimeDelta::FromSeconds(1); 27const TimeDelta kOneMicrosecond = TimeDelta::FromMicroseconds(1); 28const TimeDelta kDeltaTimeForFlingSequences = TimeDelta::FromMilliseconds(5); 29 30GestureProvider::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; 36 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; 45} 46 47} // namespace 48 49class GestureProviderTest : public testing::Test, public GestureProviderClient { 50 public: 51 GestureProviderTest() {} 52 virtual ~GestureProviderTest() {} 53 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); 59 } 60 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); 68 } 69 70 static MockMotionEvent ObtainMotionEvent(base::TimeTicks event_time, 71 MotionEvent::Action action) { 72 return ObtainMotionEvent(event_time, action, kFakeCoordX, kFakeCoordY); 73 } 74 75 // Test 76 virtual void SetUp() OVERRIDE { 77 gesture_provider_.reset(new GestureProvider(GetDefaultConfig(), this)); 78 gesture_provider_->SetMultiTouchSupportEnabled(false); 79 } 80 81 virtual void TearDown() OVERRIDE { 82 gestures_.clear(); 83 gesture_provider_.reset(); 84 } 85 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); 91 } 92 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()); 98 } 99 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; 104 } 105 return false; 106 } 107 108 const GestureEventData& GetMostRecentGestureEvent() const { 109 EXPECT_FALSE(gestures_.empty()); 110 return gestures_.back(); 111 } 112 113 const EventType GetMostRecentGestureEventType() const { 114 EXPECT_FALSE(gestures_.empty()); 115 return gestures_.back().type; 116 } 117 118 size_t GetReceivedGestureCount() const { return gestures_.size(); } 119 120 const GestureEventData& GetReceivedGesture(size_t index) const { 121 EXPECT_LT(index, GetReceivedGestureCount()); 122 return gestures_[index]; 123 } 124 125 const GestureEventData* GetActiveScrollBeginEvent() const { 126 return active_scroll_begin_event_ ? active_scroll_begin_event_.get() : NULL; 127 } 128 129 const GestureProvider::Config& GetDefaultConfig() const { 130 static GestureProvider::Config sConfig = CreateDefaultConfig(); 131 return sConfig; 132 } 133 134 int GetTouchSlop() const { 135 return GetDefaultConfig().gesture_detector_config.scaled_touch_slop; 136 } 137 138 base::TimeDelta GetLongPressTimeout() const { 139 return GetDefaultConfig().gesture_detector_config.longpress_timeout; 140 } 141 142 base::TimeDelta GetShowPressTimeout() const { 143 return GetDefaultConfig().gesture_detector_config.showpress_timeout; 144 } 145 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 153 MockMotionEvent event = 154 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN); 155 156 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 157 158 event = ObtainMotionEvent(event_time + kOneSecond, 159 MotionEvent::ACTION_MOVE, 160 scroll_to_x, 161 scroll_to_y); 162 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 163 EXPECT_TRUE(gesture_provider_->IsScrollInProgress()); 164 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN)); 165 EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType()); 166 ASSERT_EQ(4U, GetReceivedGestureCount()) << "Only TapDown, TapCancel, " 167 "ScrollBegin and ScrollBy " 168 "should have been sent"; 169 170 EXPECT_EQ(ET_GESTURE_TAP_CANCEL, GetReceivedGesture(1).type); 171 EXPECT_EQ(ET_GESTURE_SCROLL_BEGIN, GetReceivedGesture(2).type); 172 EXPECT_EQ(event_time + kOneSecond, GetReceivedGesture(2).time) 173 << "ScrollBegin should have the time of the ACTION_MOVE"; 174 175 event = ObtainMotionEvent( 176 event_time + kOneSecond, end_action_type, scroll_to_x, scroll_to_y); 177 gesture_provider_->OnTouchEvent(event); 178 EXPECT_FALSE(gesture_provider_->IsScrollInProgress()); 179 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_END)); 180 EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType()); 181 } 182 183 static void RunTasksAndWait(base::TimeDelta delay) { 184 base::MessageLoop::current()->PostDelayedTask( 185 FROM_HERE, base::MessageLoop::QuitClosure(), delay); 186 base::MessageLoop::current()->Run(); 187 } 188 189 std::vector<GestureEventData> gestures_; 190 scoped_ptr<GestureProvider> gesture_provider_; 191 scoped_ptr<GestureEventData> active_scroll_begin_event_; 192 base::MessageLoopForUI message_loop_; 193}; 194 195// Verify that a DOWN followed shortly by an UP will trigger a single tap. 196TEST_F(GestureProviderTest, GestureTapTap) { 197 base::TimeTicks event_time = base::TimeTicks::Now(); 198 199 gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false); 200 201 MockMotionEvent event = 202 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN); 203 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 204 EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType()); 205 206 event = ObtainMotionEvent(event_time + kOneMicrosecond, 207 MotionEvent::ACTION_UP); 208 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 209 EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType()); 210 // Ensure tap details have been set. 211 EXPECT_EQ(10, GetMostRecentGestureEvent().details.tap.width); 212 EXPECT_EQ(10, GetMostRecentGestureEvent().details.tap.height); 213 EXPECT_EQ(1, GetMostRecentGestureEvent().details.tap.tap_count); 214 215} 216 217// Verify that a DOWN followed shortly by an UP will trigger 218// a ET_GESTURE_TAP_UNCONFIRMED event if double-tap is enabled. 219TEST_F(GestureProviderTest, GestureTapTapWithDelay) { 220 base::TimeTicks event_time = base::TimeTicks::Now(); 221 222 gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true); 223 224 MockMotionEvent event = 225 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN); 226 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 227 EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType()); 228 229 event = ObtainMotionEvent(event_time + kOneMicrosecond, 230 MotionEvent::ACTION_UP); 231 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 232 EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType()); 233 // Ensure tap details have been set. 234 EXPECT_EQ(10, GetMostRecentGestureEvent().details.tap.width); 235 EXPECT_EQ(10, GetMostRecentGestureEvent().details.tap.height); 236 EXPECT_EQ(1, GetMostRecentGestureEvent().details.tap.tap_count); 237 238 EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_TAP)); 239} 240 241// Verify that a DOWN followed by a MOVE will trigger fling (but not LONG). 242TEST_F(GestureProviderTest, GestureFlingAndCancelLongPress) { 243 base::TimeTicks event_time = TimeTicks::Now(); 244 base::TimeDelta delta_time = kDeltaTimeForFlingSequences; 245 246 MockMotionEvent event = 247 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN); 248 249 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 250 EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType()); 251 252 event = ObtainMotionEvent(event_time + delta_time, 253 MotionEvent::ACTION_MOVE, 254 kFakeCoordX * 10, 255 kFakeCoordY * 10); 256 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 257 258 event = ObtainMotionEvent(event_time + delta_time * 2, 259 MotionEvent::ACTION_UP, 260 kFakeCoordX * 10, 261 kFakeCoordY * 10); 262 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 263 EXPECT_EQ(ET_SCROLL_FLING_START, GetMostRecentGestureEventType()); 264 EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_PRESS)); 265} 266 267// Verify that for a normal scroll the following events are sent: 268// - ET_GESTURE_SCROLL_BEGIN 269// - ET_GESTURE_SCROLL_UPDATE 270// - ET_GESTURE_SCROLL_END 271TEST_F(GestureProviderTest, ScrollEventActionUpSequence) { 272 CheckScrollEventSequenceForEndActionType(MotionEvent::ACTION_UP); 273} 274 275// Verify that for a cancelled scroll the following events are sent: 276// - ET_GESTURE_SCROLL_BEGIN 277// - ET_GESTURE_SCROLL_UPDATE 278// - ET_GESTURE_SCROLL_END 279TEST_F(GestureProviderTest, ScrollEventActionCancelSequence) { 280 CheckScrollEventSequenceForEndActionType(MotionEvent::ACTION_CANCEL); 281} 282 283// Verify that for a normal fling (fling after scroll) the following events are 284// sent: 285// - ET_GESTURE_SCROLL_BEGIN 286// - ET_SCROLL_FLING_START 287TEST_F(GestureProviderTest, FlingEventSequence) { 288 base::TimeTicks event_time = base::TimeTicks::Now(); 289 base::TimeDelta delta_time = kDeltaTimeForFlingSequences; 290 291 MockMotionEvent event = 292 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN); 293 294 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 295 296 event = ObtainMotionEvent(event_time + delta_time, 297 MotionEvent::ACTION_MOVE, 298 kFakeCoordX * 5, 299 kFakeCoordY * 5); 300 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 301 EXPECT_TRUE(gesture_provider_->IsScrollInProgress()); 302 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN)); 303 EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType()); 304 ASSERT_EQ(4U, GetReceivedGestureCount()); 305 ASSERT_EQ(ET_GESTURE_SCROLL_BEGIN, GetReceivedGesture(2).type); 306 307 // We don't want to take a dependency here on exactly how hints are calculated 308 // for a fling (eg. may depend on velocity), so just validate the direction. 309 int hint_x = GetReceivedGesture(2).details.scroll_begin.delta_x_hint; 310 int hint_y = GetReceivedGesture(2).details.scroll_begin.delta_y_hint; 311 EXPECT_TRUE(hint_x > 0 && hint_y > 0 && hint_x > hint_y) 312 << "ScrollBegin hint should be in positive X axis"; 313 314 event = ObtainMotionEvent(event_time + delta_time * 2, 315 MotionEvent::ACTION_UP, 316 kFakeCoordX * 10, 317 kFakeCoordY * 10); 318 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 319 EXPECT_FALSE(gesture_provider_->IsScrollInProgress()); 320 EXPECT_EQ(ET_SCROLL_FLING_START, GetMostRecentGestureEventType()); 321 EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SCROLL_END)); 322 EXPECT_EQ(event_time + delta_time * 2, GetMostRecentGestureEvent().time) 323 << "FlingStart should have the time of the ACTION_UP"; 324} 325 326TEST_F(GestureProviderTest, TapCancelledWhenWindowFocusLost) { 327 const base::TimeTicks event_time = TimeTicks::Now(); 328 329 MockMotionEvent event = 330 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN); 331 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 332 EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType()); 333 334 RunTasksAndWait(GetLongPressTimeout() + GetShowPressTimeout() + 335 kOneMicrosecond); 336 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SHOW_PRESS)); 337 EXPECT_EQ(ET_GESTURE_LONG_PRESS, GetMostRecentGestureEventType()); 338 339 // The long press triggers window focus loss by opening a context menu 340 EXPECT_TRUE(CancelActiveTouchSequence()); 341 EXPECT_EQ(ET_GESTURE_TAP_CANCEL, GetMostRecentGestureEventType()); 342} 343 344TEST_F(GestureProviderTest, TapCancelledWhenScrollBegins) { 345 base::TimeTicks event_time = base::TimeTicks::Now(); 346 347 MockMotionEvent event = 348 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN); 349 350 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 351 352 EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType()); 353 event = ObtainMotionEvent(event_time + kOneMicrosecond, 354 MotionEvent::ACTION_MOVE, 355 kFakeCoordX + 50, 356 kFakeCoordY + 50); 357 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 358 359 EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType()); 360 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_TAP_CANCEL)); 361} 362 363TEST_F(GestureProviderTest, DoubleTap) { 364 base::TimeTicks event_time = base::TimeTicks::Now(); 365 366 MockMotionEvent event = 367 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN); 368 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 369 370 EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType()); 371 372 event = ObtainMotionEvent(event_time + kOneMicrosecond, 373 MotionEvent::ACTION_UP, 374 kFakeCoordX, 375 kFakeCoordY); 376 gesture_provider_->OnTouchEvent(event); 377 EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType()); 378 379 event = ObtainMotionEvent(event_time + kOneMicrosecond * 2, 380 MotionEvent::ACTION_DOWN, 381 kFakeCoordX, 382 kFakeCoordY); 383 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 384 EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType()); 385 386 // Moving a very small amount of distance should not trigger the double tap 387 // drag zoom mode. 388 event = ObtainMotionEvent(event_time + kOneMicrosecond * 3, 389 MotionEvent::ACTION_MOVE, 390 kFakeCoordX, 391 kFakeCoordY + 1); 392 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 393 EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType()); 394 395 event = ObtainMotionEvent(event_time + kOneMicrosecond * 3, 396 MotionEvent::ACTION_UP, 397 kFakeCoordX, 398 kFakeCoordY + 1); 399 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 400 401 const GestureEventData& double_tap = GetMostRecentGestureEvent(); 402 EXPECT_EQ(ET_GESTURE_DOUBLE_TAP, double_tap.type); 403 // Ensure tap details have been set. 404 EXPECT_EQ(10, double_tap.details.tap.width); 405 EXPECT_EQ(10, double_tap.details.tap.height); 406 EXPECT_EQ(1, double_tap.details.tap.tap_count); 407} 408 409TEST_F(GestureProviderTest, DoubleTapDragZoom) { 410 const base::TimeTicks down_time_1 = TimeTicks::Now(); 411 const base::TimeTicks down_time_2 = down_time_1 + kOneMicrosecond * 2; 412 413 MockMotionEvent event = 414 ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN); 415 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 416 417 event = ObtainMotionEvent(down_time_1 + kOneMicrosecond, 418 MotionEvent::ACTION_UP, 419 kFakeCoordX, 420 kFakeCoordY); 421 gesture_provider_->OnTouchEvent(event); 422 EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType()); 423 424 event = ObtainMotionEvent( 425 down_time_2, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY); 426 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 427 EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType()); 428 429 event = ObtainMotionEvent(down_time_2 + kOneMicrosecond, 430 MotionEvent::ACTION_MOVE, 431 kFakeCoordX, 432 kFakeCoordY + 100); 433 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 434 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN)); 435 const GestureEventData* scroll_begin_gesture = GetActiveScrollBeginEvent(); 436 ASSERT_TRUE(!!scroll_begin_gesture); 437 EXPECT_EQ(0, scroll_begin_gesture->details.scroll_begin.delta_x_hint); 438 EXPECT_EQ(100, scroll_begin_gesture->details.scroll_begin.delta_y_hint); 439 EXPECT_EQ(ET_GESTURE_PINCH_BEGIN, GetMostRecentGestureEventType()); 440 441 event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2, 442 MotionEvent::ACTION_MOVE, 443 kFakeCoordX, 444 kFakeCoordY + 200); 445 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 446 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_UPDATE)); 447 EXPECT_EQ(ET_GESTURE_PINCH_UPDATE, GetMostRecentGestureEventType()); 448 449 event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3, 450 MotionEvent::ACTION_UP, 451 kFakeCoordX, 452 kFakeCoordY + 200); 453 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 454 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_PINCH_END)); 455 EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType()); 456} 457 458TEST_F(GestureProviderTest, DoubleTapDragZoomCancelledOnSecondaryPointerDown) { 459 const base::TimeTicks down_time_1 = TimeTicks::Now(); 460 const base::TimeTicks down_time_2 = down_time_1 + kOneMicrosecond * 2; 461 462 MockMotionEvent event = 463 ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN); 464 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 465 EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType()); 466 467 event = ObtainMotionEvent(down_time_1 + kOneMicrosecond, 468 MotionEvent::ACTION_UP); 469 gesture_provider_->OnTouchEvent(event); 470 EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType()); 471 472 event = ObtainMotionEvent(down_time_2, MotionEvent::ACTION_DOWN); 473 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 474 EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType()); 475 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_TAP_CANCEL)); 476 477 event = ObtainMotionEvent(down_time_2 + kOneMicrosecond, 478 MotionEvent::ACTION_MOVE, 479 kFakeCoordX, 480 kFakeCoordY - 30); 481 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 482 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN)); 483 EXPECT_EQ(ET_GESTURE_PINCH_BEGIN, GetMostRecentGestureEventType()); 484 485 event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2, 486 MotionEvent::ACTION_POINTER_DOWN, 487 kFakeCoordX, 488 kFakeCoordY - 30, 489 kFakeCoordX + 50, 490 kFakeCoordY + 50); 491 gesture_provider_->OnTouchEvent(event); 492 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_PINCH_END)); 493 EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType()); 494 const size_t gesture_count = GetReceivedGestureCount(); 495 496 event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3, 497 MotionEvent::ACTION_POINTER_UP, 498 kFakeCoordX, 499 kFakeCoordY - 30, 500 kFakeCoordX + 50, 501 kFakeCoordY + 50); 502 gesture_provider_->OnTouchEvent(event); 503 EXPECT_EQ(gesture_count, GetReceivedGestureCount()); 504} 505 506// Generate a scroll gesture and verify that the resulting scroll motion event 507// has both absolute and relative position information. 508TEST_F(GestureProviderTest, ScrollUpdateValues) { 509 const int delta_x = 16; 510 const int delta_y = 84; 511 512 const base::TimeTicks event_time = TimeTicks::Now(); 513 514 MockMotionEvent event = 515 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN); 516 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 517 518 // Move twice so that we get two ET_GESTURE_SCROLL_UPDATE events and can 519 // compare the relative and absolute coordinates. 520 event = ObtainMotionEvent(event_time + kOneMicrosecond, 521 MotionEvent::ACTION_MOVE, 522 kFakeCoordX - delta_x / 2, 523 kFakeCoordY - delta_y / 2); 524 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 525 526 event = ObtainMotionEvent(event_time + kOneMicrosecond * 2, 527 MotionEvent::ACTION_MOVE, 528 kFakeCoordX - delta_x, 529 kFakeCoordY - delta_y); 530 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 531 532 // Make sure the reported gesture event has all the expected details. 533 ASSERT_LT(0U, GetReceivedGestureCount()); 534 GestureEventData gesture = GetMostRecentGestureEvent(); 535 EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, gesture.type); 536 EXPECT_EQ(event_time + kOneMicrosecond * 2, gesture.time); 537 EXPECT_EQ(kFakeCoordX - delta_x, gesture.x); 538 EXPECT_EQ(kFakeCoordY - delta_y, gesture.y); 539 540 // No horizontal delta because of snapping. 541 EXPECT_EQ(0, gesture.details.scroll_update.delta_x); 542 EXPECT_EQ(-delta_y / 2, gesture.details.scroll_update.delta_y); 543} 544 545// Verify that fractional scroll deltas are rounded as expected and that 546// fractional scrolling doesn't break scroll snapping. 547TEST_F(GestureProviderTest, FractionalScroll) { 548 const float delta_x = 0.4f; 549 const float delta_y = 5.2f; 550 551 const base::TimeTicks event_time = TimeTicks::Now(); 552 553 MockMotionEvent event = 554 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN); 555 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 556 557 // Skip past the touch slop and move back. 558 event = ObtainMotionEvent(event_time, 559 MotionEvent::ACTION_MOVE, 560 kFakeCoordX, 561 kFakeCoordY + 100); 562 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 563 event = ObtainMotionEvent(event_time, 564 MotionEvent::ACTION_MOVE); 565 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 566 567 // Now move up slowly, mostly vertically but with a (fractional) bit of 568 // horizontal motion. 569 for(int i = 1; i <= 10; i++) { 570 event = ObtainMotionEvent(event_time + kOneMicrosecond * i, 571 MotionEvent::ACTION_MOVE, 572 kFakeCoordX + delta_x * i, 573 kFakeCoordY + delta_y * i); 574 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 575 576 ASSERT_LT(0U, GetReceivedGestureCount()); 577 GestureEventData gesture = GetMostRecentGestureEvent(); 578 EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, gesture.type); 579 EXPECT_EQ(event_time + kOneMicrosecond * i, gesture.time); 580 581 // Verify that the event co-ordinates are still the precise values we 582 // supplied. 583 EXPECT_EQ(kFakeCoordX + delta_x * i, gesture.x); 584 EXPECT_EQ(kFakeCoordY + delta_y * i, gesture.y); 585 586 // Verify that we're scrolling vertically by the expected amount 587 // (modulo rounding). 588 EXPECT_GE(gesture.details.scroll_update.delta_y, (int)delta_y); 589 EXPECT_LE(gesture.details.scroll_update.delta_y, ((int)delta_y) + 1); 590 591 // And that there has been no horizontal motion at all. 592 EXPECT_EQ(0, gesture.details.scroll_update.delta_x); 593 } 594} 595 596// Generate a scroll gesture and verify that the resulting scroll begin event 597// has the expected hint values. 598TEST_F(GestureProviderTest, ScrollBeginValues) { 599 const int delta_x = 13; 600 const int delta_y = 89; 601 602 const base::TimeTicks event_time = TimeTicks::Now(); 603 604 MockMotionEvent event = 605 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN); 606 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 607 608 // Move twice such that the first event isn't sufficient to start 609 // scrolling on it's own. 610 event = ObtainMotionEvent(event_time + kOneMicrosecond, 611 MotionEvent::ACTION_MOVE, 612 kFakeCoordX + 2, 613 kFakeCoordY + 1); 614 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 615 EXPECT_FALSE(gesture_provider_->IsScrollInProgress()); 616 617 event = ObtainMotionEvent(event_time + kOneMicrosecond * 2, 618 MotionEvent::ACTION_MOVE, 619 kFakeCoordX + delta_x, 620 kFakeCoordY + delta_y); 621 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 622 EXPECT_TRUE(gesture_provider_->IsScrollInProgress()); 623 624 const GestureEventData* scroll_begin_gesture = GetActiveScrollBeginEvent(); 625 ASSERT_TRUE(!!scroll_begin_gesture); 626 EXPECT_EQ(delta_x, scroll_begin_gesture->details.scroll_begin.delta_x_hint); 627 EXPECT_EQ(delta_y, scroll_begin_gesture->details.scroll_begin.delta_y_hint); 628} 629 630TEST_F(GestureProviderTest, LongPressAndTapCancelledWhenScrollBegins) { 631 base::TimeTicks event_time = base::TimeTicks::Now(); 632 633 MockMotionEvent event = 634 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN); 635 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 636 event = ObtainMotionEvent(event_time + kOneMicrosecond, 637 MotionEvent::ACTION_MOVE, 638 kFakeCoordX * 5, 639 kFakeCoordY * 5); 640 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 641 event = ObtainMotionEvent(event_time + kOneMicrosecond * 2, 642 MotionEvent::ACTION_MOVE, 643 kFakeCoordX * 10, 644 kFakeCoordY * 10); 645 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 646 647 const base::TimeDelta long_press_timeout = 648 GetLongPressTimeout() + GetShowPressTimeout() + kOneMicrosecond; 649 RunTasksAndWait(long_press_timeout); 650 651 // No LONG_TAP as the LONG_PRESS timer is cancelled. 652 EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_PRESS)); 653 EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_TAP)); 654} 655 656// Verify that LONG_TAP is triggered after LONG_PRESS followed by an UP. 657TEST_F(GestureProviderTest, GestureLongTap) { 658 base::TimeTicks event_time = base::TimeTicks::Now(); 659 660 MockMotionEvent event = 661 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN); 662 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 663 664 const base::TimeDelta long_press_timeout = 665 GetLongPressTimeout() + GetShowPressTimeout() + kOneMicrosecond; 666 RunTasksAndWait(long_press_timeout); 667 668 EXPECT_EQ(ET_GESTURE_LONG_PRESS, GetMostRecentGestureEventType()); 669 670 event = ObtainMotionEvent(event_time + kOneSecond, MotionEvent::ACTION_UP); 671 gesture_provider_->OnTouchEvent(event); 672 EXPECT_EQ(ET_GESTURE_LONG_TAP, GetMostRecentGestureEventType()); 673} 674 675TEST_F(GestureProviderTest, GestureLongPressDoesNotPreventScrolling) { 676 base::TimeTicks event_time = base::TimeTicks::Now(); 677 678 MockMotionEvent event = 679 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN); 680 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 681 682 const base::TimeDelta long_press_timeout = 683 GetLongPressTimeout() + GetShowPressTimeout() + kOneMicrosecond; 684 RunTasksAndWait(long_press_timeout); 685 686 EXPECT_EQ(ET_GESTURE_LONG_PRESS, GetMostRecentGestureEventType()); 687 event = ObtainMotionEvent(event_time + long_press_timeout, 688 MotionEvent::ACTION_MOVE, 689 kFakeCoordX + 100, 690 kFakeCoordY + 100); 691 gesture_provider_->OnTouchEvent(event); 692 693 EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType()); 694 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN)); 695 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_TAP_CANCEL)); 696 697 event = ObtainMotionEvent(event_time + long_press_timeout, 698 MotionEvent::ACTION_UP); 699 gesture_provider_->OnTouchEvent(event); 700 EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_TAP)); 701} 702 703TEST_F(GestureProviderTest, NoGestureLongPressDuringDoubleTap) { 704 base::TimeTicks event_time = base::TimeTicks::Now(); 705 706 MockMotionEvent event = ObtainMotionEvent( 707 event_time, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY); 708 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 709 710 event = ObtainMotionEvent(event_time + kOneMicrosecond, 711 MotionEvent::ACTION_UP, 712 kFakeCoordX, 713 kFakeCoordY); 714 gesture_provider_->OnTouchEvent(event); 715 EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType()); 716 717 event = ObtainMotionEvent(event_time + kOneMicrosecond, 718 MotionEvent::ACTION_DOWN, 719 kFakeCoordX, 720 kFakeCoordY); 721 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 722 EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType()); 723 EXPECT_TRUE(gesture_provider_->IsDoubleTapInProgress()); 724 725 const base::TimeDelta long_press_timeout = 726 GetLongPressTimeout() + GetShowPressTimeout() + kOneMicrosecond; 727 RunTasksAndWait(long_press_timeout); 728 EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_PRESS)); 729 730 event = ObtainMotionEvent(event_time + long_press_timeout, 731 MotionEvent::ACTION_MOVE, 732 kFakeCoordX + 20, 733 kFakeCoordY + 20); 734 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 735 EXPECT_EQ(ET_GESTURE_PINCH_BEGIN, GetMostRecentGestureEventType()); 736 EXPECT_TRUE(gesture_provider_->IsDoubleTapInProgress()); 737 738 event = ObtainMotionEvent(event_time + long_press_timeout + kOneMicrosecond, 739 MotionEvent::ACTION_UP, 740 kFakeCoordX, 741 kFakeCoordY + 1); 742 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 743 EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType()); 744 EXPECT_FALSE(gesture_provider_->IsDoubleTapInProgress()); 745} 746 747// Verify that the touch slop region is removed from the first scroll delta to 748// avoid a jump when starting to scroll. 749TEST_F(GestureProviderTest, TouchSlopRemovedFromScroll) { 750 const int scaled_touch_slop = GetTouchSlop(); 751 const int scroll_delta = 5; 752 753 base::TimeTicks event_time = base::TimeTicks::Now(); 754 755 MockMotionEvent event = 756 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN); 757 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 758 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)); 764 765 EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType()); 766 GestureEventData gesture = GetMostRecentGestureEvent(); 767 EXPECT_EQ(0, gesture.details.scroll_update.delta_x); 768 EXPECT_EQ(scroll_delta, gesture.details.scroll_update.delta_y); 769} 770 771TEST_F(GestureProviderTest, NoDoubleTapWhenExplicitlyDisabled) { 772 gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false); 773 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()); 780 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()); 787 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()); 794 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()); 801} 802 803TEST_F(GestureProviderTest, NoDoubleTapDragZoomWhenDisabledOnPlatform) { 804 const base::TimeTicks down_time_1 = TimeTicks::Now(); 805 const base::TimeTicks down_time_2 = down_time_1 + kOneMicrosecond * 2; 806 807 gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false); 808 809 MockMotionEvent event = 810 ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN); 811 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 812 813 event = ObtainMotionEvent(down_time_1 + kOneMicrosecond, 814 MotionEvent::ACTION_UP, 815 kFakeCoordX, 816 kFakeCoordY); 817 gesture_provider_->OnTouchEvent(event); 818 819 event = ObtainMotionEvent( 820 down_time_2, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY); 821 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 822 823 event = ObtainMotionEvent(down_time_2 + kOneMicrosecond, 824 MotionEvent::ACTION_MOVE, 825 kFakeCoordX, 826 kFakeCoordY + 100); 827 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)); 832 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)); 842 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)); 849} 850 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. 854TEST_F(GestureProviderTest, NoDoubleTapDragZoomWhenDisabledOnPage) { 855 const base::TimeTicks down_time_1 = TimeTicks::Now(); 856 const base::TimeTicks down_time_2 = down_time_1 + kOneMicrosecond * 2; 857 858 gesture_provider_->SetDoubleTapSupportForPageEnabled(false); 859 860 MockMotionEvent event = 861 ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN); 862 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 863 864 event = ObtainMotionEvent(down_time_1 + kOneMicrosecond, 865 MotionEvent::ACTION_UP, 866 kFakeCoordX, 867 kFakeCoordY); 868 gesture_provider_->OnTouchEvent(event); 869 870 event = ObtainMotionEvent( 871 down_time_2, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY); 872 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 873 874 event = ObtainMotionEvent(down_time_2 + kOneMicrosecond, 875 MotionEvent::ACTION_MOVE, 876 kFakeCoordX, 877 kFakeCoordY + 100); 878 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)); 883 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)); 891 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)); 898} 899 900// Verify that updating double tap support during a double tap drag zoom 901// disables double tap detection after the gesture has ended. 902TEST_F(GestureProviderTest, FixedPageScaleDuringDoubleTapDragZoom) { 903 base::TimeTicks down_time_1 = TimeTicks::Now(); 904 base::TimeTicks down_time_2 = down_time_1 + kOneMicrosecond * 2; 905 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()); 925 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); 929 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_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_UPDATE)); 937 EXPECT_EQ(ET_GESTURE_PINCH_UPDATE, GetMostRecentGestureEventType()); 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()); 945 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; 951 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)); 970 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)); 986} 987 988// Verify that pinch zoom sends the proper event sequence. 989TEST_F(GestureProviderTest, PinchZoom) { 990 base::TimeTicks event_time = base::TimeTicks::Now(); 991 const int scaled_touch_slop = GetTouchSlop(); 992 993 gesture_provider_->SetMultiTouchSupportEnabled(true); 994 995 int secondary_coord_x = kFakeCoordX + 20 * scaled_touch_slop; 996 int secondary_coord_y = kFakeCoordY + 20 * scaled_touch_slop; 997 998 MockMotionEvent event = 999 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN); 1000 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 1001 EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType()); 1002 1003 event = ObtainMotionEvent(event_time, 1004 MotionEvent::ACTION_POINTER_DOWN, 1005 kFakeCoordX, 1006 kFakeCoordY, 1007 secondary_coord_x, 1008 secondary_coord_y); 1009 gesture_provider_->OnTouchEvent(event); 1010 EXPECT_EQ(1U, GetReceivedGestureCount()); 1011 1012 secondary_coord_x += 5 * scaled_touch_slop; 1013 secondary_coord_y += 5 * scaled_touch_slop; 1014 1015 event = ObtainMotionEvent(event_time, 1016 MotionEvent::ACTION_MOVE, 1017 kFakeCoordX, 1018 kFakeCoordY, 1019 secondary_coord_x, 1020 secondary_coord_y); 1021 1022 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 1023 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_PINCH_BEGIN)); 1024 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN)); 1025 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_PINCH_UPDATE)); 1026 EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_UPDATE)); 1027 1028 event = ObtainMotionEvent(event_time, 1029 MotionEvent::ACTION_POINTER_UP, 1030 kFakeCoordX, 1031 kFakeCoordY, 1032 secondary_coord_x, 1033 secondary_coord_y); 1034 1035 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 1036 EXPECT_EQ(ET_GESTURE_PINCH_END, GetMostRecentGestureEventType()); 1037 EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SCROLL_END)); 1038 1039 event = ObtainMotionEvent(event_time, MotionEvent::ACTION_UP); 1040 gesture_provider_->OnTouchEvent(event); 1041 EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType()); 1042} 1043 1044// Verify that the timer of LONG_PRESS will be cancelled when scrolling begins 1045// so LONG_PRESS and LONG_TAP won't be triggered. 1046TEST_F(GestureProviderTest, GesturesCancelledAfterLongPressCausesLostFocus) { 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 const base::TimeDelta long_press_timeout = 1054 GetLongPressTimeout() + GetShowPressTimeout() + kOneMicrosecond; 1055 RunTasksAndWait(long_press_timeout); 1056 EXPECT_EQ(ET_GESTURE_LONG_PRESS, GetMostRecentGestureEventType()); 1057 1058 EXPECT_TRUE(CancelActiveTouchSequence()); 1059 EXPECT_EQ(ET_GESTURE_TAP_CANCEL, GetMostRecentGestureEventType()); 1060 1061 event = ObtainMotionEvent(event_time + long_press_timeout, 1062 MotionEvent::ACTION_UP); 1063 gesture_provider_->OnTouchEvent(event); 1064 EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_TAP)); 1065} 1066 1067// Verify that inserting a touch cancel event will trigger proper touch and 1068// gesture sequence cancellation. 1069TEST_F(GestureProviderTest, CancelActiveTouchSequence) { 1070 base::TimeTicks event_time = base::TimeTicks::Now(); 1071 1072 EXPECT_FALSE(CancelActiveTouchSequence()); 1073 EXPECT_EQ(0U, GetReceivedGestureCount()); 1074 1075 MockMotionEvent event = 1076 ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN); 1077 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 1078 EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType()); 1079 1080 ASSERT_TRUE(CancelActiveTouchSequence()); 1081 EXPECT_EQ(ET_GESTURE_TAP_CANCEL, GetMostRecentGestureEventType()); 1082 1083 // Subsequent MotionEvent's are dropped until ACTION_DOWN. 1084 event = ObtainMotionEvent(event_time + kOneMicrosecond, 1085 MotionEvent::ACTION_MOVE); 1086 EXPECT_FALSE(gesture_provider_->OnTouchEvent(event)); 1087 1088 event = ObtainMotionEvent(event_time + kOneMicrosecond * 2, 1089 MotionEvent::ACTION_UP); 1090 EXPECT_FALSE(gesture_provider_->OnTouchEvent(event)); 1091 1092 event = ObtainMotionEvent(event_time + kOneMicrosecond * 3, 1093 MotionEvent::ACTION_DOWN); 1094 EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); 1095 EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType()); 1096} 1097 1098} // namespace ui 1099