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