1 // Copyright 2013 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 "content/renderer/input/input_handler_proxy.h" 6 7 #include "base/basictypes.h" 8 #include "base/memory/scoped_ptr.h" 9 #include "cc/base/swap_promise_monitor.h" 10 #include "content/common/input/did_overscroll_params.h" 11 #include "content/renderer/input/input_handler_proxy_client.h" 12 #include "testing/gmock/include/gmock/gmock.h" 13 #include "testing/gtest/include/gtest/gtest.h" 14 #include "third_party/WebKit/public/platform/WebFloatPoint.h" 15 #include "third_party/WebKit/public/platform/WebFloatSize.h" 16 #include "third_party/WebKit/public/platform/WebGestureCurve.h" 17 #include "third_party/WebKit/public/platform/WebPoint.h" 18 #include "third_party/WebKit/public/web/WebInputEvent.h" 19 #include "ui/events/latency_info.h" 20 21 using blink::WebActiveWheelFlingParameters; 22 using blink::WebFloatPoint; 23 using blink::WebFloatSize; 24 using blink::WebGestureDevice; 25 using blink::WebGestureEvent; 26 using blink::WebInputEvent; 27 using blink::WebKeyboardEvent; 28 using blink::WebMouseWheelEvent; 29 using blink::WebPoint; 30 using blink::WebSize; 31 using blink::WebTouchEvent; 32 using blink::WebTouchPoint; 33 34 namespace content { 35 namespace { 36 37 double InSecondsF(const base::TimeTicks& time) { 38 return (time - base::TimeTicks()).InSecondsF(); 39 } 40 41 WebGestureEvent CreateFling(base::TimeTicks timestamp, 42 WebGestureDevice source_device, 43 WebFloatPoint velocity, 44 WebPoint point, 45 WebPoint global_point, 46 int modifiers) { 47 WebGestureEvent fling; 48 fling.type = WebInputEvent::GestureFlingStart; 49 fling.sourceDevice = source_device; 50 fling.timeStampSeconds = (timestamp - base::TimeTicks()).InSecondsF(); 51 fling.data.flingStart.velocityX = velocity.x; 52 fling.data.flingStart.velocityY = velocity.y; 53 fling.x = point.x; 54 fling.y = point.y; 55 fling.globalX = global_point.x; 56 fling.globalY = global_point.y; 57 fling.modifiers = modifiers; 58 return fling; 59 } 60 61 WebGestureEvent CreateFling(WebGestureDevice source_device, 62 WebFloatPoint velocity, 63 WebPoint point, 64 WebPoint global_point, 65 int modifiers) { 66 return CreateFling(base::TimeTicks(), 67 source_device, 68 velocity, 69 point, 70 global_point, 71 modifiers); 72 } 73 74 class MockInputHandler : public cc::InputHandler { 75 public: 76 MockInputHandler() {} 77 virtual ~MockInputHandler() {} 78 79 MOCK_METHOD0(PinchGestureBegin, void()); 80 MOCK_METHOD2(PinchGestureUpdate, 81 void(float magnify_delta, const gfx::Point& anchor)); 82 MOCK_METHOD0(PinchGestureEnd, void()); 83 84 MOCK_METHOD0(SetNeedsAnimate, void()); 85 86 MOCK_METHOD2(ScrollBegin, 87 ScrollStatus(const gfx::Point& viewport_point, 88 cc::InputHandler::ScrollInputType type)); 89 MOCK_METHOD2(ScrollBy, 90 bool(const gfx::Point& viewport_point, 91 const gfx::Vector2dF& scroll_delta)); 92 MOCK_METHOD2(ScrollVerticallyByPage, 93 bool(const gfx::Point& viewport_point, 94 cc::ScrollDirection direction)); 95 MOCK_METHOD0(ScrollEnd, void()); 96 MOCK_METHOD0(FlingScrollBegin, cc::InputHandler::ScrollStatus()); 97 98 virtual scoped_ptr<cc::SwapPromiseMonitor> 99 CreateLatencyInfoSwapPromiseMonitor(ui::LatencyInfo* latency) OVERRIDE { 100 return scoped_ptr<cc::SwapPromiseMonitor>(); 101 } 102 103 virtual void BindToClient(cc::InputHandlerClient* client) OVERRIDE {} 104 105 virtual void StartPageScaleAnimation(const gfx::Vector2d& target_offset, 106 bool anchor_point, 107 float page_scale, 108 base::TimeDelta duration) OVERRIDE {} 109 110 virtual void MouseMoveAt(const gfx::Point& mouse_position) OVERRIDE {} 111 112 MOCK_METHOD2(IsCurrentlyScrollingLayerAt, 113 bool(const gfx::Point& point, 114 cc::InputHandler::ScrollInputType type)); 115 116 MOCK_METHOD1(HaveTouchEventHandlersAt, bool(const gfx::Point& point)); 117 118 virtual void SetRootLayerScrollOffsetDelegate( 119 cc::LayerScrollOffsetDelegate* root_layer_scroll_offset_delegate) 120 OVERRIDE {} 121 122 virtual void OnRootLayerDelegatedScrollOffsetChanged() OVERRIDE {} 123 124 DISALLOW_COPY_AND_ASSIGN(MockInputHandler); 125 }; 126 127 // A simple WebGestureCurve implementation that flings at a constant velocity 128 // indefinitely. 129 class FakeWebGestureCurve : public blink::WebGestureCurve { 130 public: 131 FakeWebGestureCurve(const blink::WebFloatSize& velocity, 132 const blink::WebFloatSize& cumulative_scroll) 133 : velocity_(velocity), cumulative_scroll_(cumulative_scroll) {} 134 135 virtual ~FakeWebGestureCurve() {} 136 137 // Returns false if curve has finished and can no longer be applied. 138 virtual bool apply(double time, blink::WebGestureCurveTarget* target) { 139 blink::WebFloatSize displacement(velocity_.width * time, 140 velocity_.height * time); 141 blink::WebFloatSize increment( 142 displacement.width - cumulative_scroll_.width, 143 displacement.height - cumulative_scroll_.height); 144 cumulative_scroll_ = displacement; 145 // scrollBy() could delete this curve if the animation is over, so don't 146 // touch any member variables after making that call. 147 return target->scrollBy(increment, velocity_); 148 } 149 150 private: 151 blink::WebFloatSize velocity_; 152 blink::WebFloatSize cumulative_scroll_; 153 154 DISALLOW_COPY_AND_ASSIGN(FakeWebGestureCurve); 155 }; 156 157 class MockInputHandlerProxyClient 158 : public content::InputHandlerProxyClient { 159 public: 160 MockInputHandlerProxyClient() {} 161 virtual ~MockInputHandlerProxyClient() {} 162 163 virtual void WillShutdown() OVERRIDE {} 164 165 MOCK_METHOD1(TransferActiveWheelFlingAnimation, 166 void(const WebActiveWheelFlingParameters&)); 167 168 virtual blink::WebGestureCurve* CreateFlingAnimationCurve( 169 WebGestureDevice deviceSource, 170 const WebFloatPoint& velocity, 171 const WebSize& cumulative_scroll) OVERRIDE { 172 return new FakeWebGestureCurve( 173 blink::WebFloatSize(velocity.x, velocity.y), 174 blink::WebFloatSize(cumulative_scroll.width, cumulative_scroll.height)); 175 } 176 177 MOCK_METHOD1(DidOverscroll, void(const DidOverscrollParams&)); 178 virtual void DidStopFlinging() OVERRIDE {} 179 180 private: 181 DISALLOW_COPY_AND_ASSIGN(MockInputHandlerProxyClient); 182 }; 183 184 WebTouchPoint CreateWebTouchPoint(WebTouchPoint::State state, float x, 185 float y) { 186 WebTouchPoint point; 187 point.state = state; 188 point.screenPosition = WebFloatPoint(x, y); 189 point.position = WebFloatPoint(x, y); 190 return point; 191 } 192 193 class InputHandlerProxyTest : public testing::Test { 194 public: 195 InputHandlerProxyTest() 196 : expected_disposition_(InputHandlerProxy::DID_HANDLE) { 197 input_handler_.reset( 198 new content::InputHandlerProxy(&mock_input_handler_, &mock_client_)); 199 } 200 201 ~InputHandlerProxyTest() { 202 input_handler_.reset(); 203 } 204 205 // This is defined as a macro because when an expectation is not satisfied the 206 // only output you get 207 // out of gmock is the line number that set the expectation. 208 #define VERIFY_AND_RESET_MOCKS() \ 209 do { \ 210 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); \ 211 testing::Mock::VerifyAndClearExpectations(&mock_client_); \ 212 } while (false) 213 214 void StartFling(base::TimeTicks timestamp, 215 WebGestureDevice source_device, 216 WebFloatPoint velocity, 217 WebPoint position) { 218 expected_disposition_ = InputHandlerProxy::DID_HANDLE; 219 VERIFY_AND_RESET_MOCKS(); 220 221 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 222 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 223 gesture_.type = WebInputEvent::GestureScrollBegin; 224 gesture_.sourceDevice = source_device; 225 EXPECT_EQ(expected_disposition_, 226 input_handler_->HandleInputEvent(gesture_)); 227 228 VERIFY_AND_RESET_MOCKS(); 229 230 EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) 231 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 232 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 233 234 gesture_ = 235 CreateFling(timestamp, source_device, velocity, position, position, 0); 236 EXPECT_EQ(expected_disposition_, 237 input_handler_->HandleInputEvent(gesture_)); 238 239 VERIFY_AND_RESET_MOCKS(); 240 } 241 242 void CancelFling(base::TimeTicks timestamp) { 243 gesture_.timeStampSeconds = InSecondsF(timestamp); 244 gesture_.type = WebInputEvent::GestureFlingCancel; 245 EXPECT_EQ(expected_disposition_, 246 input_handler_->HandleInputEvent(gesture_)); 247 248 VERIFY_AND_RESET_MOCKS(); 249 } 250 251 protected: 252 testing::StrictMock<MockInputHandler> mock_input_handler_; 253 scoped_ptr<content::InputHandlerProxy> input_handler_; 254 testing::StrictMock<MockInputHandlerProxyClient> mock_client_; 255 WebGestureEvent gesture_; 256 257 InputHandlerProxy::EventDisposition expected_disposition_; 258 }; 259 260 TEST_F(InputHandlerProxyTest, MouseWheelByPageMainThread) { 261 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE; 262 WebMouseWheelEvent wheel; 263 wheel.type = WebInputEvent::MouseWheel; 264 wheel.scrollByPage = true; 265 266 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(wheel)); 267 testing::Mock::VerifyAndClearExpectations(&mock_client_); 268 } 269 270 TEST_F(InputHandlerProxyTest, MouseWheelWithCtrl) { 271 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE; 272 WebMouseWheelEvent wheel; 273 wheel.type = WebInputEvent::MouseWheel; 274 wheel.modifiers = WebInputEvent::ControlKey; 275 276 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(wheel)); 277 testing::Mock::VerifyAndClearExpectations(&mock_client_); 278 } 279 280 TEST_F(InputHandlerProxyTest, GestureScrollStarted) { 281 // We shouldn't send any events to the widget for this gesture. 282 expected_disposition_ = InputHandlerProxy::DID_HANDLE; 283 VERIFY_AND_RESET_MOCKS(); 284 285 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 286 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 287 288 gesture_.type = WebInputEvent::GestureScrollBegin; 289 EXPECT_EQ(expected_disposition_,input_handler_->HandleInputEvent(gesture_)); 290 291 // The event should not be marked as handled if scrolling is not possible. 292 expected_disposition_ = InputHandlerProxy::DROP_EVENT; 293 VERIFY_AND_RESET_MOCKS(); 294 295 gesture_.type = WebInputEvent::GestureScrollUpdate; 296 gesture_.data.scrollUpdate.deltaY = 297 -40; // -Y means scroll down - i.e. in the +Y direction. 298 EXPECT_CALL(mock_input_handler_, 299 ScrollBy(testing::_, 300 testing::Property(&gfx::Vector2dF::y, testing::Gt(0)))) 301 .WillOnce(testing::Return(false)); 302 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 303 304 // Mark the event as handled if scroll happens. 305 expected_disposition_ = InputHandlerProxy::DID_HANDLE; 306 VERIFY_AND_RESET_MOCKS(); 307 308 gesture_.type = WebInputEvent::GestureScrollUpdate; 309 gesture_.data.scrollUpdate.deltaY = 310 -40; // -Y means scroll down - i.e. in the +Y direction. 311 EXPECT_CALL(mock_input_handler_, 312 ScrollBy(testing::_, 313 testing::Property(&gfx::Vector2dF::y, testing::Gt(0)))) 314 .WillOnce(testing::Return(true)); 315 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 316 317 VERIFY_AND_RESET_MOCKS(); 318 319 gesture_.type = WebInputEvent::GestureScrollEnd; 320 gesture_.data.scrollUpdate.deltaY = 0; 321 EXPECT_CALL(mock_input_handler_, ScrollEnd()); 322 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 323 } 324 325 TEST_F(InputHandlerProxyTest, GestureScrollOnMainThread) { 326 // We should send all events to the widget for this gesture. 327 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE; 328 VERIFY_AND_RESET_MOCKS(); 329 330 EXPECT_CALL(mock_input_handler_, ScrollBegin(::testing::_, ::testing::_)) 331 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread)); 332 333 gesture_.type = WebInputEvent::GestureScrollBegin; 334 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 335 336 VERIFY_AND_RESET_MOCKS(); 337 338 gesture_.type = WebInputEvent::GestureScrollUpdate; 339 gesture_.data.scrollUpdate.deltaY = 40; 340 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 341 342 VERIFY_AND_RESET_MOCKS(); 343 344 gesture_.type = WebInputEvent::GestureScrollEnd; 345 gesture_.data.scrollUpdate.deltaY = 0; 346 EXPECT_CALL(mock_input_handler_, ScrollEnd()).WillOnce(testing::Return()); 347 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 348 } 349 350 TEST_F(InputHandlerProxyTest, GestureScrollIgnored) { 351 // We shouldn't handle the GestureScrollBegin. 352 // Instead, we should get a DROP_EVENT result, indicating 353 // that we could determine that there's nothing that could scroll or otherwise 354 // react to this gesture sequence and thus we should drop the whole gesture 355 // sequence on the floor, except for the ScrollEnd. 356 expected_disposition_ = InputHandlerProxy::DROP_EVENT; 357 VERIFY_AND_RESET_MOCKS(); 358 359 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 360 .WillOnce(testing::Return(cc::InputHandler::ScrollIgnored)); 361 362 gesture_.type = WebInputEvent::GestureScrollBegin; 363 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 364 365 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE; 366 gesture_.type = WebInputEvent::GestureScrollEnd; 367 EXPECT_CALL(mock_input_handler_, ScrollEnd()).WillOnce(testing::Return()); 368 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 369 } 370 371 TEST_F(InputHandlerProxyTest, GesturePinch) { 372 // We shouldn't send any events to the widget for this gesture. 373 expected_disposition_ = InputHandlerProxy::DID_HANDLE; 374 VERIFY_AND_RESET_MOCKS(); 375 376 gesture_.type = WebInputEvent::GesturePinchBegin; 377 EXPECT_CALL(mock_input_handler_, PinchGestureBegin()); 378 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 379 380 VERIFY_AND_RESET_MOCKS(); 381 382 gesture_.type = WebInputEvent::GesturePinchUpdate; 383 gesture_.data.pinchUpdate.scale = 1.5; 384 gesture_.x = 7; 385 gesture_.y = 13; 386 EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(1.5, gfx::Point(7, 13))); 387 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 388 389 VERIFY_AND_RESET_MOCKS(); 390 391 gesture_.type = WebInputEvent::GesturePinchUpdate; 392 gesture_.data.pinchUpdate.scale = 0.5; 393 gesture_.x = 9; 394 gesture_.y = 6; 395 EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(.5, gfx::Point(9, 6))); 396 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 397 398 VERIFY_AND_RESET_MOCKS(); 399 400 gesture_.type = WebInputEvent::GesturePinchEnd; 401 EXPECT_CALL(mock_input_handler_, PinchGestureEnd()); 402 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 403 } 404 405 TEST_F(InputHandlerProxyTest, GesturePinchAfterScrollOnMainThread) { 406 // Scrolls will start by being sent to the main thread. 407 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE; 408 VERIFY_AND_RESET_MOCKS(); 409 410 EXPECT_CALL(mock_input_handler_, ScrollBegin(::testing::_, ::testing::_)) 411 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread)); 412 413 gesture_.type = WebInputEvent::GestureScrollBegin; 414 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 415 416 VERIFY_AND_RESET_MOCKS(); 417 418 gesture_.type = WebInputEvent::GestureScrollUpdate; 419 gesture_.data.scrollUpdate.deltaY = 40; 420 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 421 422 // However, after the pinch gesture starts, they should go to the impl 423 // thread. 424 expected_disposition_ = InputHandlerProxy::DID_HANDLE; 425 VERIFY_AND_RESET_MOCKS(); 426 427 gesture_.type = WebInputEvent::GesturePinchBegin; 428 EXPECT_CALL(mock_input_handler_, PinchGestureBegin()); 429 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 430 431 VERIFY_AND_RESET_MOCKS(); 432 433 gesture_.type = WebInputEvent::GesturePinchUpdate; 434 gesture_.data.pinchUpdate.scale = 1.5; 435 gesture_.x = 7; 436 gesture_.y = 13; 437 EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(1.5, gfx::Point(7, 13))); 438 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 439 440 VERIFY_AND_RESET_MOCKS(); 441 442 gesture_.type = WebInputEvent::GestureScrollUpdate; 443 gesture_.data.scrollUpdate.deltaY = 444 -40; // -Y means scroll down - i.e. in the +Y direction. 445 EXPECT_CALL(mock_input_handler_, 446 ScrollBy(testing::_, 447 testing::Property(&gfx::Vector2dF::y, testing::Gt(0)))) 448 .WillOnce(testing::Return(true)); 449 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 450 451 VERIFY_AND_RESET_MOCKS(); 452 453 gesture_.type = WebInputEvent::GesturePinchUpdate; 454 gesture_.data.pinchUpdate.scale = 0.5; 455 gesture_.x = 9; 456 gesture_.y = 6; 457 EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(.5, gfx::Point(9, 6))); 458 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 459 460 VERIFY_AND_RESET_MOCKS(); 461 462 gesture_.type = WebInputEvent::GesturePinchEnd; 463 EXPECT_CALL(mock_input_handler_, PinchGestureEnd()); 464 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 465 466 // After the pinch gesture ends, they should go to back to the main 467 // thread. 468 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE; 469 VERIFY_AND_RESET_MOCKS(); 470 471 gesture_.type = WebInputEvent::GestureScrollEnd; 472 gesture_.data.scrollUpdate.deltaY = 0; 473 EXPECT_CALL(mock_input_handler_, ScrollEnd()) 474 .WillOnce(testing::Return()); 475 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 476 } 477 478 TEST_F(InputHandlerProxyTest, GestureFlingStartedTouchpad) { 479 // We shouldn't send any events to the widget for this gesture. 480 expected_disposition_ = InputHandlerProxy::DID_HANDLE; 481 VERIFY_AND_RESET_MOCKS(); 482 483 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 484 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 485 EXPECT_CALL(mock_input_handler_, ScrollEnd()); 486 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 487 488 gesture_.type = WebInputEvent::GestureFlingStart; 489 gesture_.data.flingStart.velocityX = 10; 490 gesture_.sourceDevice = blink::WebGestureDeviceTouchpad; 491 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 492 493 VERIFY_AND_RESET_MOCKS(); 494 495 // Verify that a GestureFlingCancel during an animation cancels it. 496 gesture_.type = WebInputEvent::GestureFlingCancel; 497 gesture_.sourceDevice = blink::WebGestureDeviceTouchpad; 498 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 499 } 500 501 TEST_F(InputHandlerProxyTest, GestureFlingOnMainThreadTouchpad) { 502 // We should send all events to the widget for this gesture. 503 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE; 504 VERIFY_AND_RESET_MOCKS(); 505 506 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 507 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread)); 508 509 gesture_.type = WebInputEvent::GestureFlingStart; 510 gesture_.sourceDevice = blink::WebGestureDeviceTouchpad; 511 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 512 513 // Since we returned ScrollStatusOnMainThread from scrollBegin, ensure the 514 // input handler knows it's scrolling off the impl thread 515 ASSERT_FALSE(input_handler_->gesture_scroll_on_impl_thread_for_testing()); 516 517 VERIFY_AND_RESET_MOCKS(); 518 519 // Even if we didn't start a fling ourselves, we still need to send the cancel 520 // event to the widget. 521 gesture_.type = WebInputEvent::GestureFlingCancel; 522 gesture_.sourceDevice = blink::WebGestureDeviceTouchpad; 523 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 524 } 525 526 TEST_F(InputHandlerProxyTest, GestureFlingIgnoredTouchpad) { 527 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE; 528 VERIFY_AND_RESET_MOCKS(); 529 530 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 531 .WillOnce(testing::Return(cc::InputHandler::ScrollIgnored)); 532 533 gesture_.type = WebInputEvent::GestureFlingStart; 534 gesture_.sourceDevice = blink::WebGestureDeviceTouchpad; 535 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 536 537 expected_disposition_ = InputHandlerProxy::DROP_EVENT; 538 VERIFY_AND_RESET_MOCKS(); 539 540 // Since the previous fling was ignored, we should also be dropping the next 541 // fling_cancel. 542 gesture_.type = WebInputEvent::GestureFlingCancel; 543 gesture_.sourceDevice = blink::WebGestureDeviceTouchpad; 544 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 545 } 546 547 TEST_F(InputHandlerProxyTest, GestureFlingAnimatesTouchpad) { 548 // We shouldn't send any events to the widget for this gesture. 549 expected_disposition_ = InputHandlerProxy::DID_HANDLE; 550 VERIFY_AND_RESET_MOCKS(); 551 552 // On the fling start, we should schedule an animation but not actually start 553 // scrolling. 554 gesture_.type = WebInputEvent::GestureFlingStart; 555 WebFloatPoint fling_delta = WebFloatPoint(1000, 0); 556 WebPoint fling_point = WebPoint(7, 13); 557 WebPoint fling_global_point = WebPoint(17, 23); 558 // Note that for trackpad, wheel events with the Control modifier are 559 // special (reserved for zoom), so don't set that here. 560 int modifiers = WebInputEvent::ShiftKey | WebInputEvent::AltKey; 561 gesture_ = CreateFling(blink::WebGestureDeviceTouchpad, 562 fling_delta, 563 fling_point, 564 fling_global_point, 565 modifiers); 566 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 567 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 568 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 569 EXPECT_CALL(mock_input_handler_, ScrollEnd()); 570 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 571 572 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 573 // The first animate call should let us pick up an animation start time, but 574 // we shouldn't actually move anywhere just yet. The first frame after the 575 // fling start will typically include the last scroll from the gesture that 576 // lead to the scroll (either wheel or gesture scroll), so there should be no 577 // visible hitch. 578 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 579 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 580 .Times(0); 581 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10); 582 input_handler_->Animate(time); 583 584 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 585 586 // The second call should start scrolling in the -X direction. 587 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 588 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 589 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 590 EXPECT_CALL(mock_input_handler_, 591 ScrollBy(testing::_, 592 testing::Property(&gfx::Vector2dF::x, testing::Lt(0)))) 593 .WillOnce(testing::Return(true)); 594 EXPECT_CALL(mock_input_handler_, ScrollEnd()); 595 time += base::TimeDelta::FromMilliseconds(100); 596 input_handler_->Animate(time); 597 598 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 599 600 // Let's say on the third call we hit a non-scrollable region. We should abort 601 // the fling and not scroll. 602 // We also should pass the current fling parameters out to the client so the 603 // rest of the fling can be 604 // transferred to the main thread. 605 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 606 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread)); 607 EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_, testing::_)).Times(0); 608 EXPECT_CALL(mock_input_handler_, ScrollEnd()).Times(0); 609 // Expected wheel fling animation parameters: 610 // *) fling_delta and fling_point should match the original GestureFlingStart 611 // event 612 // *) startTime should be 10 to match the time parameter of the first 613 // Animate() call after the GestureFlingStart 614 // *) cumulativeScroll depends on the curve, but since we've animated in the 615 // -X direction the X value should be < 0 616 EXPECT_CALL( 617 mock_client_, 618 TransferActiveWheelFlingAnimation(testing::AllOf( 619 testing::Field(&WebActiveWheelFlingParameters::delta, 620 testing::Eq(fling_delta)), 621 testing::Field(&WebActiveWheelFlingParameters::point, 622 testing::Eq(fling_point)), 623 testing::Field(&WebActiveWheelFlingParameters::globalPoint, 624 testing::Eq(fling_global_point)), 625 testing::Field(&WebActiveWheelFlingParameters::modifiers, 626 testing::Eq(modifiers)), 627 testing::Field(&WebActiveWheelFlingParameters::startTime, 628 testing::Eq(10)), 629 testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll, 630 testing::Field(&WebSize::width, testing::Gt(0)))))); 631 time += base::TimeDelta::FromMilliseconds(100); 632 input_handler_->Animate(time); 633 634 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 635 testing::Mock::VerifyAndClearExpectations(&mock_client_); 636 637 // Since we've aborted the fling, the next animation should be a no-op and 638 // should not result in another 639 // frame being requested. 640 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()).Times(0); 641 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 642 .Times(0); 643 time += base::TimeDelta::FromMilliseconds(100); 644 input_handler_->Animate(time); 645 646 // Since we've transferred the fling to the main thread, we need to pass the 647 // next GestureFlingCancel to the main 648 // thread as well. 649 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE; 650 gesture_.type = WebInputEvent::GestureFlingCancel; 651 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 652 } 653 654 TEST_F(InputHandlerProxyTest, GestureFlingTransferResetsTouchpad) { 655 // We shouldn't send any events to the widget for this gesture. 656 expected_disposition_ = InputHandlerProxy::DID_HANDLE; 657 VERIFY_AND_RESET_MOCKS(); 658 659 // Start a gesture fling in the -X direction with zero Y movement. 660 WebFloatPoint fling_delta = WebFloatPoint(1000, 0); 661 WebPoint fling_point = WebPoint(7, 13); 662 WebPoint fling_global_point = WebPoint(17, 23); 663 // Note that for trackpad, wheel events with the Control modifier are 664 // special (reserved for zoom), so don't set that here. 665 int modifiers = WebInputEvent::ShiftKey | WebInputEvent::AltKey; 666 gesture_ = CreateFling(blink::WebGestureDeviceTouchpad, 667 fling_delta, 668 fling_point, 669 fling_global_point, 670 modifiers); 671 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 672 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 673 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 674 EXPECT_CALL(mock_input_handler_, ScrollEnd()); 675 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 676 677 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 678 679 // Start the fling animation at time 10. This shouldn't actually scroll, just 680 // establish a start time. 681 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 682 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 683 .Times(0); 684 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10); 685 input_handler_->Animate(time); 686 687 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 688 689 // The second call should start scrolling in the -X direction. 690 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 691 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 692 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 693 EXPECT_CALL(mock_input_handler_, 694 ScrollBy(testing::_, 695 testing::Property(&gfx::Vector2dF::x, testing::Lt(0)))) 696 .WillOnce(testing::Return(true)); 697 EXPECT_CALL(mock_input_handler_, ScrollEnd()); 698 time += base::TimeDelta::FromMilliseconds(100); 699 input_handler_->Animate(time); 700 701 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 702 703 // Let's say on the third call we hit a non-scrollable region. We should abort 704 // the fling and not scroll. 705 // We also should pass the current fling parameters out to the client so the 706 // rest of the fling can be 707 // transferred to the main thread. 708 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 709 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread)); 710 EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_, testing::_)).Times(0); 711 EXPECT_CALL(mock_input_handler_, ScrollEnd()).Times(0); 712 713 // Expected wheel fling animation parameters: 714 // *) fling_delta and fling_point should match the original GestureFlingStart 715 // event 716 // *) startTime should be 10 to match the time parameter of the first 717 // Animate() call after the GestureFlingStart 718 // *) cumulativeScroll depends on the curve, but since we've animated in the 719 // -X direction the X value should be < 0 720 EXPECT_CALL( 721 mock_client_, 722 TransferActiveWheelFlingAnimation(testing::AllOf( 723 testing::Field(&WebActiveWheelFlingParameters::delta, 724 testing::Eq(fling_delta)), 725 testing::Field(&WebActiveWheelFlingParameters::point, 726 testing::Eq(fling_point)), 727 testing::Field(&WebActiveWheelFlingParameters::globalPoint, 728 testing::Eq(fling_global_point)), 729 testing::Field(&WebActiveWheelFlingParameters::modifiers, 730 testing::Eq(modifiers)), 731 testing::Field(&WebActiveWheelFlingParameters::startTime, 732 testing::Eq(10)), 733 testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll, 734 testing::Field(&WebSize::width, testing::Gt(0)))))); 735 time += base::TimeDelta::FromMilliseconds(100); 736 input_handler_->Animate(time); 737 738 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 739 testing::Mock::VerifyAndClearExpectations(&mock_client_); 740 741 // Since we've aborted the fling, the next animation should be a no-op and 742 // should not result in another 743 // frame being requested. 744 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()).Times(0); 745 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 746 .Times(0); 747 time += base::TimeDelta::FromMilliseconds(100); 748 input_handler_->Animate(time); 749 750 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 751 752 // Since we've transferred the fling to the main thread, we need to pass the 753 // next GestureFlingCancel to the main 754 // thread as well. 755 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE; 756 gesture_.type = WebInputEvent::GestureFlingCancel; 757 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 758 759 VERIFY_AND_RESET_MOCKS(); 760 input_handler_->MainThreadHasStoppedFlinging(); 761 762 // Start a second gesture fling, this time in the +Y direction with no X. 763 fling_delta = WebFloatPoint(0, -1000); 764 fling_point = WebPoint(95, 87); 765 fling_global_point = WebPoint(32, 71); 766 modifiers = WebInputEvent::AltKey; 767 gesture_ = CreateFling(blink::WebGestureDeviceTouchpad, 768 fling_delta, 769 fling_point, 770 fling_global_point, 771 modifiers); 772 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 773 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 774 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 775 EXPECT_CALL(mock_input_handler_, ScrollEnd()); 776 expected_disposition_ = InputHandlerProxy::DID_HANDLE; 777 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 778 779 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 780 781 // Start the second fling animation at time 30. 782 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 783 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 784 .Times(0); 785 time = base::TimeTicks() + base::TimeDelta::FromSeconds(30); 786 input_handler_->Animate(time); 787 788 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 789 790 // Tick the second fling once normally. 791 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 792 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 793 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 794 EXPECT_CALL(mock_input_handler_, 795 ScrollBy(testing::_, 796 testing::Property(&gfx::Vector2dF::y, testing::Gt(0)))) 797 .WillOnce(testing::Return(true)); 798 EXPECT_CALL(mock_input_handler_, ScrollEnd()); 799 time += base::TimeDelta::FromMilliseconds(100); 800 input_handler_->Animate(time); 801 802 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 803 804 // Then abort the second fling. 805 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 806 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread)); 807 EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_, testing::_)).Times(0); 808 EXPECT_CALL(mock_input_handler_, ScrollEnd()).Times(0); 809 810 // We should get parameters from the second fling, nothing from the first 811 // fling should "leak". 812 EXPECT_CALL( 813 mock_client_, 814 TransferActiveWheelFlingAnimation(testing::AllOf( 815 testing::Field(&WebActiveWheelFlingParameters::delta, 816 testing::Eq(fling_delta)), 817 testing::Field(&WebActiveWheelFlingParameters::point, 818 testing::Eq(fling_point)), 819 testing::Field(&WebActiveWheelFlingParameters::globalPoint, 820 testing::Eq(fling_global_point)), 821 testing::Field(&WebActiveWheelFlingParameters::modifiers, 822 testing::Eq(modifiers)), 823 testing::Field(&WebActiveWheelFlingParameters::startTime, 824 testing::Eq(30)), 825 testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll, 826 testing::Field(&WebSize::height, testing::Lt(0)))))); 827 time += base::TimeDelta::FromMilliseconds(100); 828 input_handler_->Animate(time); 829 } 830 831 TEST_F(InputHandlerProxyTest, GestureFlingStartedTouchscreen) { 832 // We shouldn't send any events to the widget for this gesture. 833 expected_disposition_ = InputHandlerProxy::DID_HANDLE; 834 VERIFY_AND_RESET_MOCKS(); 835 836 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 837 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 838 gesture_.type = WebInputEvent::GestureScrollBegin; 839 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; 840 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 841 842 VERIFY_AND_RESET_MOCKS(); 843 844 EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) 845 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 846 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 847 848 gesture_.type = WebInputEvent::GestureFlingStart; 849 gesture_.data.flingStart.velocityX = 10; 850 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; 851 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 852 853 VERIFY_AND_RESET_MOCKS(); 854 855 EXPECT_CALL(mock_input_handler_, ScrollEnd()); 856 857 // Verify that a GestureFlingCancel during an animation cancels it. 858 gesture_.type = WebInputEvent::GestureFlingCancel; 859 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; 860 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 861 } 862 863 TEST_F(InputHandlerProxyTest, GestureFlingOnMainThreadTouchscreen) { 864 // We should send all events to the widget for this gesture. 865 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE; 866 VERIFY_AND_RESET_MOCKS(); 867 868 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 869 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread)); 870 871 gesture_.type = WebInputEvent::GestureScrollBegin; 872 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 873 874 VERIFY_AND_RESET_MOCKS(); 875 876 EXPECT_CALL(mock_input_handler_, FlingScrollBegin()).Times(0); 877 878 gesture_.type = WebInputEvent::GestureFlingStart; 879 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; 880 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 881 882 VERIFY_AND_RESET_MOCKS(); 883 884 // Even if we didn't start a fling ourselves, we still need to send the cancel 885 // event to the widget. 886 gesture_.type = WebInputEvent::GestureFlingCancel; 887 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; 888 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 889 } 890 891 TEST_F(InputHandlerProxyTest, GestureFlingIgnoredTouchscreen) { 892 expected_disposition_ = InputHandlerProxy::DID_HANDLE; 893 VERIFY_AND_RESET_MOCKS(); 894 895 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 896 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 897 898 gesture_.type = WebInputEvent::GestureScrollBegin; 899 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; 900 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 901 902 expected_disposition_ = InputHandlerProxy::DROP_EVENT; 903 VERIFY_AND_RESET_MOCKS(); 904 905 EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) 906 .WillOnce(testing::Return(cc::InputHandler::ScrollIgnored)); 907 908 gesture_.type = WebInputEvent::GestureFlingStart; 909 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; 910 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 911 912 VERIFY_AND_RESET_MOCKS(); 913 914 // Even if we didn't start a fling ourselves, we still need to send the cancel 915 // event to the widget. 916 gesture_.type = WebInputEvent::GestureFlingCancel; 917 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; 918 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 919 } 920 921 TEST_F(InputHandlerProxyTest, GestureFlingAnimatesTouchscreen) { 922 // We shouldn't send any events to the widget for this gesture. 923 expected_disposition_ = InputHandlerProxy::DID_HANDLE; 924 VERIFY_AND_RESET_MOCKS(); 925 926 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 927 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 928 929 gesture_.type = WebInputEvent::GestureScrollBegin; 930 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; 931 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 932 933 VERIFY_AND_RESET_MOCKS(); 934 935 // On the fling start, we should schedule an animation but not actually start 936 // scrolling. 937 WebFloatPoint fling_delta = WebFloatPoint(100, 0); 938 WebPoint fling_point = WebPoint(7, 13); 939 WebPoint fling_global_point = WebPoint(17, 23); 940 // Note that for touchscreen the control modifier is not special. 941 int modifiers = WebInputEvent::ControlKey; 942 gesture_ = CreateFling(blink::WebGestureDeviceTouchscreen, 943 fling_delta, 944 fling_point, 945 fling_global_point, 946 modifiers); 947 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 948 EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) 949 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 950 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 951 952 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 953 // The first animate call should let us pick up an animation start time, but 954 // we shouldn't actually move anywhere just yet. The first frame after the 955 // fling start will typically include the last scroll from the gesture that 956 // lead to the scroll (either wheel or gesture scroll), so there should be no 957 // visible hitch. 958 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 959 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10); 960 input_handler_->Animate(time); 961 962 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 963 964 // The second call should start scrolling in the -X direction. 965 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 966 EXPECT_CALL(mock_input_handler_, 967 ScrollBy(testing::_, 968 testing::Property(&gfx::Vector2dF::x, testing::Lt(0)))) 969 .WillOnce(testing::Return(true)); 970 time += base::TimeDelta::FromMilliseconds(100); 971 input_handler_->Animate(time); 972 973 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 974 975 EXPECT_CALL(mock_input_handler_, ScrollEnd()); 976 gesture_.type = WebInputEvent::GestureFlingCancel; 977 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 978 } 979 980 TEST_F(InputHandlerProxyTest, GestureFlingWithValidTimestamp) { 981 // We shouldn't send any events to the widget for this gesture. 982 expected_disposition_ = InputHandlerProxy::DID_HANDLE; 983 VERIFY_AND_RESET_MOCKS(); 984 985 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 986 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 987 988 gesture_.type = WebInputEvent::GestureScrollBegin; 989 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; 990 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 991 992 VERIFY_AND_RESET_MOCKS(); 993 994 // On the fling start, we should schedule an animation but not actually start 995 // scrolling. 996 base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10); 997 base::TimeTicks time = base::TimeTicks() + dt; 998 WebFloatPoint fling_delta = WebFloatPoint(100, 0); 999 WebPoint fling_point = WebPoint(7, 13); 1000 WebPoint fling_global_point = WebPoint(17, 23); 1001 int modifiers = WebInputEvent::ControlKey; 1002 gesture_ = CreateFling(time, 1003 blink::WebGestureDeviceTouchscreen, 1004 fling_delta, 1005 fling_point, 1006 fling_global_point, 1007 modifiers); 1008 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 1009 EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) 1010 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 1011 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 1012 1013 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 1014 // With a valid time stamp, the first animate call should skip start time 1015 // initialization and immediately begin scroll update production. This reduces 1016 // the likelihood of a hitch between the scroll preceding the fling and 1017 // the first scroll generated by the fling. 1018 // Scrolling should start in the -X direction. 1019 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 1020 EXPECT_CALL(mock_input_handler_, 1021 ScrollBy(testing::_, 1022 testing::Property(&gfx::Vector2dF::x, testing::Lt(0)))) 1023 .WillOnce(testing::Return(true)); 1024 time += dt; 1025 input_handler_->Animate(time); 1026 1027 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 1028 1029 EXPECT_CALL(mock_input_handler_, ScrollEnd()); 1030 gesture_.type = WebInputEvent::GestureFlingCancel; 1031 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 1032 } 1033 1034 TEST_F(InputHandlerProxyTest, GestureFlingWithInvalidTimestamp) { 1035 // We shouldn't send any events to the widget for this gesture. 1036 expected_disposition_ = InputHandlerProxy::DID_HANDLE; 1037 VERIFY_AND_RESET_MOCKS(); 1038 1039 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 1040 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 1041 1042 gesture_.type = WebInputEvent::GestureScrollBegin; 1043 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; 1044 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 1045 1046 VERIFY_AND_RESET_MOCKS(); 1047 1048 // On the fling start, we should schedule an animation but not actually start 1049 // scrolling. 1050 base::TimeDelta start_time_offset = base::TimeDelta::FromMilliseconds(10); 1051 gesture_.type = WebInputEvent::GestureFlingStart; 1052 WebFloatPoint fling_delta = WebFloatPoint(100, 0); 1053 WebPoint fling_point = WebPoint(7, 13); 1054 WebPoint fling_global_point = WebPoint(17, 23); 1055 int modifiers = WebInputEvent::ControlKey; 1056 gesture_.timeStampSeconds = start_time_offset.InSecondsF(); 1057 gesture_.data.flingStart.velocityX = fling_delta.x; 1058 gesture_.data.flingStart.velocityY = fling_delta.y; 1059 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; 1060 gesture_.x = fling_point.x; 1061 gesture_.y = fling_point.y; 1062 gesture_.globalX = fling_global_point.x; 1063 gesture_.globalY = fling_global_point.y; 1064 gesture_.modifiers = modifiers; 1065 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 1066 EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) 1067 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 1068 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 1069 1070 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 1071 // Event though a time stamp was provided for the fling event, it will be 1072 // ignored as its too far in the past relative to the first animate call's 1073 // timestamp. 1074 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 1075 base::TimeTicks time = 1076 base::TimeTicks() + start_time_offset + base::TimeDelta::FromSeconds(1); 1077 input_handler_->Animate(time); 1078 1079 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 1080 1081 // Further animation ticks should update the fling as usual. 1082 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 1083 EXPECT_CALL(mock_input_handler_, 1084 ScrollBy(testing::_, 1085 testing::Property(&gfx::Vector2dF::x, testing::Lt(0)))) 1086 .WillOnce(testing::Return(true)); 1087 time += base::TimeDelta::FromMilliseconds(10); 1088 input_handler_->Animate(time); 1089 1090 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 1091 1092 EXPECT_CALL(mock_input_handler_, ScrollEnd()); 1093 gesture_.type = WebInputEvent::GestureFlingCancel; 1094 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 1095 } 1096 1097 TEST_F(InputHandlerProxyTest, 1098 GestureScrollOnImplThreadFlagClearedAfterFling) { 1099 // We shouldn't send any events to the widget for this gesture. 1100 expected_disposition_ = InputHandlerProxy::DID_HANDLE; 1101 VERIFY_AND_RESET_MOCKS(); 1102 1103 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 1104 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 1105 1106 gesture_.type = WebInputEvent::GestureScrollBegin; 1107 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 1108 1109 // After sending a GestureScrollBegin, the member variable 1110 // |gesture_scroll_on_impl_thread_| should be true. 1111 EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing()); 1112 1113 expected_disposition_ = InputHandlerProxy::DID_HANDLE; 1114 VERIFY_AND_RESET_MOCKS(); 1115 1116 // On the fling start, we should schedule an animation but not actually start 1117 // scrolling. 1118 WebFloatPoint fling_delta = WebFloatPoint(100, 0); 1119 WebPoint fling_point = WebPoint(7, 13); 1120 WebPoint fling_global_point = WebPoint(17, 23); 1121 int modifiers = WebInputEvent::ControlKey | WebInputEvent::AltKey; 1122 gesture_ = CreateFling(blink::WebGestureDeviceTouchscreen, 1123 fling_delta, 1124 fling_point, 1125 fling_global_point, 1126 modifiers); 1127 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 1128 EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) 1129 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 1130 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 1131 1132 // |gesture_scroll_on_impl_thread_| should still be true after 1133 // a GestureFlingStart is sent. 1134 EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing()); 1135 1136 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 1137 // The first animate call should let us pick up an animation start time, but 1138 // we shouldn't actually move anywhere just yet. The first frame after the 1139 // fling start will typically include the last scroll from the gesture that 1140 // lead to the scroll (either wheel or gesture scroll), so there should be no 1141 // visible hitch. 1142 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 1143 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10); 1144 input_handler_->Animate(time); 1145 1146 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 1147 1148 // The second call should start scrolling in the -X direction. 1149 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 1150 EXPECT_CALL(mock_input_handler_, 1151 ScrollBy(testing::_, 1152 testing::Property(&gfx::Vector2dF::x, testing::Lt(0)))) 1153 .WillOnce(testing::Return(true)); 1154 time += base::TimeDelta::FromMilliseconds(100); 1155 input_handler_->Animate(time); 1156 1157 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 1158 1159 EXPECT_CALL(mock_input_handler_, ScrollEnd()); 1160 gesture_.type = WebInputEvent::GestureFlingCancel; 1161 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 1162 1163 // |gesture_scroll_on_impl_thread_| should be false once 1164 // the fling has finished (note no GestureScrollEnd has been sent). 1165 EXPECT_TRUE(!input_handler_->gesture_scroll_on_impl_thread_for_testing()); 1166 } 1167 1168 TEST_F(InputHandlerProxyTest, GestureFlingStopsAtContentEdge) { 1169 // We shouldn't send any events to the widget for this gesture. 1170 expected_disposition_ = InputHandlerProxy::DID_HANDLE; 1171 VERIFY_AND_RESET_MOCKS(); 1172 1173 // On the fling start, we should schedule an animation but not actually start 1174 // scrolling. 1175 gesture_.type = WebInputEvent::GestureFlingStart; 1176 WebFloatPoint fling_delta = WebFloatPoint(100, 100); 1177 gesture_.data.flingStart.velocityX = fling_delta.x; 1178 gesture_.data.flingStart.velocityY = fling_delta.y; 1179 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 1180 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 1181 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 1182 EXPECT_CALL(mock_input_handler_, ScrollEnd()); 1183 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 1184 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 1185 1186 // The first animate doesn't cause any scrolling. 1187 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 1188 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10); 1189 input_handler_->Animate(time); 1190 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 1191 1192 // The second animate starts scrolling in the positive X and Y directions. 1193 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 1194 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 1195 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 1196 EXPECT_CALL(mock_input_handler_, 1197 ScrollBy(testing::_, 1198 testing::Property(&gfx::Vector2dF::y, testing::Lt(0)))) 1199 .WillOnce(testing::Return(true)); 1200 EXPECT_CALL(mock_input_handler_, ScrollEnd()); 1201 time += base::TimeDelta::FromMilliseconds(100); 1202 input_handler_->Animate(time); 1203 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 1204 1205 // Simulate hitting the bottom content edge. 1206 gfx::Vector2dF accumulated_overscroll(0, 100); 1207 gfx::Vector2dF latest_overscroll_delta(0, 10); 1208 EXPECT_CALL(mock_client_, 1209 DidOverscroll(testing::AllOf( 1210 testing::Field(&DidOverscrollParams::accumulated_overscroll, 1211 testing::Eq(accumulated_overscroll)), 1212 testing::Field(&DidOverscrollParams::latest_overscroll_delta, 1213 testing::Eq(latest_overscroll_delta)), 1214 testing::Field( 1215 &DidOverscrollParams::current_fling_velocity, 1216 testing::Property(&gfx::Vector2dF::y, testing::Lt(0)))))); 1217 input_handler_->DidOverscroll(accumulated_overscroll, 1218 latest_overscroll_delta); 1219 1220 // The next call to animate will no longer scroll vertically. 1221 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 1222 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 1223 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 1224 EXPECT_CALL(mock_input_handler_, 1225 ScrollBy(testing::_, 1226 testing::Property(&gfx::Vector2dF::y, testing::Eq(0)))) 1227 .WillOnce(testing::Return(true)); 1228 EXPECT_CALL(mock_input_handler_, ScrollEnd()); 1229 time += base::TimeDelta::FromMilliseconds(100); 1230 input_handler_->Animate(time); 1231 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 1232 } 1233 1234 TEST_F(InputHandlerProxyTest, GestureFlingNotCancelledBySmallTimeDelta) { 1235 // We shouldn't send any events to the widget for this gesture. 1236 expected_disposition_ = InputHandlerProxy::DID_HANDLE; 1237 VERIFY_AND_RESET_MOCKS(); 1238 1239 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 1240 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 1241 1242 gesture_.type = WebInputEvent::GestureScrollBegin; 1243 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; 1244 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 1245 1246 VERIFY_AND_RESET_MOCKS(); 1247 1248 // On the fling start, we should schedule an animation but not actually start 1249 // scrolling. 1250 base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10); 1251 base::TimeTicks time = base::TimeTicks() + dt; 1252 WebFloatPoint fling_delta = WebFloatPoint(100, 0); 1253 WebPoint fling_point = WebPoint(7, 13); 1254 WebPoint fling_global_point = WebPoint(17, 23); 1255 int modifiers = WebInputEvent::ControlKey; 1256 gesture_ = CreateFling(time, 1257 blink::WebGestureDeviceTouchscreen, 1258 fling_delta, 1259 fling_point, 1260 fling_global_point, 1261 modifiers); 1262 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 1263 EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) 1264 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 1265 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 1266 1267 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 1268 // With an animation timestamp equivalent to the starting timestamp, the 1269 // animation will simply be rescheduled. 1270 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 1271 input_handler_->Animate(time); 1272 1273 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 1274 EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing()); 1275 1276 // A small time delta should not stop the fling, even if the client 1277 // reports no scrolling. 1278 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 1279 EXPECT_CALL(mock_input_handler_, 1280 ScrollBy(testing::_, 1281 testing::Property(&gfx::Vector2dF::x, testing::Lt(0)))) 1282 .WillOnce(testing::Return(false)); 1283 time += base::TimeDelta::FromMicroseconds(5); 1284 input_handler_->Animate(time); 1285 1286 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 1287 EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing()); 1288 1289 // A time delta of zero should not stop the fling, and neither should it 1290 // trigger scrolling on the client. 1291 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 1292 input_handler_->Animate(time); 1293 1294 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 1295 EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing()); 1296 1297 // Lack of movement on the client, with a non-trivial scroll delta, should 1298 // terminate the fling. 1299 EXPECT_CALL(mock_input_handler_, ScrollEnd()); 1300 EXPECT_CALL(mock_input_handler_, 1301 ScrollBy(testing::_, 1302 testing::Property(&gfx::Vector2dF::x, testing::Lt(1)))) 1303 .WillOnce(testing::Return(false)); 1304 time += base::TimeDelta::FromMilliseconds(100); 1305 input_handler_->Animate(time); 1306 1307 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 1308 EXPECT_FALSE(input_handler_->gesture_scroll_on_impl_thread_for_testing()); 1309 } 1310 1311 TEST_F(InputHandlerProxyTest, GestureFlingCancelledAfterBothAxesStopScrolling) { 1312 // We shouldn't send any events to the widget for this gesture. 1313 expected_disposition_ = InputHandlerProxy::DID_HANDLE; 1314 VERIFY_AND_RESET_MOCKS(); 1315 1316 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 1317 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 1318 gesture_.type = WebInputEvent::GestureScrollBegin; 1319 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; 1320 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 1321 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 1322 1323 // On the fling start, we should schedule an animation but not actually start 1324 // scrolling. 1325 gesture_.type = WebInputEvent::GestureFlingStart; 1326 WebFloatPoint fling_delta = WebFloatPoint(100, 100); 1327 gesture_.data.flingStart.velocityX = fling_delta.x; 1328 gesture_.data.flingStart.velocityY = fling_delta.y; 1329 EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) 1330 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 1331 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 1332 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 1333 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 1334 1335 // The first animate doesn't cause any scrolling. 1336 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 1337 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10); 1338 input_handler_->Animate(time); 1339 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 1340 1341 // The second animate starts scrolling in the positive X and Y directions. 1342 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 1343 EXPECT_CALL(mock_input_handler_, 1344 ScrollBy(testing::_, 1345 testing::Property(&gfx::Vector2dF::y, testing::Lt(0)))) 1346 .WillOnce(testing::Return(true)); 1347 time += base::TimeDelta::FromMilliseconds(10); 1348 input_handler_->Animate(time); 1349 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 1350 1351 // Simulate hitting the bottom content edge. 1352 gfx::Vector2dF accumulated_overscroll(0, 100); 1353 gfx::Vector2dF latest_overscroll_delta(0, 100); 1354 EXPECT_CALL(mock_client_, 1355 DidOverscroll(testing::AllOf( 1356 testing::Field(&DidOverscrollParams::accumulated_overscroll, 1357 testing::Eq(accumulated_overscroll)), 1358 testing::Field(&DidOverscrollParams::latest_overscroll_delta, 1359 testing::Eq(latest_overscroll_delta)), 1360 testing::Field( 1361 &DidOverscrollParams::current_fling_velocity, 1362 testing::Property(&gfx::Vector2dF::y, testing::Lt(0)))))); 1363 input_handler_->DidOverscroll(accumulated_overscroll, 1364 latest_overscroll_delta); 1365 1366 // The next call to animate will no longer scroll vertically. 1367 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 1368 EXPECT_CALL(mock_input_handler_, 1369 ScrollBy(testing::_, 1370 testing::Property(&gfx::Vector2dF::y, testing::Eq(0)))) 1371 .WillOnce(testing::Return(true)); 1372 time += base::TimeDelta::FromMilliseconds(10); 1373 input_handler_->Animate(time); 1374 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 1375 1376 // Simulate hitting the right content edge. 1377 accumulated_overscroll = gfx::Vector2dF(100, 100); 1378 latest_overscroll_delta = gfx::Vector2dF(100, 0); 1379 EXPECT_CALL(mock_client_, 1380 DidOverscroll(testing::AllOf( 1381 testing::Field(&DidOverscrollParams::accumulated_overscroll, 1382 testing::Eq(accumulated_overscroll)), 1383 testing::Field(&DidOverscrollParams::latest_overscroll_delta, 1384 testing::Eq(latest_overscroll_delta)), 1385 testing::Field( 1386 &DidOverscrollParams::current_fling_velocity, 1387 testing::Property(&gfx::Vector2dF::x, testing::Lt(0)))))); 1388 input_handler_->DidOverscroll(accumulated_overscroll, 1389 latest_overscroll_delta); 1390 // The next call to animate will no longer scroll horizontally or vertically, 1391 // and the fling should be cancelled. 1392 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()).Times(0); 1393 EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_, testing::_)).Times(0); 1394 EXPECT_CALL(mock_input_handler_, ScrollEnd()); 1395 time += base::TimeDelta::FromMilliseconds(10); 1396 input_handler_->Animate(time); 1397 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 1398 EXPECT_FALSE(input_handler_->gesture_scroll_on_impl_thread_for_testing()); 1399 } 1400 1401 TEST_F(InputHandlerProxyTest, MultiTouchPointHitTestNegative) { 1402 // None of the three touch points fall in the touch region. So the event 1403 // should be dropped. 1404 expected_disposition_ = InputHandlerProxy::DROP_EVENT; 1405 VERIFY_AND_RESET_MOCKS(); 1406 1407 EXPECT_CALL(mock_input_handler_, 1408 HaveTouchEventHandlersAt( 1409 testing::Property(&gfx::Point::x, testing::Gt(0)))) 1410 .WillOnce(testing::Return(false)); 1411 EXPECT_CALL(mock_input_handler_, 1412 HaveTouchEventHandlersAt( 1413 testing::Property(&gfx::Point::x, testing::Lt(0)))) 1414 .WillOnce(testing::Return(false)); 1415 1416 WebTouchEvent touch; 1417 touch.type = WebInputEvent::TouchStart; 1418 1419 touch.touchesLength = 3; 1420 touch.touches[0] = CreateWebTouchPoint(WebTouchPoint::StateStationary, 0, 0); 1421 touch.touches[1] = CreateWebTouchPoint(WebTouchPoint::StatePressed, 10, 10); 1422 touch.touches[2] = CreateWebTouchPoint(WebTouchPoint::StatePressed, -10, 10); 1423 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(touch)); 1424 } 1425 1426 TEST_F(InputHandlerProxyTest, MultiTouchPointHitTestPositive) { 1427 // One of the touch points is on a touch-region. So the event should be sent 1428 // to the main thread. 1429 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE; 1430 VERIFY_AND_RESET_MOCKS(); 1431 1432 EXPECT_CALL(mock_input_handler_, 1433 HaveTouchEventHandlersAt( 1434 testing::Property(&gfx::Point::x, testing::Eq(0)))) 1435 .WillOnce(testing::Return(false)); 1436 EXPECT_CALL(mock_input_handler_, 1437 HaveTouchEventHandlersAt( 1438 testing::Property(&gfx::Point::x, testing::Gt(0)))) 1439 .WillOnce(testing::Return(true)); 1440 // Since the second touch point hits a touch-region, there should be no 1441 // hit-testing for the third touch point. 1442 1443 WebTouchEvent touch; 1444 touch.type = WebInputEvent::TouchStart; 1445 1446 touch.touchesLength = 3; 1447 touch.touches[0] = CreateWebTouchPoint(WebTouchPoint::StatePressed, 0, 0); 1448 touch.touches[1] = CreateWebTouchPoint(WebTouchPoint::StatePressed, 10, 10); 1449 touch.touches[2] = CreateWebTouchPoint(WebTouchPoint::StatePressed, -10, 10); 1450 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(touch)); 1451 } 1452 1453 TEST_F(InputHandlerProxyTest, GestureFlingCancelledByKeyboardEvent) { 1454 // We shouldn't send any events to the widget for this gesture. 1455 expected_disposition_ = InputHandlerProxy::DID_HANDLE; 1456 VERIFY_AND_RESET_MOCKS(); 1457 1458 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 1459 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 1460 gesture_.type = WebInputEvent::GestureScrollBegin; 1461 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; 1462 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 1463 EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing()); 1464 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 1465 1466 // Keyboard events received during a scroll should have no effect. 1467 WebKeyboardEvent key_event; 1468 key_event.type = WebInputEvent::KeyDown; 1469 EXPECT_EQ(InputHandlerProxy::DID_NOT_HANDLE, 1470 input_handler_->HandleInputEvent(key_event)); 1471 EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing()); 1472 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 1473 1474 // On the fling start, animation should be scheduled, but no scrolling occurs. 1475 gesture_.type = WebInputEvent::GestureFlingStart; 1476 WebFloatPoint fling_delta = WebFloatPoint(100, 100); 1477 gesture_.data.flingStart.velocityX = fling_delta.x; 1478 gesture_.data.flingStart.velocityY = fling_delta.y; 1479 EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) 1480 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 1481 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 1482 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 1483 EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing()); 1484 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 1485 1486 // Keyboard events received during a fling should cancel the active fling. 1487 EXPECT_CALL(mock_input_handler_, ScrollEnd()); 1488 EXPECT_EQ(InputHandlerProxy::DID_NOT_HANDLE, 1489 input_handler_->HandleInputEvent(key_event)); 1490 EXPECT_FALSE(input_handler_->gesture_scroll_on_impl_thread_for_testing()); 1491 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 1492 1493 // The call to animate should have no effect, as the fling was cancelled. 1494 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10); 1495 input_handler_->Animate(time); 1496 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 1497 1498 // A fling cancel should be dropped, as there is nothing to cancel. 1499 gesture_.type = WebInputEvent::GestureFlingCancel; 1500 EXPECT_EQ(InputHandlerProxy::DROP_EVENT, 1501 input_handler_->HandleInputEvent(gesture_)); 1502 EXPECT_FALSE(input_handler_->gesture_scroll_on_impl_thread_for_testing()); 1503 } 1504 1505 TEST_F(InputHandlerProxyTest, GestureFlingWithNegativeTimeDelta) { 1506 // We shouldn't send any events to the widget for this gesture. 1507 expected_disposition_ = InputHandlerProxy::DID_HANDLE; 1508 VERIFY_AND_RESET_MOCKS(); 1509 1510 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 1511 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 1512 1513 gesture_.type = WebInputEvent::GestureScrollBegin; 1514 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; 1515 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 1516 1517 VERIFY_AND_RESET_MOCKS(); 1518 1519 // On the fling start, we should schedule an animation but not actually start 1520 // scrolling. 1521 base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10); 1522 base::TimeTicks time = base::TimeTicks() + dt; 1523 WebFloatPoint fling_delta = WebFloatPoint(100, 0); 1524 WebPoint fling_point = WebPoint(7, 13); 1525 WebPoint fling_global_point = WebPoint(17, 23); 1526 int modifiers = WebInputEvent::ControlKey; 1527 gesture_ = CreateFling(time, 1528 blink::WebGestureDeviceTouchscreen, 1529 fling_delta, 1530 fling_point, 1531 fling_global_point, 1532 modifiers); 1533 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 1534 EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) 1535 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 1536 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 1537 1538 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 1539 1540 // If we get a negative time delta, that is, the Animation tick time happens 1541 // before the fling's start time then we should *not* try scrolling and 1542 // instead reset the fling start time. 1543 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 1544 EXPECT_CALL(mock_input_handler_, 1545 ScrollBy(testing::_, 1546 testing::_)).Times(0); 1547 time -= base::TimeDelta::FromMilliseconds(5); 1548 input_handler_->Animate(time); 1549 1550 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 1551 1552 // The first call should have reset the start time so subsequent calls should 1553 // generate scroll events. 1554 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 1555 EXPECT_CALL(mock_input_handler_, 1556 ScrollBy(testing::_, 1557 testing::Property(&gfx::Vector2dF::x, testing::Lt(0)))) 1558 .WillOnce(testing::Return(true)); 1559 1560 input_handler_->Animate(time + base::TimeDelta::FromMilliseconds(1)); 1561 1562 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); 1563 1564 EXPECT_CALL(mock_input_handler_, ScrollEnd()); 1565 gesture_.type = WebInputEvent::GestureFlingCancel; 1566 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 1567 } 1568 1569 TEST_F(InputHandlerProxyTest, FlingBoost) { 1570 base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10); 1571 base::TimeTicks time = base::TimeTicks() + dt; 1572 base::TimeTicks last_animate_time = time; 1573 WebFloatPoint fling_delta = WebFloatPoint(1000, 0); 1574 WebPoint fling_point = WebPoint(7, 13); 1575 StartFling( 1576 time, blink::WebGestureDeviceTouchscreen, fling_delta, fling_point); 1577 1578 // Now cancel the fling. The fling cancellation should be deferred to allow 1579 // fling boosting events to arrive. 1580 time += dt; 1581 CancelFling(time); 1582 1583 // The GestureScrollBegin should be swallowed by the fling if it hits the same 1584 // scrolling layer. 1585 EXPECT_CALL(mock_input_handler_, 1586 IsCurrentlyScrollingLayerAt(testing::_, testing::_)) 1587 .WillOnce(testing::Return(true)); 1588 1589 time += dt; 1590 gesture_.timeStampSeconds = InSecondsF(time); 1591 gesture_.type = WebInputEvent::GestureScrollBegin; 1592 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 1593 1594 VERIFY_AND_RESET_MOCKS(); 1595 1596 // Animate calls within the deferred cancellation window should continue. 1597 time += dt; 1598 float expected_delta = 1599 (time - last_animate_time).InSecondsF() * -fling_delta.x; 1600 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 1601 EXPECT_CALL(mock_input_handler_, 1602 ScrollBy(testing::_, 1603 testing::Property(&gfx::Vector2dF::x, 1604 testing::Eq(expected_delta)))) 1605 .WillOnce(testing::Return(true)); 1606 input_handler_->Animate(time); 1607 last_animate_time = time; 1608 1609 VERIFY_AND_RESET_MOCKS(); 1610 1611 // GestureScrollUpdates in the same direction and at sufficient speed should 1612 // be swallowed by the fling. 1613 time += dt; 1614 gesture_.timeStampSeconds = InSecondsF(time); 1615 gesture_.type = WebInputEvent::GestureScrollUpdate; 1616 gesture_.data.scrollUpdate.deltaX = fling_delta.x; 1617 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 1618 1619 VERIFY_AND_RESET_MOCKS(); 1620 1621 // Animate calls within the deferred cancellation window should continue. 1622 time += dt; 1623 expected_delta = (time - last_animate_time).InSecondsF() * -fling_delta.x; 1624 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 1625 EXPECT_CALL(mock_input_handler_, 1626 ScrollBy(testing::_, 1627 testing::Property(&gfx::Vector2dF::x, 1628 testing::Eq(expected_delta)))) 1629 .WillOnce(testing::Return(true)); 1630 input_handler_->Animate(time); 1631 last_animate_time = time; 1632 1633 VERIFY_AND_RESET_MOCKS(); 1634 1635 // GestureFlingStart in the same direction and at sufficient speed should 1636 // boost the active fling. 1637 1638 gesture_ = CreateFling(time, 1639 blink::WebGestureDeviceTouchscreen, 1640 fling_delta, 1641 fling_point, 1642 fling_point, 1643 0); 1644 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 1645 VERIFY_AND_RESET_MOCKS(); 1646 1647 time += dt; 1648 // Note we get *2x* as much delta because 2 flings have combined. 1649 expected_delta = 2 * (time - last_animate_time).InSecondsF() * -fling_delta.x; 1650 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 1651 EXPECT_CALL(mock_input_handler_, 1652 ScrollBy(testing::_, 1653 testing::Property(&gfx::Vector2dF::x, 1654 testing::Eq(expected_delta)))) 1655 .WillOnce(testing::Return(true)); 1656 input_handler_->Animate(time); 1657 last_animate_time = time; 1658 1659 VERIFY_AND_RESET_MOCKS(); 1660 1661 // Repeated GestureFlingStarts should accumulate. 1662 1663 CancelFling(time); 1664 gesture_ = CreateFling(time, 1665 blink::WebGestureDeviceTouchscreen, 1666 fling_delta, 1667 fling_point, 1668 fling_point, 1669 0); 1670 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 1671 VERIFY_AND_RESET_MOCKS(); 1672 1673 time += dt; 1674 // Note we get *3x* as much delta because 3 flings have combined. 1675 expected_delta = 3 * (time - last_animate_time).InSecondsF() * -fling_delta.x; 1676 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 1677 EXPECT_CALL(mock_input_handler_, 1678 ScrollBy(testing::_, 1679 testing::Property(&gfx::Vector2dF::x, 1680 testing::Eq(expected_delta)))) 1681 .WillOnce(testing::Return(true)); 1682 input_handler_->Animate(time); 1683 last_animate_time = time; 1684 1685 VERIFY_AND_RESET_MOCKS(); 1686 1687 // GestureFlingCancel should terminate the fling if no boosting gestures are 1688 // received within the timeout window. 1689 1690 time += dt; 1691 gesture_.timeStampSeconds = InSecondsF(time); 1692 gesture_.type = WebInputEvent::GestureFlingCancel; 1693 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 1694 1695 VERIFY_AND_RESET_MOCKS(); 1696 1697 time += base::TimeDelta::FromMilliseconds(100); 1698 EXPECT_CALL(mock_input_handler_, ScrollEnd()); 1699 input_handler_->Animate(time); 1700 1701 VERIFY_AND_RESET_MOCKS(); 1702 } 1703 1704 TEST_F(InputHandlerProxyTest, NoFlingBoostIfScrollTargetsDifferentLayer) { 1705 base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10); 1706 base::TimeTicks time = base::TimeTicks() + dt; 1707 WebFloatPoint fling_delta = WebFloatPoint(1000, 0); 1708 WebPoint fling_point = WebPoint(7, 13); 1709 StartFling( 1710 time, blink::WebGestureDeviceTouchscreen, fling_delta, fling_point); 1711 1712 // Cancel the fling. The fling cancellation should be deferred to allow 1713 // fling boosting events to arrive. 1714 time += dt; 1715 CancelFling(time); 1716 1717 // If the GestureScrollBegin targets a different layer, the fling should be 1718 // cancelled and the scroll should be handled as usual. 1719 EXPECT_CALL(mock_input_handler_, 1720 IsCurrentlyScrollingLayerAt(testing::_, testing::_)) 1721 .WillOnce(testing::Return(false)); 1722 EXPECT_CALL(mock_input_handler_, ScrollEnd()); 1723 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 1724 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 1725 1726 time += dt; 1727 gesture_.timeStampSeconds = InSecondsF(time); 1728 gesture_.type = WebInputEvent::GestureScrollBegin; 1729 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 1730 1731 VERIFY_AND_RESET_MOCKS(); 1732 } 1733 1734 TEST_F(InputHandlerProxyTest, NoFlingBoostIfScrollDelayed) { 1735 base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10); 1736 base::TimeTicks time = base::TimeTicks() + dt; 1737 WebFloatPoint fling_delta = WebFloatPoint(1000, 0); 1738 WebPoint fling_point = WebPoint(7, 13); 1739 StartFling( 1740 time, blink::WebGestureDeviceTouchscreen, fling_delta, fling_point); 1741 1742 // Cancel the fling. The fling cancellation should be deferred to allow 1743 // fling boosting events to arrive. 1744 time += dt; 1745 CancelFling(time); 1746 1747 // The GestureScrollBegin should be swallowed by the fling if it hits the same 1748 // scrolling layer. 1749 EXPECT_CALL(mock_input_handler_, 1750 IsCurrentlyScrollingLayerAt(testing::_, testing::_)) 1751 .WillOnce(testing::Return(true)); 1752 1753 time += dt; 1754 gesture_.timeStampSeconds = InSecondsF(time); 1755 gesture_.type = WebInputEvent::GestureScrollBegin; 1756 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 1757 1758 VERIFY_AND_RESET_MOCKS(); 1759 1760 // If no GestureScrollUpdate or GestureFlingStart is received within the 1761 // timeout window, the fling should be cancelled and scrolling should resume. 1762 time += base::TimeDelta::FromMilliseconds(100); 1763 EXPECT_CALL(mock_input_handler_, ScrollEnd()); 1764 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 1765 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 1766 input_handler_->Animate(time); 1767 1768 VERIFY_AND_RESET_MOCKS(); 1769 } 1770 1771 TEST_F(InputHandlerProxyTest, NoFlingBoostIfScrollInDifferentDirection) { 1772 base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10); 1773 base::TimeTicks time = base::TimeTicks() + dt; 1774 WebFloatPoint fling_delta = WebFloatPoint(1000, 0); 1775 WebPoint fling_point = WebPoint(7, 13); 1776 StartFling( 1777 time, blink::WebGestureDeviceTouchscreen, fling_delta, fling_point); 1778 1779 // Cancel the fling. The fling cancellation should be deferred to allow 1780 // fling boosting events to arrive. 1781 time += dt; 1782 CancelFling(time); 1783 1784 // The GestureScrollBegin should be swallowed by the fling if it hits the same 1785 // scrolling layer. 1786 EXPECT_CALL(mock_input_handler_, 1787 IsCurrentlyScrollingLayerAt(testing::_, testing::_)) 1788 .WillOnce(testing::Return(true)); 1789 1790 time += dt; 1791 gesture_.timeStampSeconds = InSecondsF(time); 1792 gesture_.type = WebInputEvent::GestureScrollBegin; 1793 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 1794 1795 VERIFY_AND_RESET_MOCKS(); 1796 1797 // If the GestureScrollUpdate is in a different direction than the fling, 1798 // the fling should be cancelled and scrolling should resume. 1799 time += dt; 1800 gesture_.timeStampSeconds = InSecondsF(time); 1801 gesture_.type = WebInputEvent::GestureScrollUpdate; 1802 gesture_.data.scrollUpdate.deltaX = -fling_delta.x; 1803 EXPECT_CALL(mock_input_handler_, ScrollEnd()); 1804 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) 1805 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); 1806 EXPECT_CALL(mock_input_handler_, 1807 ScrollBy(testing::_, 1808 testing::Property(&gfx::Vector2dF::x, 1809 testing::Eq(fling_delta.x)))) 1810 .WillOnce(testing::Return(true)); 1811 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 1812 1813 VERIFY_AND_RESET_MOCKS(); 1814 } 1815 1816 TEST_F(InputHandlerProxyTest, NoFlingBoostIfFlingTooSlow) { 1817 base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10); 1818 base::TimeTicks time = base::TimeTicks() + dt; 1819 WebFloatPoint fling_delta = WebFloatPoint(1000, 0); 1820 WebPoint fling_point = WebPoint(7, 13); 1821 StartFling( 1822 time, blink::WebGestureDeviceTouchscreen, fling_delta, fling_point); 1823 1824 // Cancel the fling. The fling cancellation should be deferred to allow 1825 // fling boosting events to arrive. 1826 time += dt; 1827 CancelFling(time); 1828 1829 // If the new fling is too slow, no boosting should take place, with the new 1830 // fling replacing the old. 1831 WebFloatPoint small_fling_delta = WebFloatPoint(100, 0); 1832 gesture_ = CreateFling(time, 1833 blink::WebGestureDeviceTouchscreen, 1834 small_fling_delta, 1835 fling_point, 1836 fling_point, 1837 0); 1838 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); 1839 1840 VERIFY_AND_RESET_MOCKS(); 1841 1842 // Note that the new fling delta uses the *slow*, unboosted fling velocity. 1843 time += dt; 1844 float expected_delta = dt.InSecondsF() * -small_fling_delta.x; 1845 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()); 1846 EXPECT_CALL(mock_input_handler_, 1847 ScrollBy(testing::_, 1848 testing::Property(&gfx::Vector2dF::x, 1849 testing::Eq(expected_delta)))) 1850 .WillOnce(testing::Return(true)); 1851 input_handler_->Animate(time); 1852 1853 VERIFY_AND_RESET_MOCKS(); 1854 } 1855 1856 } // namespace 1857 } // namespace content 1858