OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 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/gpu/input_handler_proxy.h" |
| 6 |
| 7 #include "base/basictypes.h" |
| 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "content/renderer/gpu/input_handler_proxy_client.h" |
| 10 #include "testing/gmock/include/gmock/gmock.h" |
| 11 #include "testing/gtest/include/gtest/gtest.h" |
| 12 #include "third_party/WebKit/Source/Platform/chromium/public/WebFloatPoint.h" |
| 13 #include "third_party/WebKit/Source/Platform/chromium/public/WebFloatSize.h" |
| 14 #include "third_party/WebKit/Source/Platform/chromium/public/WebGestureCurve.h" |
| 15 #include "third_party/WebKit/Source/Platform/chromium/public/WebPoint.h" |
| 16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" |
| 17 |
| 18 using WebKit::WebActiveWheelFlingParameters; |
| 19 using WebKit::WebFloatPoint; |
| 20 using WebKit::WebFloatSize; |
| 21 using WebKit::WebGestureEvent; |
| 22 using WebKit::WebInputEvent; |
| 23 using WebKit::WebMouseWheelEvent; |
| 24 using WebKit::WebPoint; |
| 25 using WebKit::WebSize; |
| 26 |
| 27 namespace { |
| 28 |
| 29 class MockInputHandler : public cc::InputHandler { |
| 30 public: |
| 31 MockInputHandler() {} |
| 32 virtual ~MockInputHandler() {} |
| 33 |
| 34 MOCK_METHOD0(PinchGestureBegin, void()); |
| 35 MOCK_METHOD2(PinchGestureUpdate, |
| 36 void(float magnify_delta, gfx::Point anchor)); |
| 37 MOCK_METHOD0(PinchGestureEnd, void()); |
| 38 |
| 39 MOCK_METHOD0(ScheduleAnimation, void()); |
| 40 |
| 41 MOCK_METHOD2(ScrollBegin, |
| 42 ScrollStatus(gfx::Point viewport_point, |
| 43 cc::InputHandler::ScrollInputType type)); |
| 44 MOCK_METHOD2(ScrollBy, |
| 45 bool(gfx::Point viewport_point, gfx::Vector2dF scroll_delta)); |
| 46 MOCK_METHOD2(ScrollVerticallyByPage, |
| 47 bool(gfx::Point viewport_point, |
| 48 WebKit::WebScrollbar::ScrollDirection direction)); |
| 49 MOCK_METHOD0(ScrollEnd, void()); |
| 50 MOCK_METHOD0(FlingScrollBegin, cc::InputHandler::ScrollStatus()); |
| 51 |
| 52 MOCK_METHOD1(DidReceiveLastInputEventForVSync, void(base::TimeTicks time)); |
| 53 |
| 54 virtual void BindToClient(cc::InputHandlerClient* client) OVERRIDE {} |
| 55 |
| 56 virtual void StartPageScaleAnimation(gfx::Vector2d target_offset, |
| 57 bool anchor_point, |
| 58 float page_scale, |
| 59 base::TimeTicks start_time, |
| 60 base::TimeDelta duration) OVERRIDE {} |
| 61 |
| 62 virtual void NotifyCurrentFlingVelocity(gfx::Vector2dF velocity) OVERRIDE {} |
| 63 |
| 64 virtual bool HaveTouchEventHandlersAt(gfx::Point point) OVERRIDE { |
| 65 return false; |
| 66 } |
| 67 |
| 68 virtual void SetRootLayerScrollOffsetDelegate( |
| 69 cc::LayerScrollOffsetDelegate* root_layer_scroll_offset_delegate) |
| 70 OVERRIDE {} |
| 71 |
| 72 virtual void OnRootLayerDelegatedScrollOffsetChanged() OVERRIDE {} |
| 73 |
| 74 DISALLOW_COPY_AND_ASSIGN(MockInputHandler); |
| 75 }; |
| 76 |
| 77 // A simple WebGestureCurve implementation that flings at a constant velocity |
| 78 // indefinitely. |
| 79 class FakeWebGestureCurve : public WebKit::WebGestureCurve { |
| 80 public: |
| 81 FakeWebGestureCurve(const WebKit::WebFloatPoint& velocity, |
| 82 const WebKit::WebSize& cumulative_scroll) |
| 83 : velocity_(velocity), cumulative_scroll_(cumulative_scroll) {} |
| 84 |
| 85 virtual ~FakeWebGestureCurve() {} |
| 86 |
| 87 // Returns false if curve has finished and can no longer be applied. |
| 88 virtual bool apply(double time, WebKit::WebGestureCurveTarget* target) { |
| 89 WebKit::WebSize displacement(velocity_.x * time, velocity_.y * time); |
| 90 WebKit::WebFloatSize increment( |
| 91 displacement.width - cumulative_scroll_.width, |
| 92 displacement.height - cumulative_scroll_.height); |
| 93 cumulative_scroll_ = displacement; |
| 94 // scrollBy() could delete this curve if the animation is over, so don't |
| 95 // touch any member variables after making that call. |
| 96 target->scrollBy(increment); |
| 97 return true; |
| 98 } |
| 99 |
| 100 private: |
| 101 WebKit::WebFloatPoint velocity_; |
| 102 WebKit::WebSize cumulative_scroll_; |
| 103 |
| 104 DISALLOW_COPY_AND_ASSIGN(FakeWebGestureCurve); |
| 105 }; |
| 106 |
| 107 class MockInputHandlerProxyClient |
| 108 : public content::InputHandlerProxyClient { |
| 109 public: |
| 110 MockInputHandlerProxyClient() {} |
| 111 virtual ~MockInputHandlerProxyClient() {} |
| 112 |
| 113 virtual void WillShutdown() OVERRIDE {} |
| 114 |
| 115 MOCK_METHOD0(DidHandleInputEvent, void()); |
| 116 MOCK_METHOD1(DidNotHandleInputEvent, void(bool send_to_widget)); |
| 117 |
| 118 MOCK_METHOD1(TransferActiveWheelFlingAnimation, |
| 119 void(const WebActiveWheelFlingParameters&)); |
| 120 |
| 121 virtual WebKit::WebGestureCurve* CreateFlingAnimationCurve( |
| 122 int deviceSource, |
| 123 const WebFloatPoint& velocity, |
| 124 const WebSize& cumulative_scroll) OVERRIDE { |
| 125 return new FakeWebGestureCurve(velocity, cumulative_scroll); |
| 126 } |
| 127 |
| 128 private: |
| 129 DISALLOW_COPY_AND_ASSIGN(MockInputHandlerProxyClient); |
| 130 }; |
| 131 |
| 132 class InputHandlerProxyTest : public testing::Test { |
| 133 public: |
| 134 InputHandlerProxyTest() : expected_disposition_(DidHandle) { |
| 135 input_handler_.reset( |
| 136 new content::InputHandlerProxy(&mock_input_handler_)); |
| 137 input_handler_->SetClient(&mock_client_); |
| 138 } |
| 139 |
| 140 ~InputHandlerProxyTest() { |
| 141 input_handler_.reset(); |
| 142 } |
| 143 |
| 144 // This is defined as a macro because when an expectation is not satisfied the |
| 145 // only output you get |
| 146 // out of gmock is the line number that set the expectation. |
| 147 #define VERIFY_AND_RESET_MOCKS() \ |
| 148 do { \ |
| 149 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); \ |
| 150 testing::Mock::VerifyAndClearExpectations(&mock_client_); \ |
| 151 switch (expected_disposition_) { \ |
| 152 case DidHandle: \ |
| 153 /* If we expect to handle events, we shouldn't get any */ \ |
| 154 /* DidNotHandleInputEvent() calls with any parameter. */ \ |
| 155 EXPECT_CALL(mock_client_, DidNotHandleInputEvent(::testing::_)) \ |
| 156 .Times(0); \ |
| 157 EXPECT_CALL(mock_client_, DidHandleInputEvent()); \ |
| 158 break; \ |
| 159 case DidNotHandle: \ |
| 160 /* If we aren't expecting to handle events, we shouldn't call */ \ |
| 161 /* DidHandleInputEvent(). */ \ |
| 162 EXPECT_CALL(mock_client_, DidHandleInputEvent()).Times(0); \ |
| 163 EXPECT_CALL(mock_client_, DidNotHandleInputEvent(false)).Times(0); \ |
| 164 EXPECT_CALL(mock_client_, DidNotHandleInputEvent(true)); \ |
| 165 break; \ |
| 166 case DropEvent: \ |
| 167 /* If we're expecting to drop, we shouldn't get any didHandle..() */ \ |
| 168 /* or DidNotHandleInputEvent(true) calls. */ \ |
| 169 EXPECT_CALL(mock_client_, DidHandleInputEvent()).Times(0); \ |
| 170 EXPECT_CALL(mock_client_, DidNotHandleInputEvent(true)).Times(0); \ |
| 171 EXPECT_CALL(mock_client_, DidNotHandleInputEvent(false)); \ |
| 172 break; \ |
| 173 } \ |
| 174 } while (false) |
| 175 |
| 176 protected: |
| 177 testing::StrictMock<MockInputHandler> mock_input_handler_; |
| 178 scoped_ptr<content::InputHandlerProxy> input_handler_; |
| 179 testing::StrictMock<MockInputHandlerProxyClient> mock_client_; |
| 180 WebGestureEvent gesture_; |
| 181 |
| 182 enum ExpectedDisposition { |
| 183 DidHandle, |
| 184 DidNotHandle, |
| 185 DropEvent |
| 186 }; |
| 187 ExpectedDisposition expected_disposition_; |
| 188 }; |
| 189 |
| 190 TEST_F(InputHandlerProxyTest, MouseWheelByPageMainThread) { |
| 191 WebMouseWheelEvent wheel; |
| 192 wheel.type = WebInputEvent::MouseWheel; |
| 193 wheel.scrollByPage = true; |
| 194 |
| 195 EXPECT_CALL(mock_client_, DidNotHandleInputEvent(true)).Times(1); |
| 196 input_handler_->HandleInputEvent(wheel); |
| 197 testing::Mock::VerifyAndClearExpectations(&mock_client_); |
| 198 } |
| 199 |
| 200 TEST_F(InputHandlerProxyTest, GestureScrollStarted) { |
| 201 // We shouldn't send any events to the widget for this gesture. |
| 202 expected_disposition_ = DidHandle; |
| 203 VERIFY_AND_RESET_MOCKS(); |
| 204 |
| 205 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) |
| 206 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); |
| 207 |
| 208 gesture_.type = WebInputEvent::GestureScrollBegin; |
| 209 input_handler_->HandleInputEvent(gesture_); |
| 210 |
| 211 // The event should not be marked as handled if scrolling is not possible. |
| 212 expected_disposition_ = DropEvent; |
| 213 VERIFY_AND_RESET_MOCKS(); |
| 214 |
| 215 gesture_.type = WebInputEvent::GestureScrollUpdate; |
| 216 gesture_.data.scrollUpdate.deltaY = |
| 217 -40; // -Y means scroll down - i.e. in the +Y direction. |
| 218 EXPECT_CALL(mock_input_handler_, |
| 219 ScrollBy(testing::_, |
| 220 testing::Property(&gfx::Vector2dF::y, testing::Gt(0)))) |
| 221 .WillOnce(testing::Return(false)); |
| 222 input_handler_->HandleInputEvent(gesture_); |
| 223 |
| 224 // Mark the event as handled if scroll happens. |
| 225 expected_disposition_ = DidHandle; |
| 226 VERIFY_AND_RESET_MOCKS(); |
| 227 |
| 228 gesture_.type = WebInputEvent::GestureScrollUpdate; |
| 229 gesture_.data.scrollUpdate.deltaY = |
| 230 -40; // -Y means scroll down - i.e. in the +Y direction. |
| 231 EXPECT_CALL(mock_input_handler_, |
| 232 ScrollBy(testing::_, |
| 233 testing::Property(&gfx::Vector2dF::y, testing::Gt(0)))) |
| 234 .WillOnce(testing::Return(true)); |
| 235 input_handler_->HandleInputEvent(gesture_); |
| 236 |
| 237 VERIFY_AND_RESET_MOCKS(); |
| 238 |
| 239 gesture_.type = WebInputEvent::GestureScrollEnd; |
| 240 gesture_.data.scrollUpdate.deltaY = 0; |
| 241 EXPECT_CALL(mock_input_handler_, ScrollEnd()); |
| 242 input_handler_->HandleInputEvent(gesture_); |
| 243 } |
| 244 |
| 245 TEST_F(InputHandlerProxyTest, GestureScrollOnMainThread) { |
| 246 // We should send all events to the widget for this gesture. |
| 247 expected_disposition_ = DidNotHandle; |
| 248 VERIFY_AND_RESET_MOCKS(); |
| 249 |
| 250 EXPECT_CALL(mock_input_handler_, ScrollBegin(::testing::_, ::testing::_)) |
| 251 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread)); |
| 252 |
| 253 gesture_.type = WebInputEvent::GestureScrollBegin; |
| 254 input_handler_->HandleInputEvent(gesture_); |
| 255 |
| 256 VERIFY_AND_RESET_MOCKS(); |
| 257 |
| 258 gesture_.type = WebInputEvent::GestureScrollUpdate; |
| 259 gesture_.data.scrollUpdate.deltaY = 40; |
| 260 input_handler_->HandleInputEvent(gesture_); |
| 261 |
| 262 VERIFY_AND_RESET_MOCKS(); |
| 263 |
| 264 gesture_.type = WebInputEvent::GestureScrollEnd; |
| 265 gesture_.data.scrollUpdate.deltaY = 0; |
| 266 input_handler_->HandleInputEvent(gesture_); |
| 267 } |
| 268 |
| 269 TEST_F(InputHandlerProxyTest, GestureScrollIgnored) { |
| 270 // We shouldn't handle the GestureScrollBegin. |
| 271 // Instead, we should get one DidNotHandleInputEvent(false) call per |
| 272 // HandleInputEvent(), indicating that we could determine that there's nothing |
| 273 // that could scroll or otherwise react to this gesture sequence and thus we |
| 274 // should drop the whole gesture sequence on the floor. |
| 275 expected_disposition_ = DropEvent; |
| 276 VERIFY_AND_RESET_MOCKS(); |
| 277 |
| 278 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) |
| 279 .WillOnce(testing::Return(cc::InputHandler::ScrollIgnored)); |
| 280 |
| 281 gesture_.type = WebInputEvent::GestureScrollBegin; |
| 282 input_handler_->HandleInputEvent(gesture_); |
| 283 } |
| 284 |
| 285 TEST_F(InputHandlerProxyTest, GesturePinch) { |
| 286 // We shouldn't send any events to the widget for this gesture. |
| 287 expected_disposition_ = DidHandle; |
| 288 VERIFY_AND_RESET_MOCKS(); |
| 289 |
| 290 gesture_.type = WebInputEvent::GesturePinchBegin; |
| 291 EXPECT_CALL(mock_input_handler_, PinchGestureBegin()); |
| 292 input_handler_->HandleInputEvent(gesture_); |
| 293 |
| 294 VERIFY_AND_RESET_MOCKS(); |
| 295 |
| 296 gesture_.type = WebInputEvent::GesturePinchUpdate; |
| 297 gesture_.data.pinchUpdate.scale = 1.5; |
| 298 gesture_.x = 7; |
| 299 gesture_.y = 13; |
| 300 EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(1.5, gfx::Point(7, 13))); |
| 301 input_handler_->HandleInputEvent(gesture_); |
| 302 |
| 303 VERIFY_AND_RESET_MOCKS(); |
| 304 |
| 305 gesture_.type = WebInputEvent::GesturePinchUpdate; |
| 306 gesture_.data.pinchUpdate.scale = 0.5; |
| 307 gesture_.x = 9; |
| 308 gesture_.y = 6; |
| 309 EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(.5, gfx::Point(9, 6))); |
| 310 input_handler_->HandleInputEvent(gesture_); |
| 311 |
| 312 VERIFY_AND_RESET_MOCKS(); |
| 313 |
| 314 gesture_.type = WebInputEvent::GesturePinchEnd; |
| 315 EXPECT_CALL(mock_input_handler_, PinchGestureEnd()); |
| 316 input_handler_->HandleInputEvent(gesture_); |
| 317 } |
| 318 |
| 319 TEST_F(InputHandlerProxyTest, GesturePinchAfterScrollOnMainThread) { |
| 320 // Scrolls will start by being sent to the main thread. |
| 321 expected_disposition_ = DidNotHandle; |
| 322 VERIFY_AND_RESET_MOCKS(); |
| 323 |
| 324 EXPECT_CALL(mock_input_handler_, ScrollBegin(::testing::_, ::testing::_)) |
| 325 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread)); |
| 326 |
| 327 gesture_.type = WebInputEvent::GestureScrollBegin; |
| 328 input_handler_->HandleInputEvent(gesture_); |
| 329 |
| 330 VERIFY_AND_RESET_MOCKS(); |
| 331 |
| 332 gesture_.type = WebInputEvent::GestureScrollUpdate; |
| 333 gesture_.data.scrollUpdate.deltaY = 40; |
| 334 input_handler_->HandleInputEvent(gesture_); |
| 335 |
| 336 // However, after the pinch gesture starts, they should go to the impl |
| 337 // thread. |
| 338 expected_disposition_ = DidHandle; |
| 339 VERIFY_AND_RESET_MOCKS(); |
| 340 |
| 341 gesture_.type = WebInputEvent::GesturePinchBegin; |
| 342 EXPECT_CALL(mock_input_handler_, PinchGestureBegin()); |
| 343 input_handler_->HandleInputEvent(gesture_); |
| 344 |
| 345 VERIFY_AND_RESET_MOCKS(); |
| 346 |
| 347 gesture_.type = WebInputEvent::GesturePinchUpdate; |
| 348 gesture_.data.pinchUpdate.scale = 1.5; |
| 349 gesture_.x = 7; |
| 350 gesture_.y = 13; |
| 351 EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(1.5, gfx::Point(7, 13))); |
| 352 input_handler_->HandleInputEvent(gesture_); |
| 353 |
| 354 VERIFY_AND_RESET_MOCKS(); |
| 355 |
| 356 gesture_.type = WebInputEvent::GestureScrollUpdate; |
| 357 gesture_.data.scrollUpdate.deltaY = |
| 358 -40; // -Y means scroll down - i.e. in the +Y direction. |
| 359 EXPECT_CALL(mock_input_handler_, |
| 360 ScrollBy(testing::_, |
| 361 testing::Property(&gfx::Vector2dF::y, testing::Gt(0)))) |
| 362 .WillOnce(testing::Return(true)); |
| 363 input_handler_->HandleInputEvent(gesture_); |
| 364 |
| 365 VERIFY_AND_RESET_MOCKS(); |
| 366 |
| 367 gesture_.type = WebInputEvent::GesturePinchUpdate; |
| 368 gesture_.data.pinchUpdate.scale = 0.5; |
| 369 gesture_.x = 9; |
| 370 gesture_.y = 6; |
| 371 EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(.5, gfx::Point(9, 6))); |
| 372 input_handler_->HandleInputEvent(gesture_); |
| 373 |
| 374 VERIFY_AND_RESET_MOCKS(); |
| 375 |
| 376 gesture_.type = WebInputEvent::GesturePinchEnd; |
| 377 EXPECT_CALL(mock_input_handler_, PinchGestureEnd()); |
| 378 input_handler_->HandleInputEvent(gesture_); |
| 379 |
| 380 // After the pinch gesture ends, they should go to back to the main |
| 381 // thread. |
| 382 expected_disposition_ = DidNotHandle; |
| 383 VERIFY_AND_RESET_MOCKS(); |
| 384 |
| 385 gesture_.type = WebInputEvent::GestureScrollEnd; |
| 386 gesture_.data.scrollUpdate.deltaY = 0; |
| 387 input_handler_->HandleInputEvent(gesture_); |
| 388 } |
| 389 |
| 390 TEST_F(InputHandlerProxyTest, GestureFlingStartedTouchpad) { |
| 391 // We shouldn't send any events to the widget for this gesture. |
| 392 expected_disposition_ = DidHandle; |
| 393 VERIFY_AND_RESET_MOCKS(); |
| 394 |
| 395 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) |
| 396 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); |
| 397 EXPECT_CALL(mock_input_handler_, ScrollEnd()); |
| 398 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); |
| 399 |
| 400 gesture_.type = WebInputEvent::GestureFlingStart; |
| 401 gesture_.data.flingStart.velocityX = 10; |
| 402 gesture_.sourceDevice = WebGestureEvent::Touchpad; |
| 403 input_handler_->HandleInputEvent(gesture_); |
| 404 |
| 405 VERIFY_AND_RESET_MOCKS(); |
| 406 |
| 407 // Verify that a GestureFlingCancel during an animation cancels it. |
| 408 gesture_.type = WebInputEvent::GestureFlingCancel; |
| 409 gesture_.sourceDevice = WebGestureEvent::Touchpad; |
| 410 input_handler_->HandleInputEvent(gesture_); |
| 411 } |
| 412 |
| 413 TEST_F(InputHandlerProxyTest, GestureFlingOnMainThreadTouchpad) { |
| 414 // We should send all events to the widget for this gesture. |
| 415 expected_disposition_ = DidNotHandle; |
| 416 VERIFY_AND_RESET_MOCKS(); |
| 417 |
| 418 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) |
| 419 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread)); |
| 420 |
| 421 gesture_.type = WebInputEvent::GestureFlingStart; |
| 422 gesture_.sourceDevice = WebGestureEvent::Touchpad; |
| 423 input_handler_->HandleInputEvent(gesture_); |
| 424 |
| 425 // Since we returned ScrollStatusOnMainThread from scrollBegin, ensure the |
| 426 // input handler knows it's scrolling off the impl thread |
| 427 ASSERT_FALSE(input_handler_->gesture_scroll_on_impl_thread_for_testing()); |
| 428 |
| 429 VERIFY_AND_RESET_MOCKS(); |
| 430 |
| 431 // Even if we didn't start a fling ourselves, we still need to send the cancel |
| 432 // event to the widget. |
| 433 gesture_.type = WebInputEvent::GestureFlingCancel; |
| 434 gesture_.sourceDevice = WebGestureEvent::Touchpad; |
| 435 input_handler_->HandleInputEvent(gesture_); |
| 436 } |
| 437 |
| 438 TEST_F(InputHandlerProxyTest, GestureFlingIgnoredTouchpad) { |
| 439 expected_disposition_ = DidNotHandle; |
| 440 VERIFY_AND_RESET_MOCKS(); |
| 441 |
| 442 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) |
| 443 .WillOnce(testing::Return(cc::InputHandler::ScrollIgnored)); |
| 444 |
| 445 gesture_.type = WebInputEvent::GestureFlingStart; |
| 446 gesture_.sourceDevice = WebGestureEvent::Touchpad; |
| 447 input_handler_->HandleInputEvent(gesture_); |
| 448 |
| 449 expected_disposition_ = DropEvent; |
| 450 VERIFY_AND_RESET_MOCKS(); |
| 451 |
| 452 // Since the previous fling was ignored, we should also be dropping the next |
| 453 // fling_cancel. |
| 454 gesture_.type = WebInputEvent::GestureFlingCancel; |
| 455 gesture_.sourceDevice = WebGestureEvent::Touchpad; |
| 456 input_handler_->HandleInputEvent(gesture_); |
| 457 } |
| 458 |
| 459 TEST_F(InputHandlerProxyTest, GestureFlingAnimatesTouchpad) { |
| 460 // We shouldn't send any events to the widget for this gesture. |
| 461 expected_disposition_ = DidHandle; |
| 462 VERIFY_AND_RESET_MOCKS(); |
| 463 |
| 464 // On the fling start, we should schedule an animation but not actually start |
| 465 // scrolling. |
| 466 gesture_.type = WebInputEvent::GestureFlingStart; |
| 467 WebFloatPoint fling_delta = WebFloatPoint(1000, 0); |
| 468 WebPoint fling_point = WebPoint(7, 13); |
| 469 WebPoint fling_global_point = WebPoint(17, 23); |
| 470 int modifiers = 7; |
| 471 gesture_.data.flingStart.velocityX = fling_delta.x; |
| 472 gesture_.data.flingStart.velocityY = fling_delta.y; |
| 473 gesture_.sourceDevice = WebGestureEvent::Touchpad; |
| 474 gesture_.x = fling_point.x; |
| 475 gesture_.y = fling_point.y; |
| 476 gesture_.globalX = fling_global_point.x; |
| 477 gesture_.globalY = fling_global_point.y; |
| 478 gesture_.modifiers = modifiers; |
| 479 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); |
| 480 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) |
| 481 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); |
| 482 EXPECT_CALL(mock_input_handler_, ScrollEnd()); |
| 483 input_handler_->HandleInputEvent(gesture_); |
| 484 |
| 485 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); |
| 486 // The first animate call should let us pick up an animation start time, but |
| 487 // we shouldn't actually move anywhere just yet. The first frame after the |
| 488 // fling start will typically include the last scroll from the gesture that |
| 489 // lead to the scroll (either wheel or gesture scroll), so there should be no |
| 490 // visible hitch. |
| 491 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); |
| 492 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) |
| 493 .Times(0); |
| 494 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10); |
| 495 input_handler_->Animate(time); |
| 496 |
| 497 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); |
| 498 |
| 499 // The second call should start scrolling in the -X direction. |
| 500 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); |
| 501 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) |
| 502 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); |
| 503 EXPECT_CALL(mock_input_handler_, |
| 504 ScrollBy(testing::_, |
| 505 testing::Property(&gfx::Vector2dF::x, testing::Lt(0)))) |
| 506 .WillOnce(testing::Return(true)); |
| 507 EXPECT_CALL(mock_input_handler_, ScrollEnd()); |
| 508 time += base::TimeDelta::FromMilliseconds(100); |
| 509 input_handler_->Animate(time); |
| 510 |
| 511 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); |
| 512 |
| 513 // Let's say on the third call we hit a non-scrollable region. We should abort |
| 514 // the fling and not scroll. |
| 515 // We also should pass the current fling parameters out to the client so the |
| 516 // rest of the fling can be |
| 517 // transferred to the main thread. |
| 518 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); |
| 519 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) |
| 520 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread)); |
| 521 EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_, testing::_)).Times(0); |
| 522 EXPECT_CALL(mock_input_handler_, ScrollEnd()).Times(0); |
| 523 // Expected wheel fling animation parameters: |
| 524 // *) fling_delta and fling_point should match the original GestureFlingStart |
| 525 // event |
| 526 // *) startTime should be 10 to match the time parameter of the first |
| 527 // Animate() call after the GestureFlingStart |
| 528 // *) cumulativeScroll depends on the curve, but since we've animated in the |
| 529 // -X direction the X value should be < 0 |
| 530 EXPECT_CALL( |
| 531 mock_client_, |
| 532 TransferActiveWheelFlingAnimation(testing::AllOf( |
| 533 testing::Field(&WebActiveWheelFlingParameters::delta, |
| 534 testing::Eq(fling_delta)), |
| 535 testing::Field(&WebActiveWheelFlingParameters::point, |
| 536 testing::Eq(fling_point)), |
| 537 testing::Field(&WebActiveWheelFlingParameters::globalPoint, |
| 538 testing::Eq(fling_global_point)), |
| 539 testing::Field(&WebActiveWheelFlingParameters::modifiers, |
| 540 testing::Eq(modifiers)), |
| 541 testing::Field(&WebActiveWheelFlingParameters::startTime, |
| 542 testing::Eq(10)), |
| 543 testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll, |
| 544 testing::Field(&WebSize::width, testing::Gt(0)))))); |
| 545 time += base::TimeDelta::FromMilliseconds(100); |
| 546 input_handler_->Animate(time); |
| 547 |
| 548 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); |
| 549 testing::Mock::VerifyAndClearExpectations(&mock_client_); |
| 550 |
| 551 // Since we've aborted the fling, the next animation should be a no-op and |
| 552 // should not result in another |
| 553 // frame being requested. |
| 554 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()).Times(0); |
| 555 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) |
| 556 .Times(0); |
| 557 time += base::TimeDelta::FromMilliseconds(100); |
| 558 input_handler_->Animate(time); |
| 559 |
| 560 // Since we've transferred the fling to the main thread, we need to pass the |
| 561 // next GestureFlingCancel to the main |
| 562 // thread as well. |
| 563 EXPECT_CALL(mock_client_, DidNotHandleInputEvent(true)); |
| 564 gesture_.type = WebInputEvent::GestureFlingCancel; |
| 565 input_handler_->HandleInputEvent(gesture_); |
| 566 } |
| 567 |
| 568 TEST_F(InputHandlerProxyTest, GestureFlingTransferResetsTouchpad) { |
| 569 // We shouldn't send any events to the widget for this gesture. |
| 570 expected_disposition_ = DidHandle; |
| 571 VERIFY_AND_RESET_MOCKS(); |
| 572 |
| 573 // Start a gesture fling in the -X direction with zero Y movement. |
| 574 gesture_.type = WebInputEvent::GestureFlingStart; |
| 575 WebFloatPoint fling_delta = WebFloatPoint(1000, 0); |
| 576 WebPoint fling_point = WebPoint(7, 13); |
| 577 WebPoint fling_global_point = WebPoint(17, 23); |
| 578 int modifiers = 1; |
| 579 gesture_.data.flingStart.velocityX = fling_delta.x; |
| 580 gesture_.data.flingStart.velocityY = fling_delta.y; |
| 581 gesture_.sourceDevice = WebGestureEvent::Touchpad; |
| 582 gesture_.x = fling_point.x; |
| 583 gesture_.y = fling_point.y; |
| 584 gesture_.globalX = fling_global_point.x; |
| 585 gesture_.globalY = fling_global_point.y; |
| 586 gesture_.modifiers = modifiers; |
| 587 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); |
| 588 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) |
| 589 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); |
| 590 EXPECT_CALL(mock_input_handler_, ScrollEnd()); |
| 591 input_handler_->HandleInputEvent(gesture_); |
| 592 |
| 593 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); |
| 594 |
| 595 // Start the fling animation at time 10. This shouldn't actually scroll, just |
| 596 // establish a start time. |
| 597 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); |
| 598 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) |
| 599 .Times(0); |
| 600 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10); |
| 601 input_handler_->Animate(time); |
| 602 |
| 603 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); |
| 604 |
| 605 // The second call should start scrolling in the -X direction. |
| 606 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); |
| 607 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) |
| 608 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); |
| 609 EXPECT_CALL(mock_input_handler_, |
| 610 ScrollBy(testing::_, |
| 611 testing::Property(&gfx::Vector2dF::x, testing::Lt(0)))) |
| 612 .WillOnce(testing::Return(true)); |
| 613 EXPECT_CALL(mock_input_handler_, ScrollEnd()); |
| 614 time += base::TimeDelta::FromMilliseconds(100); |
| 615 input_handler_->Animate(time); |
| 616 |
| 617 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); |
| 618 |
| 619 // Let's say on the third call we hit a non-scrollable region. We should abort |
| 620 // the fling and not scroll. |
| 621 // We also should pass the current fling parameters out to the client so the |
| 622 // rest of the fling can be |
| 623 // transferred to the main thread. |
| 624 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); |
| 625 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) |
| 626 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread)); |
| 627 EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_, testing::_)).Times(0); |
| 628 EXPECT_CALL(mock_input_handler_, ScrollEnd()).Times(0); |
| 629 |
| 630 // Expected wheel fling animation parameters: |
| 631 // *) fling_delta and fling_point should match the original GestureFlingStart |
| 632 // event |
| 633 // *) startTime should be 10 to match the time parameter of the first |
| 634 // Animate() call after the GestureFlingStart |
| 635 // *) cumulativeScroll depends on the curve, but since we've animated in the |
| 636 // -X direction the X value should be < 0 |
| 637 EXPECT_CALL( |
| 638 mock_client_, |
| 639 TransferActiveWheelFlingAnimation(testing::AllOf( |
| 640 testing::Field(&WebActiveWheelFlingParameters::delta, |
| 641 testing::Eq(fling_delta)), |
| 642 testing::Field(&WebActiveWheelFlingParameters::point, |
| 643 testing::Eq(fling_point)), |
| 644 testing::Field(&WebActiveWheelFlingParameters::globalPoint, |
| 645 testing::Eq(fling_global_point)), |
| 646 testing::Field(&WebActiveWheelFlingParameters::modifiers, |
| 647 testing::Eq(modifiers)), |
| 648 testing::Field(&WebActiveWheelFlingParameters::startTime, |
| 649 testing::Eq(10)), |
| 650 testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll, |
| 651 testing::Field(&WebSize::width, testing::Gt(0)))))); |
| 652 time += base::TimeDelta::FromMilliseconds(100); |
| 653 input_handler_->Animate(time); |
| 654 |
| 655 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); |
| 656 testing::Mock::VerifyAndClearExpectations(&mock_client_); |
| 657 |
| 658 // Since we've aborted the fling, the next animation should be a no-op and |
| 659 // should not result in another |
| 660 // frame being requested. |
| 661 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()).Times(0); |
| 662 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) |
| 663 .Times(0); |
| 664 time += base::TimeDelta::FromMilliseconds(100); |
| 665 input_handler_->Animate(time); |
| 666 |
| 667 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); |
| 668 |
| 669 // Since we've transferred the fling to the main thread, we need to pass the |
| 670 // next GestureFlingCancel to the main |
| 671 // thread as well. |
| 672 EXPECT_CALL(mock_client_, DidNotHandleInputEvent(true)); |
| 673 gesture_.type = WebInputEvent::GestureFlingCancel; |
| 674 input_handler_->HandleInputEvent(gesture_); |
| 675 |
| 676 VERIFY_AND_RESET_MOCKS(); |
| 677 input_handler_->MainThreadHasStoppedFlinging(); |
| 678 |
| 679 // Start a second gesture fling, this time in the +Y direction with no X. |
| 680 gesture_.type = WebInputEvent::GestureFlingStart; |
| 681 fling_delta = WebFloatPoint(0, -1000); |
| 682 fling_point = WebPoint(95, 87); |
| 683 fling_global_point = WebPoint(32, 71); |
| 684 modifiers = 2; |
| 685 gesture_.data.flingStart.velocityX = fling_delta.x; |
| 686 gesture_.data.flingStart.velocityY = fling_delta.y; |
| 687 gesture_.sourceDevice = WebGestureEvent::Touchpad; |
| 688 gesture_.x = fling_point.x; |
| 689 gesture_.y = fling_point.y; |
| 690 gesture_.globalX = fling_global_point.x; |
| 691 gesture_.globalY = fling_global_point.y; |
| 692 gesture_.modifiers = modifiers; |
| 693 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); |
| 694 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) |
| 695 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); |
| 696 EXPECT_CALL(mock_input_handler_, ScrollEnd()); |
| 697 input_handler_->HandleInputEvent(gesture_); |
| 698 |
| 699 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); |
| 700 |
| 701 // Start the second fling animation at time 30. |
| 702 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); |
| 703 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) |
| 704 .Times(0); |
| 705 time = base::TimeTicks() + base::TimeDelta::FromSeconds(30); |
| 706 input_handler_->Animate(time); |
| 707 |
| 708 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); |
| 709 |
| 710 // Tick the second fling once normally. |
| 711 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); |
| 712 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) |
| 713 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); |
| 714 EXPECT_CALL(mock_input_handler_, |
| 715 ScrollBy(testing::_, |
| 716 testing::Property(&gfx::Vector2dF::y, testing::Gt(0)))) |
| 717 .WillOnce(testing::Return(true)); |
| 718 EXPECT_CALL(mock_input_handler_, ScrollEnd()); |
| 719 time += base::TimeDelta::FromMilliseconds(100); |
| 720 input_handler_->Animate(time); |
| 721 |
| 722 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); |
| 723 |
| 724 // Then abort the second fling. |
| 725 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); |
| 726 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) |
| 727 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread)); |
| 728 EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_, testing::_)).Times(0); |
| 729 EXPECT_CALL(mock_input_handler_, ScrollEnd()).Times(0); |
| 730 |
| 731 // We should get parameters from the second fling, nothing from the first |
| 732 // fling should "leak". |
| 733 EXPECT_CALL( |
| 734 mock_client_, |
| 735 TransferActiveWheelFlingAnimation(testing::AllOf( |
| 736 testing::Field(&WebActiveWheelFlingParameters::delta, |
| 737 testing::Eq(fling_delta)), |
| 738 testing::Field(&WebActiveWheelFlingParameters::point, |
| 739 testing::Eq(fling_point)), |
| 740 testing::Field(&WebActiveWheelFlingParameters::globalPoint, |
| 741 testing::Eq(fling_global_point)), |
| 742 testing::Field(&WebActiveWheelFlingParameters::modifiers, |
| 743 testing::Eq(modifiers)), |
| 744 testing::Field(&WebActiveWheelFlingParameters::startTime, |
| 745 testing::Eq(30)), |
| 746 testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll, |
| 747 testing::Field(&WebSize::height, testing::Lt(0)))))); |
| 748 time += base::TimeDelta::FromMilliseconds(100); |
| 749 input_handler_->Animate(time); |
| 750 } |
| 751 |
| 752 TEST_F(InputHandlerProxyTest, GestureFlingStartedTouchscreen) { |
| 753 // We shouldn't send any events to the widget for this gesture. |
| 754 expected_disposition_ = DidHandle; |
| 755 VERIFY_AND_RESET_MOCKS(); |
| 756 |
| 757 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) |
| 758 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); |
| 759 gesture_.type = WebInputEvent::GestureScrollBegin; |
| 760 gesture_.sourceDevice = WebGestureEvent::Touchscreen; |
| 761 input_handler_->HandleInputEvent(gesture_); |
| 762 |
| 763 VERIFY_AND_RESET_MOCKS(); |
| 764 |
| 765 EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) |
| 766 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); |
| 767 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); |
| 768 |
| 769 gesture_.type = WebInputEvent::GestureFlingStart; |
| 770 gesture_.data.flingStart.velocityX = 10; |
| 771 gesture_.sourceDevice = WebGestureEvent::Touchscreen; |
| 772 input_handler_->HandleInputEvent(gesture_); |
| 773 |
| 774 VERIFY_AND_RESET_MOCKS(); |
| 775 |
| 776 EXPECT_CALL(mock_input_handler_, ScrollEnd()); |
| 777 |
| 778 // Verify that a GestureFlingCancel during an animation cancels it. |
| 779 gesture_.type = WebInputEvent::GestureFlingCancel; |
| 780 gesture_.sourceDevice = WebGestureEvent::Touchscreen; |
| 781 input_handler_->HandleInputEvent(gesture_); |
| 782 } |
| 783 |
| 784 TEST_F(InputHandlerProxyTest, GestureFlingOnMainThreadTouchscreen) { |
| 785 // We should send all events to the widget for this gesture. |
| 786 expected_disposition_ = DidNotHandle; |
| 787 VERIFY_AND_RESET_MOCKS(); |
| 788 |
| 789 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) |
| 790 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread)); |
| 791 |
| 792 gesture_.type = WebInputEvent::GestureScrollBegin; |
| 793 input_handler_->HandleInputEvent(gesture_); |
| 794 |
| 795 VERIFY_AND_RESET_MOCKS(); |
| 796 |
| 797 EXPECT_CALL(mock_input_handler_, FlingScrollBegin()).Times(0); |
| 798 |
| 799 gesture_.type = WebInputEvent::GestureFlingStart; |
| 800 gesture_.sourceDevice = WebGestureEvent::Touchscreen; |
| 801 input_handler_->HandleInputEvent(gesture_); |
| 802 |
| 803 VERIFY_AND_RESET_MOCKS(); |
| 804 |
| 805 // Even if we didn't start a fling ourselves, we still need to send the cancel |
| 806 // event to the widget. |
| 807 gesture_.type = WebInputEvent::GestureFlingCancel; |
| 808 gesture_.sourceDevice = WebGestureEvent::Touchscreen; |
| 809 input_handler_->HandleInputEvent(gesture_); |
| 810 } |
| 811 |
| 812 TEST_F(InputHandlerProxyTest, GestureFlingIgnoredTouchscreen) { |
| 813 expected_disposition_ = DidHandle; |
| 814 VERIFY_AND_RESET_MOCKS(); |
| 815 |
| 816 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) |
| 817 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); |
| 818 |
| 819 gesture_.type = WebInputEvent::GestureScrollBegin; |
| 820 gesture_.sourceDevice = WebGestureEvent::Touchscreen; |
| 821 input_handler_->HandleInputEvent(gesture_); |
| 822 |
| 823 expected_disposition_ = DropEvent; |
| 824 VERIFY_AND_RESET_MOCKS(); |
| 825 |
| 826 EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) |
| 827 .WillOnce(testing::Return(cc::InputHandler::ScrollIgnored)); |
| 828 |
| 829 gesture_.type = WebInputEvent::GestureFlingStart; |
| 830 gesture_.sourceDevice = WebGestureEvent::Touchscreen; |
| 831 input_handler_->HandleInputEvent(gesture_); |
| 832 |
| 833 VERIFY_AND_RESET_MOCKS(); |
| 834 |
| 835 // Even if we didn't start a fling ourselves, we still need to send the cancel |
| 836 // event to the widget. |
| 837 gesture_.type = WebInputEvent::GestureFlingCancel; |
| 838 gesture_.sourceDevice = WebGestureEvent::Touchscreen; |
| 839 input_handler_->HandleInputEvent(gesture_); |
| 840 } |
| 841 |
| 842 TEST_F(InputHandlerProxyTest, GestureFlingAnimatesTouchscreen) { |
| 843 // We shouldn't send any events to the widget for this gesture. |
| 844 expected_disposition_ = DidHandle; |
| 845 VERIFY_AND_RESET_MOCKS(); |
| 846 |
| 847 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) |
| 848 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); |
| 849 |
| 850 gesture_.type = WebInputEvent::GestureScrollBegin; |
| 851 gesture_.sourceDevice = WebGestureEvent::Touchscreen; |
| 852 input_handler_->HandleInputEvent(gesture_); |
| 853 |
| 854 VERIFY_AND_RESET_MOCKS(); |
| 855 |
| 856 // On the fling start, we should schedule an animation but not actually start |
| 857 // scrolling. |
| 858 gesture_.type = WebInputEvent::GestureFlingStart; |
| 859 WebFloatPoint fling_delta = WebFloatPoint(1000, 0); |
| 860 WebPoint fling_point = WebPoint(7, 13); |
| 861 WebPoint fling_global_point = WebPoint(17, 23); |
| 862 int modifiers = 7; |
| 863 gesture_.data.flingStart.velocityX = fling_delta.x; |
| 864 gesture_.data.flingStart.velocityY = fling_delta.y; |
| 865 gesture_.sourceDevice = WebGestureEvent::Touchscreen; |
| 866 gesture_.x = fling_point.x; |
| 867 gesture_.y = fling_point.y; |
| 868 gesture_.globalX = fling_global_point.x; |
| 869 gesture_.globalY = fling_global_point.y; |
| 870 gesture_.modifiers = modifiers; |
| 871 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); |
| 872 EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) |
| 873 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); |
| 874 input_handler_->HandleInputEvent(gesture_); |
| 875 |
| 876 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); |
| 877 // The first animate call should let us pick up an animation start time, but |
| 878 // we shouldn't actually move anywhere just yet. The first frame after the |
| 879 // fling start will typically include the last scroll from the gesture that |
| 880 // lead to the scroll (either wheel or gesture scroll), so there should be no |
| 881 // visible hitch. |
| 882 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); |
| 883 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10); |
| 884 input_handler_->Animate(time); |
| 885 |
| 886 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); |
| 887 |
| 888 // The second call should start scrolling in the -X direction. |
| 889 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); |
| 890 EXPECT_CALL(mock_input_handler_, |
| 891 ScrollBy(testing::_, |
| 892 testing::Property(&gfx::Vector2dF::x, testing::Lt(0)))) |
| 893 .WillOnce(testing::Return(true)); |
| 894 time += base::TimeDelta::FromMilliseconds(100); |
| 895 input_handler_->Animate(time); |
| 896 |
| 897 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); |
| 898 |
| 899 EXPECT_CALL(mock_client_, DidHandleInputEvent()); |
| 900 EXPECT_CALL(mock_input_handler_, ScrollEnd()); |
| 901 gesture_.type = WebInputEvent::GestureFlingCancel; |
| 902 input_handler_->HandleInputEvent(gesture_); |
| 903 } |
| 904 |
| 905 TEST_F(InputHandlerProxyTest, |
| 906 GestureScrollOnImplThreadFlagClearedAfterFling) { |
| 907 // We shouldn't send any events to the widget for this gesture. |
| 908 expected_disposition_ = DidHandle; |
| 909 VERIFY_AND_RESET_MOCKS(); |
| 910 |
| 911 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) |
| 912 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); |
| 913 |
| 914 gesture_.type = WebInputEvent::GestureScrollBegin; |
| 915 input_handler_->HandleInputEvent(gesture_); |
| 916 |
| 917 // After sending a GestureScrollBegin, the member variable |
| 918 // |gesture_scroll_on_impl_thread_| should be true. |
| 919 EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing()); |
| 920 |
| 921 expected_disposition_ = DidHandle; |
| 922 VERIFY_AND_RESET_MOCKS(); |
| 923 |
| 924 // On the fling start, we should schedule an animation but not actually start |
| 925 // scrolling. |
| 926 gesture_.type = WebInputEvent::GestureFlingStart; |
| 927 WebFloatPoint fling_delta = WebFloatPoint(1000, 0); |
| 928 WebPoint fling_point = WebPoint(7, 13); |
| 929 WebPoint fling_global_point = WebPoint(17, 23); |
| 930 int modifiers = 7; |
| 931 gesture_.data.flingStart.velocityX = fling_delta.x; |
| 932 gesture_.data.flingStart.velocityY = fling_delta.y; |
| 933 gesture_.sourceDevice = WebGestureEvent::Touchscreen; |
| 934 gesture_.x = fling_point.x; |
| 935 gesture_.y = fling_point.y; |
| 936 gesture_.globalX = fling_global_point.x; |
| 937 gesture_.globalY = fling_global_point.y; |
| 938 gesture_.modifiers = modifiers; |
| 939 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); |
| 940 EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) |
| 941 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); |
| 942 input_handler_->HandleInputEvent(gesture_); |
| 943 |
| 944 // |gesture_scroll_on_impl_thread_| should still be true after |
| 945 // a GestureFlingStart is sent. |
| 946 EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing()); |
| 947 |
| 948 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); |
| 949 // The first animate call should let us pick up an animation start time, but |
| 950 // we shouldn't actually move anywhere just yet. The first frame after the |
| 951 // fling start will typically include the last scroll from the gesture that |
| 952 // lead to the scroll (either wheel or gesture scroll), so there should be no |
| 953 // visible hitch. |
| 954 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); |
| 955 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10); |
| 956 input_handler_->Animate(time); |
| 957 |
| 958 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); |
| 959 |
| 960 // The second call should start scrolling in the -X direction. |
| 961 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); |
| 962 EXPECT_CALL(mock_input_handler_, |
| 963 ScrollBy(testing::_, |
| 964 testing::Property(&gfx::Vector2dF::x, testing::Lt(0)))) |
| 965 .WillOnce(testing::Return(true)); |
| 966 time += base::TimeDelta::FromMilliseconds(100); |
| 967 input_handler_->Animate(time); |
| 968 |
| 969 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); |
| 970 |
| 971 EXPECT_CALL(mock_client_, DidHandleInputEvent()); |
| 972 EXPECT_CALL(mock_input_handler_, ScrollEnd()); |
| 973 gesture_.type = WebInputEvent::GestureFlingCancel; |
| 974 input_handler_->HandleInputEvent(gesture_); |
| 975 |
| 976 // |gesture_scroll_on_impl_thread_| should be false once |
| 977 // the fling has finished (note no GestureScrollEnd has been sent). |
| 978 EXPECT_TRUE(!input_handler_->gesture_scroll_on_impl_thread_for_testing()); |
| 979 } |
| 980 |
| 981 TEST_F(InputHandlerProxyTest, LastInputEventForVSync) { |
| 982 expected_disposition_ = DropEvent; |
| 983 VERIFY_AND_RESET_MOCKS(); |
| 984 |
| 985 gesture_.type = WebInputEvent::GestureFlingCancel; |
| 986 gesture_.timeStampSeconds = 1234; |
| 987 base::TimeTicks time = |
| 988 base::TimeTicks() + |
| 989 base::TimeDelta::FromSeconds(gesture_.timeStampSeconds); |
| 990 gesture_.modifiers |= WebInputEvent::IsLastInputEventForCurrentVSync; |
| 991 EXPECT_CALL(mock_input_handler_, DidReceiveLastInputEventForVSync(time)); |
| 992 input_handler_->HandleInputEvent(gesture_); |
| 993 } |
| 994 |
| 995 } // namespace |
OLD | NEW |