Include all dupe types (event when value is zero) in scan stats.
[chromium-blink-merge.git] / content / renderer / input / input_handler_proxy_unittest.cc
blobcfa8631f2bd67a6d5e416496d521e92bc04dce7c
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.
5 #include "content/renderer/input/input_handler_proxy.h"
7 #include "base/basictypes.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "cc/trees/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"
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 using testing::Field;
35 namespace content {
36 namespace {
38 double InSecondsF(const base::TimeTicks& time) {
39 return (time - base::TimeTicks()).InSecondsF();
42 WebGestureEvent CreateFling(base::TimeTicks timestamp,
43 WebGestureDevice source_device,
44 WebFloatPoint velocity,
45 WebPoint point,
46 WebPoint global_point,
47 int modifiers) {
48 WebGestureEvent fling;
49 fling.type = WebInputEvent::GestureFlingStart;
50 fling.sourceDevice = source_device;
51 fling.timeStampSeconds = (timestamp - base::TimeTicks()).InSecondsF();
52 fling.data.flingStart.velocityX = velocity.x;
53 fling.data.flingStart.velocityY = velocity.y;
54 fling.x = point.x;
55 fling.y = point.y;
56 fling.globalX = global_point.x;
57 fling.globalY = global_point.y;
58 fling.modifiers = modifiers;
59 return fling;
62 WebGestureEvent CreateFling(WebGestureDevice source_device,
63 WebFloatPoint velocity,
64 WebPoint point,
65 WebPoint global_point,
66 int modifiers) {
67 return CreateFling(base::TimeTicks(),
68 source_device,
69 velocity,
70 point,
71 global_point,
72 modifiers);
75 class MockInputHandler : public cc::InputHandler {
76 public:
77 MockInputHandler() {}
78 ~MockInputHandler() override {}
80 MOCK_METHOD0(PinchGestureBegin, void());
81 MOCK_METHOD2(PinchGestureUpdate,
82 void(float magnify_delta, const gfx::Point& anchor));
83 MOCK_METHOD0(PinchGestureEnd, void());
85 MOCK_METHOD0(SetNeedsAnimate, void());
87 MOCK_METHOD2(ScrollBegin,
88 ScrollStatus(const gfx::Point& viewport_point,
89 cc::InputHandler::ScrollInputType type));
90 MOCK_METHOD2(ScrollAnimated,
91 ScrollStatus(const gfx::Point& viewport_point,
92 const gfx::Vector2dF& scroll_delta));
93 MOCK_METHOD2(ScrollBy,
94 cc::InputHandlerScrollResult(
95 const gfx::Point& viewport_point,
96 const gfx::Vector2dF& scroll_delta));
97 MOCK_METHOD2(ScrollVerticallyByPage,
98 bool(const gfx::Point& viewport_point,
99 cc::ScrollDirection direction));
100 MOCK_METHOD0(ScrollEnd, void());
101 MOCK_METHOD0(FlingScrollBegin, cc::InputHandler::ScrollStatus());
103 scoped_ptr<cc::SwapPromiseMonitor> CreateLatencyInfoSwapPromiseMonitor(
104 ui::LatencyInfo* latency) override {
105 return scoped_ptr<cc::SwapPromiseMonitor>();
108 cc::ScrollElasticityHelper* CreateScrollElasticityHelper() override {
109 return NULL;
112 void BindToClient(cc::InputHandlerClient* client) override {}
114 void MouseMoveAt(const gfx::Point& mouse_position) override {}
116 MOCK_METHOD2(IsCurrentlyScrollingLayerAt,
117 bool(const gfx::Point& point,
118 cc::InputHandler::ScrollInputType type));
120 MOCK_METHOD1(HaveWheelEventHandlersAt, bool(const gfx::Point& point));
121 MOCK_METHOD1(DoTouchEventsBlockScrollAt, bool(const gfx::Point& point));
123 void SetRootLayerScrollOffsetDelegate(
124 cc::LayerScrollOffsetDelegate* root_layer_scroll_offset_delegate)
125 override {}
127 void OnRootLayerDelegatedScrollOffsetChanged() override {}
129 DISALLOW_COPY_AND_ASSIGN(MockInputHandler);
132 // A simple WebGestureCurve implementation that flings at a constant velocity
133 // indefinitely.
134 class FakeWebGestureCurve : public blink::WebGestureCurve {
135 public:
136 FakeWebGestureCurve(const blink::WebFloatSize& velocity,
137 const blink::WebFloatSize& cumulative_scroll)
138 : velocity_(velocity), cumulative_scroll_(cumulative_scroll) {}
140 virtual ~FakeWebGestureCurve() {}
142 // Returns false if curve has finished and can no longer be applied.
143 virtual bool apply(double time, blink::WebGestureCurveTarget* target) {
144 blink::WebFloatSize displacement(velocity_.width * time,
145 velocity_.height * time);
146 blink::WebFloatSize increment(
147 displacement.width - cumulative_scroll_.width,
148 displacement.height - cumulative_scroll_.height);
149 cumulative_scroll_ = displacement;
150 // scrollBy() could delete this curve if the animation is over, so don't
151 // touch any member variables after making that call.
152 return target->scrollBy(increment, velocity_);
155 private:
156 blink::WebFloatSize velocity_;
157 blink::WebFloatSize cumulative_scroll_;
159 DISALLOW_COPY_AND_ASSIGN(FakeWebGestureCurve);
162 class MockInputHandlerProxyClient
163 : public content::InputHandlerProxyClient {
164 public:
165 MockInputHandlerProxyClient() {}
166 ~MockInputHandlerProxyClient() override {}
168 void WillShutdown() override {}
170 MOCK_METHOD1(TransferActiveWheelFlingAnimation,
171 void(const WebActiveWheelFlingParameters&));
173 blink::WebGestureCurve* CreateFlingAnimationCurve(
174 WebGestureDevice deviceSource,
175 const WebFloatPoint& velocity,
176 const WebSize& cumulative_scroll) override {
177 return new FakeWebGestureCurve(
178 blink::WebFloatSize(velocity.x, velocity.y),
179 blink::WebFloatSize(cumulative_scroll.width, cumulative_scroll.height));
182 MOCK_METHOD1(DidOverscroll, void(const DidOverscrollParams&));
183 void DidStopFlinging() override {}
184 void DidAnimateForInput() override {}
186 private:
187 DISALLOW_COPY_AND_ASSIGN(MockInputHandlerProxyClient);
190 class MockInputHandlerProxyClientWithDidAnimateForInput
191 : public MockInputHandlerProxyClient {
192 public:
193 MockInputHandlerProxyClientWithDidAnimateForInput() {}
194 ~MockInputHandlerProxyClientWithDidAnimateForInput() override {}
196 MOCK_METHOD0(DidAnimateForInput, void());
198 private:
199 DISALLOW_COPY_AND_ASSIGN(MockInputHandlerProxyClientWithDidAnimateForInput);
202 WebTouchPoint CreateWebTouchPoint(WebTouchPoint::State state, float x,
203 float y) {
204 WebTouchPoint point;
205 point.state = state;
206 point.screenPosition = WebFloatPoint(x, y);
207 point.position = WebFloatPoint(x, y);
208 return point;
211 class InputHandlerProxyTest : public testing::Test {
212 public:
213 InputHandlerProxyTest()
214 : expected_disposition_(InputHandlerProxy::DID_HANDLE) {
215 input_handler_.reset(
216 new content::InputHandlerProxy(&mock_input_handler_, &mock_client_));
217 scroll_result_did_scroll_.did_scroll = true;
218 scroll_result_did_not_scroll_.did_scroll = false;
221 ~InputHandlerProxyTest() {
222 input_handler_.reset();
225 // This is defined as a macro because when an expectation is not satisfied the
226 // only output you get
227 // out of gmock is the line number that set the expectation.
228 #define VERIFY_AND_RESET_MOCKS() \
229 do { \
230 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); \
231 testing::Mock::VerifyAndClearExpectations(&mock_client_); \
232 } while (false)
234 void StartFling(base::TimeTicks timestamp,
235 WebGestureDevice source_device,
236 WebFloatPoint velocity,
237 WebPoint position) {
238 expected_disposition_ = InputHandlerProxy::DID_HANDLE;
239 VERIFY_AND_RESET_MOCKS();
241 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
242 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
243 gesture_.type = WebInputEvent::GestureScrollBegin;
244 gesture_.sourceDevice = source_device;
245 EXPECT_EQ(expected_disposition_,
246 input_handler_->HandleInputEvent(gesture_));
248 VERIFY_AND_RESET_MOCKS();
250 EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
251 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
252 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
254 gesture_ =
255 CreateFling(timestamp, source_device, velocity, position, position, 0);
256 EXPECT_EQ(expected_disposition_,
257 input_handler_->HandleInputEvent(gesture_));
259 VERIFY_AND_RESET_MOCKS();
262 void CancelFling(base::TimeTicks timestamp) {
263 gesture_.timeStampSeconds = InSecondsF(timestamp);
264 gesture_.type = WebInputEvent::GestureFlingCancel;
265 EXPECT_EQ(expected_disposition_,
266 input_handler_->HandleInputEvent(gesture_));
268 VERIFY_AND_RESET_MOCKS();
271 protected:
272 testing::StrictMock<MockInputHandler> mock_input_handler_;
273 scoped_ptr<content::InputHandlerProxy> input_handler_;
274 testing::StrictMock<MockInputHandlerProxyClient> mock_client_;
275 WebGestureEvent gesture_;
276 InputHandlerProxy::EventDisposition expected_disposition_;
277 cc::InputHandlerScrollResult scroll_result_did_scroll_;
278 cc::InputHandlerScrollResult scroll_result_did_not_scroll_;
281 TEST_F(InputHandlerProxyTest, MouseWheelByPageMainThread) {
282 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
283 WebMouseWheelEvent wheel;
284 wheel.type = WebInputEvent::MouseWheel;
285 wheel.scrollByPage = true;
287 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(wheel));
288 testing::Mock::VerifyAndClearExpectations(&mock_client_);
291 TEST_F(InputHandlerProxyTest, MouseWheelWithCtrlNotScroll) {
292 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
293 WebMouseWheelEvent wheel;
294 wheel.type = WebInputEvent::MouseWheel;
295 wheel.modifiers = WebInputEvent::ControlKey;
296 wheel.canScroll = false;
297 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(wheel));
298 testing::Mock::VerifyAndClearExpectations(&mock_client_);
301 TEST_F(InputHandlerProxyTest, GestureScrollStarted) {
302 // We shouldn't send any events to the widget for this gesture.
303 expected_disposition_ = InputHandlerProxy::DID_HANDLE;
304 VERIFY_AND_RESET_MOCKS();
306 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
307 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
309 gesture_.type = WebInputEvent::GestureScrollBegin;
310 EXPECT_EQ(expected_disposition_,input_handler_->HandleInputEvent(gesture_));
312 // The event should not be marked as handled if scrolling is not possible.
313 expected_disposition_ = InputHandlerProxy::DROP_EVENT;
314 VERIFY_AND_RESET_MOCKS();
316 gesture_.type = WebInputEvent::GestureScrollUpdate;
317 gesture_.data.scrollUpdate.deltaY =
318 -40; // -Y means scroll down - i.e. in the +Y direction.
319 EXPECT_CALL(mock_input_handler_,
320 ScrollBy(testing::_,
321 testing::Property(&gfx::Vector2dF::y, testing::Gt(0))))
322 .WillOnce(testing::Return(scroll_result_did_not_scroll_));
323 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
325 // Mark the event as handled if scroll happens.
326 expected_disposition_ = InputHandlerProxy::DID_HANDLE;
327 VERIFY_AND_RESET_MOCKS();
329 gesture_.type = WebInputEvent::GestureScrollUpdate;
330 gesture_.data.scrollUpdate.deltaY =
331 -40; // -Y means scroll down - i.e. in the +Y direction.
332 EXPECT_CALL(mock_input_handler_,
333 ScrollBy(testing::_,
334 testing::Property(&gfx::Vector2dF::y, testing::Gt(0))))
335 .WillOnce(testing::Return(scroll_result_did_scroll_));
336 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
338 VERIFY_AND_RESET_MOCKS();
340 gesture_.type = WebInputEvent::GestureScrollEnd;
341 gesture_.data.scrollUpdate.deltaY = 0;
342 EXPECT_CALL(mock_input_handler_, ScrollEnd());
343 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
346 TEST_F(InputHandlerProxyTest, GestureScrollOnMainThread) {
347 // We should send all events to the widget for this gesture.
348 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
349 VERIFY_AND_RESET_MOCKS();
351 EXPECT_CALL(mock_input_handler_, ScrollBegin(::testing::_, ::testing::_))
352 .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD));
354 gesture_.type = WebInputEvent::GestureScrollBegin;
355 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
357 VERIFY_AND_RESET_MOCKS();
359 gesture_.type = WebInputEvent::GestureScrollUpdate;
360 gesture_.data.scrollUpdate.deltaY = 40;
361 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
363 VERIFY_AND_RESET_MOCKS();
365 gesture_.type = WebInputEvent::GestureScrollEnd;
366 gesture_.data.scrollUpdate.deltaY = 0;
367 EXPECT_CALL(mock_input_handler_, ScrollEnd()).WillOnce(testing::Return());
368 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
371 TEST_F(InputHandlerProxyTest, GestureScrollIgnored) {
372 // We shouldn't handle the GestureScrollBegin.
373 // Instead, we should get a DROP_EVENT result, indicating
374 // that we could determine that there's nothing that could scroll or otherwise
375 // react to this gesture sequence and thus we should drop the whole gesture
376 // sequence on the floor, except for the ScrollEnd.
377 expected_disposition_ = InputHandlerProxy::DROP_EVENT;
378 VERIFY_AND_RESET_MOCKS();
380 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
381 .WillOnce(testing::Return(cc::InputHandler::SCROLL_IGNORED));
383 gesture_.type = WebInputEvent::GestureScrollBegin;
384 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
386 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
387 gesture_.type = WebInputEvent::GestureScrollEnd;
388 EXPECT_CALL(mock_input_handler_, ScrollEnd()).WillOnce(testing::Return());
389 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
392 TEST_F(InputHandlerProxyTest, GesturePinch) {
393 // We shouldn't send any events to the widget for this gesture.
394 expected_disposition_ = InputHandlerProxy::DID_HANDLE;
395 VERIFY_AND_RESET_MOCKS();
397 gesture_.type = WebInputEvent::GesturePinchBegin;
398 EXPECT_CALL(mock_input_handler_, HaveWheelEventHandlersAt(testing::_))
399 .WillOnce(testing::Return(false));
400 EXPECT_CALL(mock_input_handler_, PinchGestureBegin());
401 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
403 VERIFY_AND_RESET_MOCKS();
405 gesture_.type = WebInputEvent::GesturePinchUpdate;
406 gesture_.data.pinchUpdate.scale = 1.5;
407 gesture_.x = 7;
408 gesture_.y = 13;
409 EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(1.5, gfx::Point(7, 13)));
410 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
412 VERIFY_AND_RESET_MOCKS();
414 gesture_.type = WebInputEvent::GesturePinchUpdate;
415 gesture_.data.pinchUpdate.scale = 0.5;
416 gesture_.data.pinchUpdate.zoomDisabled = true;
417 gesture_.x = 9;
418 gesture_.y = 6;
419 EXPECT_EQ(InputHandlerProxy::DROP_EVENT,
420 input_handler_->HandleInputEvent(gesture_));
421 gesture_.data.pinchUpdate.zoomDisabled = false;
423 VERIFY_AND_RESET_MOCKS();
425 gesture_.type = WebInputEvent::GesturePinchUpdate;
426 gesture_.data.pinchUpdate.scale = 0.5;
427 gesture_.x = 9;
428 gesture_.y = 6;
429 EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(.5, gfx::Point(9, 6)));
430 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
432 VERIFY_AND_RESET_MOCKS();
434 gesture_.type = WebInputEvent::GesturePinchEnd;
435 EXPECT_CALL(mock_input_handler_, PinchGestureEnd());
436 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
439 TEST_F(InputHandlerProxyTest, GesturePinchWithWheelHandler) {
440 // We will send the synthetic wheel event to the widget.
441 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
442 VERIFY_AND_RESET_MOCKS();
444 gesture_.type = WebInputEvent::GesturePinchBegin;
445 EXPECT_CALL(mock_input_handler_, HaveWheelEventHandlersAt(testing::_))
446 .WillOnce(testing::Return(true));
447 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
449 VERIFY_AND_RESET_MOCKS();
451 gesture_.type = WebInputEvent::GesturePinchUpdate;
452 gesture_.data.pinchUpdate.scale = 1.5;
453 gesture_.x = 7;
454 gesture_.y = 13;
455 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
457 VERIFY_AND_RESET_MOCKS();
459 gesture_.type = WebInputEvent::GesturePinchUpdate;
460 gesture_.data.pinchUpdate.scale = 0.5;
461 gesture_.x = 9;
462 gesture_.y = 6;
463 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
465 VERIFY_AND_RESET_MOCKS();
467 gesture_.type = WebInputEvent::GesturePinchEnd;
468 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
471 TEST_F(InputHandlerProxyTest, GesturePinchAfterScrollOnMainThread) {
472 // Scrolls will start by being sent to the main thread.
473 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
474 VERIFY_AND_RESET_MOCKS();
476 EXPECT_CALL(mock_input_handler_, ScrollBegin(::testing::_, ::testing::_))
477 .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD));
479 gesture_.type = WebInputEvent::GestureScrollBegin;
480 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
482 VERIFY_AND_RESET_MOCKS();
484 gesture_.type = WebInputEvent::GestureScrollUpdate;
485 gesture_.data.scrollUpdate.deltaY = 40;
486 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
488 // However, after the pinch gesture starts, they should go to the impl
489 // thread.
490 expected_disposition_ = InputHandlerProxy::DID_HANDLE;
491 VERIFY_AND_RESET_MOCKS();
493 gesture_.type = WebInputEvent::GesturePinchBegin;
494 EXPECT_CALL(mock_input_handler_, HaveWheelEventHandlersAt(testing::_))
495 .WillOnce(testing::Return(false));
496 EXPECT_CALL(mock_input_handler_, PinchGestureBegin());
497 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
499 VERIFY_AND_RESET_MOCKS();
501 gesture_.type = WebInputEvent::GesturePinchUpdate;
502 gesture_.data.pinchUpdate.scale = 1.5;
503 gesture_.x = 7;
504 gesture_.y = 13;
505 EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(1.5, gfx::Point(7, 13)));
506 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
508 VERIFY_AND_RESET_MOCKS();
510 gesture_.type = WebInputEvent::GestureScrollUpdate;
511 gesture_.data.scrollUpdate.deltaY =
512 -40; // -Y means scroll down - i.e. in the +Y direction.
513 EXPECT_CALL(mock_input_handler_,
514 ScrollBy(testing::_,
515 testing::Property(&gfx::Vector2dF::y, testing::Gt(0))))
516 .WillOnce(testing::Return(scroll_result_did_scroll_));
517 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
519 VERIFY_AND_RESET_MOCKS();
521 gesture_.type = WebInputEvent::GesturePinchUpdate;
522 gesture_.data.pinchUpdate.scale = 0.5;
523 gesture_.x = 9;
524 gesture_.y = 6;
525 EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(.5, gfx::Point(9, 6)));
526 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
528 VERIFY_AND_RESET_MOCKS();
530 gesture_.type = WebInputEvent::GesturePinchEnd;
531 EXPECT_CALL(mock_input_handler_, PinchGestureEnd());
532 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
534 // After the pinch gesture ends, they should go to back to the main
535 // thread.
536 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
537 VERIFY_AND_RESET_MOCKS();
539 gesture_.type = WebInputEvent::GestureScrollEnd;
540 gesture_.data.scrollUpdate.deltaY = 0;
541 EXPECT_CALL(mock_input_handler_, ScrollEnd())
542 .WillOnce(testing::Return());
543 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
546 TEST_F(InputHandlerProxyTest, GestureFlingStartedTouchpad) {
547 // We shouldn't send any events to the widget for this gesture.
548 expected_disposition_ = InputHandlerProxy::DID_HANDLE;
549 VERIFY_AND_RESET_MOCKS();
551 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
552 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
553 EXPECT_CALL(mock_input_handler_, ScrollEnd());
554 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
556 gesture_.type = WebInputEvent::GestureFlingStart;
557 gesture_.data.flingStart.velocityX = 10;
558 gesture_.sourceDevice = blink::WebGestureDeviceTouchpad;
559 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
561 VERIFY_AND_RESET_MOCKS();
563 // Verify that a GestureFlingCancel during an animation cancels it.
564 gesture_.type = WebInputEvent::GestureFlingCancel;
565 gesture_.sourceDevice = blink::WebGestureDeviceTouchpad;
566 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
569 TEST_F(InputHandlerProxyTest, GestureFlingOnMainThreadTouchpad) {
570 // We should send all events to the widget for this gesture.
571 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
572 VERIFY_AND_RESET_MOCKS();
574 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
575 .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD));
577 gesture_.type = WebInputEvent::GestureFlingStart;
578 gesture_.sourceDevice = blink::WebGestureDeviceTouchpad;
579 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
581 // Since we returned ScrollStatusOnMainThread from scrollBegin, ensure the
582 // input handler knows it's scrolling off the impl thread
583 ASSERT_FALSE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
585 VERIFY_AND_RESET_MOCKS();
587 // Even if we didn't start a fling ourselves, we still need to send the cancel
588 // event to the widget.
589 gesture_.type = WebInputEvent::GestureFlingCancel;
590 gesture_.sourceDevice = blink::WebGestureDeviceTouchpad;
591 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
594 TEST_F(InputHandlerProxyTest, GestureFlingIgnoredTouchpad) {
595 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
596 VERIFY_AND_RESET_MOCKS();
598 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
599 .WillOnce(testing::Return(cc::InputHandler::SCROLL_IGNORED));
601 gesture_.type = WebInputEvent::GestureFlingStart;
602 gesture_.sourceDevice = blink::WebGestureDeviceTouchpad;
603 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
605 expected_disposition_ = InputHandlerProxy::DROP_EVENT;
606 VERIFY_AND_RESET_MOCKS();
608 // Since the previous fling was ignored, we should also be dropping the next
609 // fling_cancel.
610 gesture_.type = WebInputEvent::GestureFlingCancel;
611 gesture_.sourceDevice = blink::WebGestureDeviceTouchpad;
612 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
615 TEST_F(InputHandlerProxyTest, GestureFlingAnimatesTouchpad) {
616 // We shouldn't send any events to the widget for this gesture.
617 expected_disposition_ = InputHandlerProxy::DID_HANDLE;
618 VERIFY_AND_RESET_MOCKS();
620 // On the fling start, we should schedule an animation but not actually start
621 // scrolling.
622 gesture_.type = WebInputEvent::GestureFlingStart;
623 WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
624 WebPoint fling_point = WebPoint(7, 13);
625 WebPoint fling_global_point = WebPoint(17, 23);
626 // Note that for trackpad, wheel events with the Control modifier are
627 // special (reserved for zoom), so don't set that here.
628 int modifiers = WebInputEvent::ShiftKey | WebInputEvent::AltKey;
629 gesture_ = CreateFling(blink::WebGestureDeviceTouchpad,
630 fling_delta,
631 fling_point,
632 fling_global_point,
633 modifiers);
634 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
635 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
636 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
637 EXPECT_CALL(mock_input_handler_, ScrollEnd());
638 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
640 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
641 // The first animate call should let us pick up an animation start time, but
642 // we shouldn't actually move anywhere just yet. The first frame after the
643 // fling start will typically include the last scroll from the gesture that
644 // lead to the scroll (either wheel or gesture scroll), so there should be no
645 // visible hitch.
646 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
647 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
648 .Times(0);
649 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
650 input_handler_->Animate(time);
652 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
654 // The second call should start scrolling in the -X direction.
655 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
656 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
657 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
658 EXPECT_CALL(mock_input_handler_,
659 ScrollBy(testing::_,
660 testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))
661 .WillOnce(testing::Return(scroll_result_did_scroll_));
662 EXPECT_CALL(mock_input_handler_, ScrollEnd());
663 time += base::TimeDelta::FromMilliseconds(100);
664 input_handler_->Animate(time);
666 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
668 // Let's say on the third call we hit a non-scrollable region. We should abort
669 // the fling and not scroll.
670 // We also should pass the current fling parameters out to the client so the
671 // rest of the fling can be
672 // transferred to the main thread.
673 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
674 .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD));
675 EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_, testing::_)).Times(0);
676 EXPECT_CALL(mock_input_handler_, ScrollEnd()).Times(0);
677 // Expected wheel fling animation parameters:
678 // *) fling_delta and fling_point should match the original GestureFlingStart
679 // event
680 // *) startTime should be 10 to match the time parameter of the first
681 // Animate() call after the GestureFlingStart
682 // *) cumulativeScroll depends on the curve, but since we've animated in the
683 // -X direction the X value should be < 0
684 EXPECT_CALL(
685 mock_client_,
686 TransferActiveWheelFlingAnimation(testing::AllOf(
687 testing::Field(&WebActiveWheelFlingParameters::delta,
688 testing::Eq(fling_delta)),
689 testing::Field(&WebActiveWheelFlingParameters::point,
690 testing::Eq(fling_point)),
691 testing::Field(&WebActiveWheelFlingParameters::globalPoint,
692 testing::Eq(fling_global_point)),
693 testing::Field(&WebActiveWheelFlingParameters::modifiers,
694 testing::Eq(modifiers)),
695 testing::Field(&WebActiveWheelFlingParameters::startTime,
696 testing::Eq(10)),
697 testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll,
698 testing::Field(&WebSize::width, testing::Gt(0))))));
699 time += base::TimeDelta::FromMilliseconds(100);
700 input_handler_->Animate(time);
702 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
703 testing::Mock::VerifyAndClearExpectations(&mock_client_);
705 // Since we've aborted the fling, the next animation should be a no-op and
706 // should not result in another
707 // frame being requested.
708 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()).Times(0);
709 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
710 .Times(0);
711 time += base::TimeDelta::FromMilliseconds(100);
712 input_handler_->Animate(time);
714 // Since we've transferred the fling to the main thread, we need to pass the
715 // next GestureFlingCancel to the main
716 // thread as well.
717 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
718 gesture_.type = WebInputEvent::GestureFlingCancel;
719 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
722 TEST_F(InputHandlerProxyTest, GestureFlingTransferResetsTouchpad) {
723 // We shouldn't send any events to the widget for this gesture.
724 expected_disposition_ = InputHandlerProxy::DID_HANDLE;
725 VERIFY_AND_RESET_MOCKS();
727 // Start a gesture fling in the -X direction with zero Y movement.
728 WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
729 WebPoint fling_point = WebPoint(7, 13);
730 WebPoint fling_global_point = WebPoint(17, 23);
731 // Note that for trackpad, wheel events with the Control modifier are
732 // special (reserved for zoom), so don't set that here.
733 int modifiers = WebInputEvent::ShiftKey | WebInputEvent::AltKey;
734 gesture_ = CreateFling(blink::WebGestureDeviceTouchpad,
735 fling_delta,
736 fling_point,
737 fling_global_point,
738 modifiers);
739 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
740 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
741 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
742 EXPECT_CALL(mock_input_handler_, ScrollEnd());
743 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
745 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
747 // Start the fling animation at time 10. This shouldn't actually scroll, just
748 // establish a start time.
749 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
750 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
751 .Times(0);
752 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
753 input_handler_->Animate(time);
755 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
757 // The second call should start scrolling in the -X direction.
758 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
759 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
760 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
761 EXPECT_CALL(mock_input_handler_,
762 ScrollBy(testing::_,
763 testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))
764 .WillOnce(testing::Return(scroll_result_did_scroll_));
765 EXPECT_CALL(mock_input_handler_, ScrollEnd());
766 time += base::TimeDelta::FromMilliseconds(100);
767 input_handler_->Animate(time);
769 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
771 // Let's say on the third call we hit a non-scrollable region. We should abort
772 // the fling and not scroll.
773 // We also should pass the current fling parameters out to the client so the
774 // rest of the fling can be
775 // transferred to the main thread.
776 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
777 .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD));
778 EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_, testing::_)).Times(0);
779 EXPECT_CALL(mock_input_handler_, ScrollEnd()).Times(0);
781 // Expected wheel fling animation parameters:
782 // *) fling_delta and fling_point should match the original GestureFlingStart
783 // event
784 // *) startTime should be 10 to match the time parameter of the first
785 // Animate() call after the GestureFlingStart
786 // *) cumulativeScroll depends on the curve, but since we've animated in the
787 // -X direction the X value should be < 0
788 EXPECT_CALL(
789 mock_client_,
790 TransferActiveWheelFlingAnimation(testing::AllOf(
791 testing::Field(&WebActiveWheelFlingParameters::delta,
792 testing::Eq(fling_delta)),
793 testing::Field(&WebActiveWheelFlingParameters::point,
794 testing::Eq(fling_point)),
795 testing::Field(&WebActiveWheelFlingParameters::globalPoint,
796 testing::Eq(fling_global_point)),
797 testing::Field(&WebActiveWheelFlingParameters::modifiers,
798 testing::Eq(modifiers)),
799 testing::Field(&WebActiveWheelFlingParameters::startTime,
800 testing::Eq(10)),
801 testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll,
802 testing::Field(&WebSize::width, testing::Gt(0))))));
803 time += base::TimeDelta::FromMilliseconds(100);
804 input_handler_->Animate(time);
806 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
807 testing::Mock::VerifyAndClearExpectations(&mock_client_);
809 // Since we've aborted the fling, the next animation should be a no-op and
810 // should not result in another
811 // frame being requested.
812 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()).Times(0);
813 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
814 .Times(0);
815 time += base::TimeDelta::FromMilliseconds(100);
816 input_handler_->Animate(time);
818 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
820 // Since we've transferred the fling to the main thread, we need to pass the
821 // next GestureFlingCancel to the main
822 // thread as well.
823 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
824 gesture_.type = WebInputEvent::GestureFlingCancel;
825 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
827 VERIFY_AND_RESET_MOCKS();
828 input_handler_->MainThreadHasStoppedFlinging();
830 // Start a second gesture fling, this time in the +Y direction with no X.
831 fling_delta = WebFloatPoint(0, -1000);
832 fling_point = WebPoint(95, 87);
833 fling_global_point = WebPoint(32, 71);
834 modifiers = WebInputEvent::AltKey;
835 gesture_ = CreateFling(blink::WebGestureDeviceTouchpad,
836 fling_delta,
837 fling_point,
838 fling_global_point,
839 modifiers);
840 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
841 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
842 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
843 EXPECT_CALL(mock_input_handler_, ScrollEnd());
844 expected_disposition_ = InputHandlerProxy::DID_HANDLE;
845 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
847 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
849 // Start the second fling animation at time 30.
850 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
851 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
852 .Times(0);
853 time = base::TimeTicks() + base::TimeDelta::FromSeconds(30);
854 input_handler_->Animate(time);
856 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
858 // Tick the second fling once normally.
859 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
860 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
861 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
862 EXPECT_CALL(mock_input_handler_,
863 ScrollBy(testing::_,
864 testing::Property(&gfx::Vector2dF::y, testing::Gt(0))))
865 .WillOnce(testing::Return(scroll_result_did_scroll_));
866 EXPECT_CALL(mock_input_handler_, ScrollEnd());
867 time += base::TimeDelta::FromMilliseconds(100);
868 input_handler_->Animate(time);
870 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
872 // Then abort the second fling.
873 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
874 .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD));
875 EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_, testing::_)).Times(0);
876 EXPECT_CALL(mock_input_handler_, ScrollEnd()).Times(0);
878 // We should get parameters from the second fling, nothing from the first
879 // fling should "leak".
880 EXPECT_CALL(
881 mock_client_,
882 TransferActiveWheelFlingAnimation(testing::AllOf(
883 testing::Field(&WebActiveWheelFlingParameters::delta,
884 testing::Eq(fling_delta)),
885 testing::Field(&WebActiveWheelFlingParameters::point,
886 testing::Eq(fling_point)),
887 testing::Field(&WebActiveWheelFlingParameters::globalPoint,
888 testing::Eq(fling_global_point)),
889 testing::Field(&WebActiveWheelFlingParameters::modifiers,
890 testing::Eq(modifiers)),
891 testing::Field(&WebActiveWheelFlingParameters::startTime,
892 testing::Eq(30)),
893 testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll,
894 testing::Field(&WebSize::height, testing::Lt(0))))));
895 time += base::TimeDelta::FromMilliseconds(100);
896 input_handler_->Animate(time);
899 TEST_F(InputHandlerProxyTest, GestureFlingStartedTouchscreen) {
900 // We shouldn't send any events to the widget for this gesture.
901 expected_disposition_ = InputHandlerProxy::DID_HANDLE;
902 VERIFY_AND_RESET_MOCKS();
904 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
905 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
906 gesture_.type = WebInputEvent::GestureScrollBegin;
907 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen;
908 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
910 VERIFY_AND_RESET_MOCKS();
912 EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
913 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
914 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
916 gesture_.type = WebInputEvent::GestureFlingStart;
917 gesture_.data.flingStart.velocityX = 10;
918 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen;
919 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
921 VERIFY_AND_RESET_MOCKS();
923 EXPECT_CALL(mock_input_handler_, ScrollEnd());
925 // Verify that a GestureFlingCancel during an animation cancels it.
926 gesture_.type = WebInputEvent::GestureFlingCancel;
927 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen;
928 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
931 TEST_F(InputHandlerProxyTest, GestureFlingOnMainThreadTouchscreen) {
932 // We should send all events to the widget for this gesture.
933 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
934 VERIFY_AND_RESET_MOCKS();
936 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
937 .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD));
939 gesture_.type = WebInputEvent::GestureScrollBegin;
940 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
942 VERIFY_AND_RESET_MOCKS();
944 EXPECT_CALL(mock_input_handler_, FlingScrollBegin()).Times(0);
946 gesture_.type = WebInputEvent::GestureFlingStart;
947 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen;
948 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
950 VERIFY_AND_RESET_MOCKS();
952 // Even if we didn't start a fling ourselves, we still need to send the cancel
953 // event to the widget.
954 gesture_.type = WebInputEvent::GestureFlingCancel;
955 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen;
956 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
959 TEST_F(InputHandlerProxyTest, GestureFlingIgnoredTouchscreen) {
960 expected_disposition_ = InputHandlerProxy::DID_HANDLE;
961 VERIFY_AND_RESET_MOCKS();
963 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
964 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
966 gesture_.type = WebInputEvent::GestureScrollBegin;
967 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen;
968 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
970 expected_disposition_ = InputHandlerProxy::DROP_EVENT;
971 VERIFY_AND_RESET_MOCKS();
973 // Flings ignored by the InputHandler should be dropped, signalling the end
974 // of the touch scroll sequence.
975 EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
976 .WillOnce(testing::Return(cc::InputHandler::SCROLL_IGNORED));
978 gesture_.type = WebInputEvent::GestureFlingStart;
979 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen;
980 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
982 VERIFY_AND_RESET_MOCKS();
984 // Subsequent scrolls should behave normally, even without an intervening
985 // GestureFlingCancel, as the original GestureFlingStart was dropped.
986 expected_disposition_ = InputHandlerProxy::DID_HANDLE;
987 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
988 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
989 gesture_.type = WebInputEvent::GestureScrollBegin;
990 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen;
991 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
994 TEST_F(InputHandlerProxyTest, GestureFlingAnimatesTouchscreen) {
995 // We shouldn't send any events to the widget for this gesture.
996 expected_disposition_ = InputHandlerProxy::DID_HANDLE;
997 VERIFY_AND_RESET_MOCKS();
999 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
1000 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
1002 gesture_.type = WebInputEvent::GestureScrollBegin;
1003 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen;
1004 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1006 VERIFY_AND_RESET_MOCKS();
1008 // On the fling start, we should schedule an animation but not actually start
1009 // scrolling.
1010 WebFloatPoint fling_delta = WebFloatPoint(100, 0);
1011 WebPoint fling_point = WebPoint(7, 13);
1012 WebPoint fling_global_point = WebPoint(17, 23);
1013 // Note that for touchscreen the control modifier is not special.
1014 int modifiers = WebInputEvent::ControlKey;
1015 gesture_ = CreateFling(blink::WebGestureDeviceTouchscreen,
1016 fling_delta,
1017 fling_point,
1018 fling_global_point,
1019 modifiers);
1020 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1021 EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
1022 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
1023 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1025 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1026 // The first animate call should let us pick up an animation start time, but
1027 // we shouldn't actually move anywhere just yet. The first frame after the
1028 // fling start will typically include the last scroll from the gesture that
1029 // lead to the scroll (either wheel or gesture scroll), so there should be no
1030 // visible hitch.
1031 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1032 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
1033 input_handler_->Animate(time);
1035 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1037 // The second call should start scrolling in the -X direction.
1038 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1039 EXPECT_CALL(mock_input_handler_,
1040 ScrollBy(testing::_,
1041 testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))
1042 .WillOnce(testing::Return(scroll_result_did_scroll_));
1043 time += base::TimeDelta::FromMilliseconds(100);
1044 input_handler_->Animate(time);
1046 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1048 EXPECT_CALL(mock_input_handler_, ScrollEnd());
1049 gesture_.type = WebInputEvent::GestureFlingCancel;
1050 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1053 TEST_F(InputHandlerProxyTest, GestureFlingWithValidTimestamp) {
1054 // We shouldn't send any events to the widget for this gesture.
1055 expected_disposition_ = InputHandlerProxy::DID_HANDLE;
1056 VERIFY_AND_RESET_MOCKS();
1058 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
1059 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
1061 gesture_.type = WebInputEvent::GestureScrollBegin;
1062 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen;
1063 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1065 VERIFY_AND_RESET_MOCKS();
1067 // On the fling start, we should schedule an animation but not actually start
1068 // scrolling.
1069 base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10);
1070 base::TimeTicks time = base::TimeTicks() + dt;
1071 WebFloatPoint fling_delta = WebFloatPoint(100, 0);
1072 WebPoint fling_point = WebPoint(7, 13);
1073 WebPoint fling_global_point = WebPoint(17, 23);
1074 int modifiers = WebInputEvent::ControlKey;
1075 gesture_ = CreateFling(time,
1076 blink::WebGestureDeviceTouchscreen,
1077 fling_delta,
1078 fling_point,
1079 fling_global_point,
1080 modifiers);
1081 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1082 EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
1083 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
1084 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1086 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1087 // With a valid time stamp, the first animate call should skip start time
1088 // initialization and immediately begin scroll update production. This reduces
1089 // the likelihood of a hitch between the scroll preceding the fling and
1090 // the first scroll generated by the fling.
1091 // Scrolling should start in the -X direction.
1092 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1093 EXPECT_CALL(mock_input_handler_,
1094 ScrollBy(testing::_,
1095 testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))
1096 .WillOnce(testing::Return(scroll_result_did_scroll_));
1097 time += dt;
1098 input_handler_->Animate(time);
1100 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1102 EXPECT_CALL(mock_input_handler_, ScrollEnd());
1103 gesture_.type = WebInputEvent::GestureFlingCancel;
1104 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1107 TEST_F(InputHandlerProxyTest, GestureFlingWithInvalidTimestamp) {
1108 // We shouldn't send any events to the widget for this gesture.
1109 expected_disposition_ = InputHandlerProxy::DID_HANDLE;
1110 VERIFY_AND_RESET_MOCKS();
1112 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
1113 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
1115 gesture_.type = WebInputEvent::GestureScrollBegin;
1116 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen;
1117 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1119 VERIFY_AND_RESET_MOCKS();
1121 // On the fling start, we should schedule an animation but not actually start
1122 // scrolling.
1123 base::TimeDelta start_time_offset = base::TimeDelta::FromMilliseconds(10);
1124 gesture_.type = WebInputEvent::GestureFlingStart;
1125 WebFloatPoint fling_delta = WebFloatPoint(100, 0);
1126 WebPoint fling_point = WebPoint(7, 13);
1127 WebPoint fling_global_point = WebPoint(17, 23);
1128 int modifiers = WebInputEvent::ControlKey;
1129 gesture_.timeStampSeconds = start_time_offset.InSecondsF();
1130 gesture_.data.flingStart.velocityX = fling_delta.x;
1131 gesture_.data.flingStart.velocityY = fling_delta.y;
1132 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen;
1133 gesture_.x = fling_point.x;
1134 gesture_.y = fling_point.y;
1135 gesture_.globalX = fling_global_point.x;
1136 gesture_.globalY = fling_global_point.y;
1137 gesture_.modifiers = modifiers;
1138 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1139 EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
1140 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
1141 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1143 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1144 // Event though a time stamp was provided for the fling event, it will be
1145 // ignored as its too far in the past relative to the first animate call's
1146 // timestamp.
1147 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1148 base::TimeTicks time =
1149 base::TimeTicks() + start_time_offset + base::TimeDelta::FromSeconds(1);
1150 input_handler_->Animate(time);
1152 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1154 // Further animation ticks should update the fling as usual.
1155 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1156 EXPECT_CALL(mock_input_handler_,
1157 ScrollBy(testing::_,
1158 testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))
1159 .WillOnce(testing::Return(scroll_result_did_scroll_));
1160 time += base::TimeDelta::FromMilliseconds(10);
1161 input_handler_->Animate(time);
1163 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1165 EXPECT_CALL(mock_input_handler_, ScrollEnd());
1166 gesture_.type = WebInputEvent::GestureFlingCancel;
1167 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1170 TEST_F(InputHandlerProxyTest,
1171 GestureScrollOnImplThreadFlagClearedAfterFling) {
1172 // We shouldn't send any events to the widget for this gesture.
1173 expected_disposition_ = InputHandlerProxy::DID_HANDLE;
1174 VERIFY_AND_RESET_MOCKS();
1176 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
1177 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
1179 gesture_.type = WebInputEvent::GestureScrollBegin;
1180 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1182 // After sending a GestureScrollBegin, the member variable
1183 // |gesture_scroll_on_impl_thread_| should be true.
1184 EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
1186 expected_disposition_ = InputHandlerProxy::DID_HANDLE;
1187 VERIFY_AND_RESET_MOCKS();
1189 // On the fling start, we should schedule an animation but not actually start
1190 // scrolling.
1191 WebFloatPoint fling_delta = WebFloatPoint(100, 0);
1192 WebPoint fling_point = WebPoint(7, 13);
1193 WebPoint fling_global_point = WebPoint(17, 23);
1194 int modifiers = WebInputEvent::ControlKey | WebInputEvent::AltKey;
1195 gesture_ = CreateFling(blink::WebGestureDeviceTouchscreen,
1196 fling_delta,
1197 fling_point,
1198 fling_global_point,
1199 modifiers);
1200 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1201 EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
1202 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
1203 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1205 // |gesture_scroll_on_impl_thread_| should still be true after
1206 // a GestureFlingStart is sent.
1207 EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
1209 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1210 // The first animate call should let us pick up an animation start time, but
1211 // we shouldn't actually move anywhere just yet. The first frame after the
1212 // fling start will typically include the last scroll from the gesture that
1213 // lead to the scroll (either wheel or gesture scroll), so there should be no
1214 // visible hitch.
1215 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1216 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
1217 input_handler_->Animate(time);
1219 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1221 // The second call should start scrolling in the -X direction.
1222 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1223 EXPECT_CALL(mock_input_handler_,
1224 ScrollBy(testing::_,
1225 testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))
1226 .WillOnce(testing::Return(scroll_result_did_scroll_));
1227 time += base::TimeDelta::FromMilliseconds(100);
1228 input_handler_->Animate(time);
1230 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1232 EXPECT_CALL(mock_input_handler_, ScrollEnd());
1233 gesture_.type = WebInputEvent::GestureFlingCancel;
1234 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1236 // |gesture_scroll_on_impl_thread_| should be false once
1237 // the fling has finished (note no GestureScrollEnd has been sent).
1238 EXPECT_TRUE(!input_handler_->gesture_scroll_on_impl_thread_for_testing());
1241 TEST_F(InputHandlerProxyTest, GestureFlingStopsAtContentEdge) {
1242 // We shouldn't send any events to the widget for this gesture.
1243 expected_disposition_ = InputHandlerProxy::DID_HANDLE;
1244 VERIFY_AND_RESET_MOCKS();
1246 // On the fling start, we should schedule an animation but not actually start
1247 // scrolling.
1248 gesture_.type = WebInputEvent::GestureFlingStart;
1249 WebFloatPoint fling_delta = WebFloatPoint(100, 100);
1250 gesture_.data.flingStart.velocityX = fling_delta.x;
1251 gesture_.data.flingStart.velocityY = fling_delta.y;
1252 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
1253 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
1254 EXPECT_CALL(mock_input_handler_, ScrollEnd());
1255 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1256 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1257 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1259 // The first animate doesn't cause any scrolling.
1260 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1261 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
1262 input_handler_->Animate(time);
1263 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1265 // The second animate starts scrolling in the positive X and Y directions.
1266 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
1267 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
1268 EXPECT_CALL(mock_input_handler_,
1269 ScrollBy(testing::_,
1270 testing::Property(&gfx::Vector2dF::y, testing::Lt(0))))
1271 .WillOnce(testing::Return(scroll_result_did_scroll_));
1272 EXPECT_CALL(mock_input_handler_, ScrollEnd());
1273 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1274 time += base::TimeDelta::FromMilliseconds(100);
1275 input_handler_->Animate(time);
1276 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1278 // The third animate overscrolls in the positive Y direction but scrolls
1279 // somewhat.
1280 cc::InputHandlerScrollResult overscroll;
1281 overscroll.did_scroll = true;
1282 overscroll.did_overscroll_root = true;
1283 overscroll.accumulated_root_overscroll = gfx::Vector2dF(0, 100);
1284 overscroll.unused_scroll_delta = gfx::Vector2dF(0, 10);
1285 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
1286 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
1287 EXPECT_CALL(mock_input_handler_,
1288 ScrollBy(testing::_,
1289 testing::Property(&gfx::Vector2dF::y, testing::Lt(0))))
1290 .WillOnce(testing::Return(overscroll));
1291 EXPECT_CALL(
1292 mock_client_,
1293 DidOverscroll(testing::AllOf(
1294 testing::Field(
1295 &DidOverscrollParams::accumulated_overscroll,
1296 testing::Eq(overscroll.accumulated_root_overscroll)),
1297 testing::Field(
1298 &DidOverscrollParams::latest_overscroll_delta,
1299 testing::Eq(overscroll.unused_scroll_delta)),
1300 testing::Field(
1301 &DidOverscrollParams::current_fling_velocity,
1302 testing::Property(&gfx::Vector2dF::y, testing::Lt(0))))));
1303 EXPECT_CALL(mock_input_handler_, ScrollEnd());
1304 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1305 time += base::TimeDelta::FromMilliseconds(100);
1306 input_handler_->Animate(time);
1307 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1309 // The next call to animate will no longer scroll vertically.
1310 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1311 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
1312 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
1313 EXPECT_CALL(mock_input_handler_,
1314 ScrollBy(testing::_,
1315 testing::Property(&gfx::Vector2dF::y, testing::Eq(0))))
1316 .WillOnce(testing::Return(scroll_result_did_scroll_));
1317 EXPECT_CALL(mock_input_handler_, ScrollEnd());
1318 time += base::TimeDelta::FromMilliseconds(100);
1319 input_handler_->Animate(time);
1320 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1323 TEST_F(InputHandlerProxyTest, GestureFlingNotCancelledBySmallTimeDelta) {
1324 // We shouldn't send any events to the widget for this gesture.
1325 expected_disposition_ = InputHandlerProxy::DID_HANDLE;
1326 VERIFY_AND_RESET_MOCKS();
1328 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
1329 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
1331 gesture_.type = WebInputEvent::GestureScrollBegin;
1332 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen;
1333 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1335 VERIFY_AND_RESET_MOCKS();
1337 // On the fling start, we should schedule an animation but not actually start
1338 // scrolling.
1339 base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10);
1340 base::TimeTicks time = base::TimeTicks() + dt;
1341 WebFloatPoint fling_delta = WebFloatPoint(100, 0);
1342 WebPoint fling_point = WebPoint(7, 13);
1343 WebPoint fling_global_point = WebPoint(17, 23);
1344 int modifiers = WebInputEvent::ControlKey;
1345 gesture_ = CreateFling(time,
1346 blink::WebGestureDeviceTouchscreen,
1347 fling_delta,
1348 fling_point,
1349 fling_global_point,
1350 modifiers);
1351 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1352 EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
1353 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
1354 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1356 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1357 // With an animation timestamp equivalent to the starting timestamp, the
1358 // animation will simply be rescheduled.
1359 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1360 input_handler_->Animate(time);
1362 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1363 EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
1365 // A small time delta should not stop the fling, even if the client
1366 // reports no scrolling.
1367 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1368 EXPECT_CALL(mock_input_handler_,
1369 ScrollBy(testing::_,
1370 testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))
1371 .WillOnce(testing::Return(scroll_result_did_not_scroll_));
1372 time += base::TimeDelta::FromMicroseconds(5);
1373 input_handler_->Animate(time);
1375 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1376 EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
1378 // A time delta of zero should not stop the fling, and neither should it
1379 // trigger scrolling on the client.
1380 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1381 input_handler_->Animate(time);
1383 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1384 EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
1386 // Lack of movement on the client, with a non-trivial scroll delta, should
1387 // terminate the fling.
1388 EXPECT_CALL(mock_input_handler_, ScrollEnd());
1389 EXPECT_CALL(mock_input_handler_,
1390 ScrollBy(testing::_,
1391 testing::Property(&gfx::Vector2dF::x, testing::Lt(1))))
1392 .WillOnce(testing::Return(scroll_result_did_not_scroll_));
1393 time += base::TimeDelta::FromMilliseconds(100);
1394 input_handler_->Animate(time);
1396 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1397 EXPECT_FALSE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
1400 TEST_F(InputHandlerProxyTest, GestureFlingCancelledAfterBothAxesStopScrolling) {
1401 cc::InputHandlerScrollResult overscroll;
1402 overscroll.did_scroll = true;
1403 overscroll.did_overscroll_root = true;
1405 // We shouldn't send any events to the widget for this gesture.
1406 expected_disposition_ = InputHandlerProxy::DID_HANDLE;
1407 VERIFY_AND_RESET_MOCKS();
1409 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
1410 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
1411 gesture_.type = WebInputEvent::GestureScrollBegin;
1412 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen;
1413 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1414 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1416 // On the fling start, we should schedule an animation but not actually start
1417 // scrolling.
1418 gesture_.type = WebInputEvent::GestureFlingStart;
1419 WebFloatPoint fling_delta = WebFloatPoint(100, 100);
1420 gesture_.data.flingStart.velocityX = fling_delta.x;
1421 gesture_.data.flingStart.velocityY = fling_delta.y;
1422 EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
1423 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
1424 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1425 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1426 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1428 // The first animate doesn't cause any scrolling.
1429 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1430 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
1431 input_handler_->Animate(time);
1432 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1434 // The second animate starts scrolling in the positive X and Y directions.
1435 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1436 EXPECT_CALL(mock_input_handler_,
1437 ScrollBy(testing::_,
1438 testing::Property(&gfx::Vector2dF::y, testing::Lt(0))))
1439 .WillOnce(testing::Return(scroll_result_did_scroll_));
1440 time += base::TimeDelta::FromMilliseconds(10);
1441 input_handler_->Animate(time);
1442 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1444 // The third animate hits the bottom content edge.
1445 overscroll.accumulated_root_overscroll = gfx::Vector2dF(0, 100);
1446 overscroll.unused_scroll_delta = gfx::Vector2dF(0, 100);
1447 EXPECT_CALL(mock_input_handler_,
1448 ScrollBy(testing::_,
1449 testing::Property(&gfx::Vector2dF::y, testing::Lt(0))))
1450 .WillOnce(testing::Return(overscroll));
1451 EXPECT_CALL(
1452 mock_client_,
1453 DidOverscroll(testing::AllOf(
1454 testing::Field(
1455 &DidOverscrollParams::accumulated_overscroll,
1456 testing::Eq(overscroll.accumulated_root_overscroll)),
1457 testing::Field(
1458 &DidOverscrollParams::latest_overscroll_delta,
1459 testing::Eq(overscroll.unused_scroll_delta)),
1460 testing::Field(
1461 &DidOverscrollParams::current_fling_velocity,
1462 testing::Property(&gfx::Vector2dF::y, testing::Lt(0))))));
1463 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1464 time += base::TimeDelta::FromMilliseconds(10);
1465 input_handler_->Animate(time);
1466 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1468 // The next call to animate will no longer scroll vertically.
1469 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1470 EXPECT_CALL(mock_input_handler_,
1471 ScrollBy(testing::_,
1472 testing::Property(&gfx::Vector2dF::y, testing::Eq(0))))
1473 .WillOnce(testing::Return(scroll_result_did_scroll_));
1474 time += base::TimeDelta::FromMilliseconds(10);
1475 input_handler_->Animate(time);
1476 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1478 // The next call will hit the right edge.
1479 overscroll.accumulated_root_overscroll = gfx::Vector2dF(100, 100);
1480 overscroll.unused_scroll_delta = gfx::Vector2dF(100, 0);
1481 EXPECT_CALL(mock_input_handler_,
1482 ScrollBy(testing::_,
1483 testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))
1484 .WillOnce(testing::Return(overscroll));
1485 EXPECT_CALL(
1486 mock_client_,
1487 DidOverscroll(testing::AllOf(
1488 testing::Field(
1489 &DidOverscrollParams::accumulated_overscroll,
1490 testing::Eq(overscroll.accumulated_root_overscroll)),
1491 testing::Field(
1492 &DidOverscrollParams::latest_overscroll_delta,
1493 testing::Eq(overscroll.unused_scroll_delta)),
1494 testing::Field(
1495 &DidOverscrollParams::current_fling_velocity,
1496 testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))));
1497 EXPECT_CALL(mock_input_handler_, ScrollEnd());
1498 time += base::TimeDelta::FromMilliseconds(10);
1499 input_handler_->Animate(time);
1500 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1502 // The next call to animate will no longer scroll horizontally or vertically,
1503 // and the fling should be cancelled.
1504 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()).Times(0);
1505 EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_, testing::_)).Times(0);
1506 time += base::TimeDelta::FromMilliseconds(10);
1507 input_handler_->Animate(time);
1508 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1509 EXPECT_FALSE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
1512 TEST_F(InputHandlerProxyTest, MultiTouchPointHitTestNegative) {
1513 // None of the three touch points fall in the touch region. So the event
1514 // should be dropped.
1515 expected_disposition_ = InputHandlerProxy::DROP_EVENT;
1516 VERIFY_AND_RESET_MOCKS();
1518 EXPECT_CALL(mock_input_handler_,
1519 DoTouchEventsBlockScrollAt(
1520 testing::Property(&gfx::Point::x, testing::Gt(0))))
1521 .WillOnce(testing::Return(false));
1522 EXPECT_CALL(mock_input_handler_,
1523 DoTouchEventsBlockScrollAt(
1524 testing::Property(&gfx::Point::x, testing::Lt(0))))
1525 .WillOnce(testing::Return(false));
1527 WebTouchEvent touch;
1528 touch.type = WebInputEvent::TouchStart;
1530 touch.touchesLength = 3;
1531 touch.touches[0] = CreateWebTouchPoint(WebTouchPoint::StateStationary, 0, 0);
1532 touch.touches[1] = CreateWebTouchPoint(WebTouchPoint::StatePressed, 10, 10);
1533 touch.touches[2] = CreateWebTouchPoint(WebTouchPoint::StatePressed, -10, 10);
1534 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(touch));
1537 TEST_F(InputHandlerProxyTest, MultiTouchPointHitTestPositive) {
1538 // One of the touch points is on a touch-region. So the event should be sent
1539 // to the main thread.
1540 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
1541 VERIFY_AND_RESET_MOCKS();
1543 EXPECT_CALL(mock_input_handler_,
1544 DoTouchEventsBlockScrollAt(
1545 testing::Property(&gfx::Point::x, testing::Eq(0))))
1546 .WillOnce(testing::Return(false));
1547 EXPECT_CALL(mock_input_handler_,
1548 DoTouchEventsBlockScrollAt(
1549 testing::Property(&gfx::Point::x, testing::Gt(0))))
1550 .WillOnce(testing::Return(true));
1551 // Since the second touch point hits a touch-region, there should be no
1552 // hit-testing for the third touch point.
1554 WebTouchEvent touch;
1555 touch.type = WebInputEvent::TouchStart;
1557 touch.touchesLength = 3;
1558 touch.touches[0] = CreateWebTouchPoint(WebTouchPoint::StatePressed, 0, 0);
1559 touch.touches[1] = CreateWebTouchPoint(WebTouchPoint::StatePressed, 10, 10);
1560 touch.touches[2] = CreateWebTouchPoint(WebTouchPoint::StatePressed, -10, 10);
1561 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(touch));
1564 TEST_F(InputHandlerProxyTest, GestureFlingCancelledByKeyboardEvent) {
1565 // We shouldn't send any events to the widget for this gesture.
1566 expected_disposition_ = InputHandlerProxy::DID_HANDLE;
1567 VERIFY_AND_RESET_MOCKS();
1569 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
1570 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
1571 gesture_.type = WebInputEvent::GestureScrollBegin;
1572 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen;
1573 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1574 EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
1575 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1577 // Keyboard events received during a scroll should have no effect.
1578 WebKeyboardEvent key_event;
1579 key_event.type = WebInputEvent::KeyDown;
1580 EXPECT_EQ(InputHandlerProxy::DID_NOT_HANDLE,
1581 input_handler_->HandleInputEvent(key_event));
1582 EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
1583 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1585 // On the fling start, animation should be scheduled, but no scrolling occurs.
1586 gesture_.type = WebInputEvent::GestureFlingStart;
1587 WebFloatPoint fling_delta = WebFloatPoint(100, 100);
1588 gesture_.data.flingStart.velocityX = fling_delta.x;
1589 gesture_.data.flingStart.velocityY = fling_delta.y;
1590 EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
1591 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
1592 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1593 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1594 EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
1595 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1597 // Keyboard events received during a fling should cancel the active fling.
1598 EXPECT_CALL(mock_input_handler_, ScrollEnd());
1599 EXPECT_EQ(InputHandlerProxy::DID_NOT_HANDLE,
1600 input_handler_->HandleInputEvent(key_event));
1601 EXPECT_FALSE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
1602 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1604 // The call to animate should have no effect, as the fling was cancelled.
1605 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
1606 input_handler_->Animate(time);
1607 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1609 // A fling cancel should be dropped, as there is nothing to cancel.
1610 gesture_.type = WebInputEvent::GestureFlingCancel;
1611 EXPECT_EQ(InputHandlerProxy::DROP_EVENT,
1612 input_handler_->HandleInputEvent(gesture_));
1613 EXPECT_FALSE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
1616 TEST_F(InputHandlerProxyTest, GestureFlingWithNegativeTimeDelta) {
1617 // We shouldn't send any events to the widget for this gesture.
1618 expected_disposition_ = InputHandlerProxy::DID_HANDLE;
1619 VERIFY_AND_RESET_MOCKS();
1621 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
1622 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
1624 gesture_.type = WebInputEvent::GestureScrollBegin;
1625 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen;
1626 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1628 VERIFY_AND_RESET_MOCKS();
1630 // On the fling start, we should schedule an animation but not actually start
1631 // scrolling.
1632 base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10);
1633 base::TimeTicks time = base::TimeTicks() + dt;
1634 WebFloatPoint fling_delta = WebFloatPoint(100, 0);
1635 WebPoint fling_point = WebPoint(7, 13);
1636 WebPoint fling_global_point = WebPoint(17, 23);
1637 int modifiers = WebInputEvent::ControlKey;
1638 gesture_ = CreateFling(time,
1639 blink::WebGestureDeviceTouchscreen,
1640 fling_delta,
1641 fling_point,
1642 fling_global_point,
1643 modifiers);
1644 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1645 EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
1646 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
1647 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1649 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1651 // If we get a negative time delta, that is, the Animation tick time happens
1652 // before the fling's start time then we should *not* try scrolling and
1653 // instead reset the fling start time.
1654 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1655 EXPECT_CALL(mock_input_handler_,
1656 ScrollBy(testing::_,
1657 testing::_)).Times(0);
1658 time -= base::TimeDelta::FromMilliseconds(5);
1659 input_handler_->Animate(time);
1661 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1663 // The first call should have reset the start time so subsequent calls should
1664 // generate scroll events.
1665 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1666 EXPECT_CALL(mock_input_handler_,
1667 ScrollBy(testing::_,
1668 testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))
1669 .WillOnce(testing::Return(scroll_result_did_scroll_));
1671 input_handler_->Animate(time + base::TimeDelta::FromMilliseconds(1));
1673 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1675 EXPECT_CALL(mock_input_handler_, ScrollEnd());
1676 gesture_.type = WebInputEvent::GestureFlingCancel;
1677 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1680 TEST_F(InputHandlerProxyTest, FlingBoost) {
1681 base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10);
1682 base::TimeTicks time = base::TimeTicks() + dt;
1683 base::TimeTicks last_animate_time = time;
1684 WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
1685 WebPoint fling_point = WebPoint(7, 13);
1686 StartFling(
1687 time, blink::WebGestureDeviceTouchscreen, fling_delta, fling_point);
1689 // Now cancel the fling. The fling cancellation should be deferred to allow
1690 // fling boosting events to arrive.
1691 time += dt;
1692 CancelFling(time);
1694 // The GestureScrollBegin should be swallowed by the fling if it hits the same
1695 // scrolling layer.
1696 EXPECT_CALL(mock_input_handler_,
1697 IsCurrentlyScrollingLayerAt(testing::_, testing::_))
1698 .WillOnce(testing::Return(true));
1700 time += dt;
1701 gesture_.timeStampSeconds = InSecondsF(time);
1702 gesture_.type = WebInputEvent::GestureScrollBegin;
1703 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1705 VERIFY_AND_RESET_MOCKS();
1707 // Animate calls within the deferred cancellation window should continue.
1708 time += dt;
1709 float expected_delta =
1710 (time - last_animate_time).InSecondsF() * -fling_delta.x;
1711 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1712 EXPECT_CALL(mock_input_handler_,
1713 ScrollBy(testing::_,
1714 testing::Property(&gfx::Vector2dF::x,
1715 testing::Eq(expected_delta))))
1716 .WillOnce(testing::Return(scroll_result_did_scroll_));
1717 input_handler_->Animate(time);
1718 last_animate_time = time;
1720 VERIFY_AND_RESET_MOCKS();
1722 // GestureScrollUpdates in the same direction and at sufficient speed should
1723 // be swallowed by the fling.
1724 time += dt;
1725 gesture_.timeStampSeconds = InSecondsF(time);
1726 gesture_.type = WebInputEvent::GestureScrollUpdate;
1727 gesture_.data.scrollUpdate.deltaX = fling_delta.x;
1728 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1730 VERIFY_AND_RESET_MOCKS();
1732 // Animate calls within the deferred cancellation window should continue.
1733 time += dt;
1734 expected_delta = (time - last_animate_time).InSecondsF() * -fling_delta.x;
1735 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1736 EXPECT_CALL(mock_input_handler_,
1737 ScrollBy(testing::_,
1738 testing::Property(&gfx::Vector2dF::x,
1739 testing::Eq(expected_delta))))
1740 .WillOnce(testing::Return(scroll_result_did_scroll_));
1741 input_handler_->Animate(time);
1742 last_animate_time = time;
1744 VERIFY_AND_RESET_MOCKS();
1746 // GestureFlingStart in the same direction and at sufficient speed should
1747 // boost the active fling.
1749 gesture_ = CreateFling(time,
1750 blink::WebGestureDeviceTouchscreen,
1751 fling_delta,
1752 fling_point,
1753 fling_point,
1755 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1756 VERIFY_AND_RESET_MOCKS();
1758 time += dt;
1759 // Note we get *2x* as much delta because 2 flings have combined.
1760 expected_delta = 2 * (time - last_animate_time).InSecondsF() * -fling_delta.x;
1761 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1762 EXPECT_CALL(mock_input_handler_,
1763 ScrollBy(testing::_,
1764 testing::Property(&gfx::Vector2dF::x,
1765 testing::Eq(expected_delta))))
1766 .WillOnce(testing::Return(scroll_result_did_scroll_));
1767 input_handler_->Animate(time);
1768 last_animate_time = time;
1770 VERIFY_AND_RESET_MOCKS();
1772 // Repeated GestureFlingStarts should accumulate.
1774 CancelFling(time);
1775 gesture_ = CreateFling(time,
1776 blink::WebGestureDeviceTouchscreen,
1777 fling_delta,
1778 fling_point,
1779 fling_point,
1781 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1782 VERIFY_AND_RESET_MOCKS();
1784 time += dt;
1785 // Note we get *3x* as much delta because 3 flings have combined.
1786 expected_delta = 3 * (time - last_animate_time).InSecondsF() * -fling_delta.x;
1787 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1788 EXPECT_CALL(mock_input_handler_,
1789 ScrollBy(testing::_,
1790 testing::Property(&gfx::Vector2dF::x,
1791 testing::Eq(expected_delta))))
1792 .WillOnce(testing::Return(scroll_result_did_scroll_));
1793 input_handler_->Animate(time);
1794 last_animate_time = time;
1796 VERIFY_AND_RESET_MOCKS();
1798 // GestureFlingCancel should terminate the fling if no boosting gestures are
1799 // received within the timeout window.
1801 time += dt;
1802 gesture_.timeStampSeconds = InSecondsF(time);
1803 gesture_.type = WebInputEvent::GestureFlingCancel;
1804 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1806 VERIFY_AND_RESET_MOCKS();
1808 time += base::TimeDelta::FromMilliseconds(100);
1809 EXPECT_CALL(mock_input_handler_, ScrollEnd());
1810 input_handler_->Animate(time);
1812 VERIFY_AND_RESET_MOCKS();
1815 TEST_F(InputHandlerProxyTest, NoFlingBoostIfScrollTargetsDifferentLayer) {
1816 base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10);
1817 base::TimeTicks time = base::TimeTicks() + dt;
1818 WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
1819 WebPoint fling_point = WebPoint(7, 13);
1820 StartFling(
1821 time, blink::WebGestureDeviceTouchscreen, fling_delta, fling_point);
1823 // Cancel the fling. The fling cancellation should be deferred to allow
1824 // fling boosting events to arrive.
1825 time += dt;
1826 CancelFling(time);
1828 // If the GestureScrollBegin targets a different layer, the fling should be
1829 // cancelled and the scroll should be handled as usual.
1830 EXPECT_CALL(mock_input_handler_,
1831 IsCurrentlyScrollingLayerAt(testing::_, testing::_))
1832 .WillOnce(testing::Return(false));
1833 EXPECT_CALL(mock_input_handler_, ScrollEnd());
1834 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
1835 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
1837 time += dt;
1838 gesture_.timeStampSeconds = InSecondsF(time);
1839 gesture_.type = WebInputEvent::GestureScrollBegin;
1840 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1842 VERIFY_AND_RESET_MOCKS();
1845 TEST_F(InputHandlerProxyTest, NoFlingBoostIfScrollDelayed) {
1846 base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10);
1847 base::TimeTicks time = base::TimeTicks() + dt;
1848 WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
1849 WebPoint fling_point = WebPoint(7, 13);
1850 StartFling(
1851 time, blink::WebGestureDeviceTouchscreen, fling_delta, fling_point);
1853 // Cancel the fling. The fling cancellation should be deferred to allow
1854 // fling boosting events to arrive.
1855 time += dt;
1856 CancelFling(time);
1858 // The GestureScrollBegin should be swallowed by the fling if it hits the same
1859 // scrolling layer.
1860 EXPECT_CALL(mock_input_handler_,
1861 IsCurrentlyScrollingLayerAt(testing::_, testing::_))
1862 .WillOnce(testing::Return(true));
1864 time += dt;
1865 gesture_.timeStampSeconds = InSecondsF(time);
1866 gesture_.type = WebInputEvent::GestureScrollBegin;
1867 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1869 VERIFY_AND_RESET_MOCKS();
1871 // If no GestureScrollUpdate or GestureFlingStart is received within the
1872 // timeout window, the fling should be cancelled and scrolling should resume.
1873 time += base::TimeDelta::FromMilliseconds(100);
1874 EXPECT_CALL(mock_input_handler_, ScrollEnd());
1875 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
1876 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
1877 input_handler_->Animate(time);
1879 VERIFY_AND_RESET_MOCKS();
1882 TEST_F(InputHandlerProxyTest, NoFlingBoostIfFlingInDifferentDirection) {
1883 base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10);
1884 base::TimeTicks time = base::TimeTicks() + dt;
1885 WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
1886 WebPoint fling_point = WebPoint(7, 13);
1887 StartFling(
1888 time, blink::WebGestureDeviceTouchscreen, fling_delta, fling_point);
1890 // Cancel the fling. The fling cancellation should be deferred to allow
1891 // fling boosting events to arrive.
1892 time += dt;
1893 CancelFling(time);
1895 // If the new fling is orthogonal to the existing fling, no boosting should
1896 // take place, with the new fling replacing the old.
1897 WebFloatPoint orthogonal_fling_delta =
1898 WebFloatPoint(fling_delta.y, -fling_delta.x);
1899 gesture_ = CreateFling(time,
1900 blink::WebGestureDeviceTouchscreen,
1901 orthogonal_fling_delta,
1902 fling_point,
1903 fling_point,
1905 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1907 VERIFY_AND_RESET_MOCKS();
1909 // Note that the new fling delta uses the orthogonal, unboosted fling
1910 // velocity.
1911 time += dt;
1912 float expected_delta = dt.InSecondsF() * -orthogonal_fling_delta.y;
1913 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1914 EXPECT_CALL(mock_input_handler_,
1915 ScrollBy(testing::_,
1916 testing::Property(&gfx::Vector2dF::y,
1917 testing::Eq(expected_delta))))
1918 .WillOnce(testing::Return(scroll_result_did_scroll_));
1919 input_handler_->Animate(time);
1921 VERIFY_AND_RESET_MOCKS();
1924 TEST_F(InputHandlerProxyTest, NoFlingBoostIfScrollInDifferentDirection) {
1925 base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10);
1926 base::TimeTicks time = base::TimeTicks() + dt;
1927 WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
1928 WebPoint fling_point = WebPoint(7, 13);
1929 StartFling(
1930 time, blink::WebGestureDeviceTouchscreen, fling_delta, fling_point);
1932 // Cancel the fling. The fling cancellation should be deferred to allow
1933 // fling boosting events to arrive.
1934 time += dt;
1935 CancelFling(time);
1937 // The GestureScrollBegin should be swallowed by the fling if it hits the same
1938 // scrolling layer.
1939 EXPECT_CALL(mock_input_handler_,
1940 IsCurrentlyScrollingLayerAt(testing::_, testing::_))
1941 .WillOnce(testing::Return(true));
1943 time += dt;
1944 gesture_.timeStampSeconds = InSecondsF(time);
1945 gesture_.type = WebInputEvent::GestureScrollBegin;
1946 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1948 VERIFY_AND_RESET_MOCKS();
1950 // If the GestureScrollUpdate is in a different direction than the fling,
1951 // the fling should be cancelled and scrolling should resume.
1952 time += dt;
1953 gesture_.timeStampSeconds = InSecondsF(time);
1954 gesture_.type = WebInputEvent::GestureScrollUpdate;
1955 gesture_.data.scrollUpdate.deltaX = -fling_delta.x;
1956 EXPECT_CALL(mock_input_handler_, ScrollEnd());
1957 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
1958 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
1959 EXPECT_CALL(mock_input_handler_,
1960 ScrollBy(testing::_,
1961 testing::Property(&gfx::Vector2dF::x,
1962 testing::Eq(fling_delta.x))))
1963 .WillOnce(testing::Return(scroll_result_did_scroll_));
1964 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1966 VERIFY_AND_RESET_MOCKS();
1969 TEST_F(InputHandlerProxyTest, NoFlingBoostIfFlingTooSlow) {
1970 base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10);
1971 base::TimeTicks time = base::TimeTicks() + dt;
1972 WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
1973 WebPoint fling_point = WebPoint(7, 13);
1974 StartFling(
1975 time, blink::WebGestureDeviceTouchscreen, fling_delta, fling_point);
1977 // Cancel the fling. The fling cancellation should be deferred to allow
1978 // fling boosting events to arrive.
1979 time += dt;
1980 CancelFling(time);
1982 // If the new fling is too slow, no boosting should take place, with the new
1983 // fling replacing the old.
1984 WebFloatPoint small_fling_delta = WebFloatPoint(100, 0);
1985 gesture_ = CreateFling(time,
1986 blink::WebGestureDeviceTouchscreen,
1987 small_fling_delta,
1988 fling_point,
1989 fling_point,
1991 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1993 VERIFY_AND_RESET_MOCKS();
1995 // Note that the new fling delta uses the *slow*, unboosted fling velocity.
1996 time += dt;
1997 float expected_delta = dt.InSecondsF() * -small_fling_delta.x;
1998 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1999 EXPECT_CALL(mock_input_handler_,
2000 ScrollBy(testing::_,
2001 testing::Property(&gfx::Vector2dF::x,
2002 testing::Eq(expected_delta))))
2003 .WillOnce(testing::Return(scroll_result_did_scroll_));
2004 input_handler_->Animate(time);
2006 VERIFY_AND_RESET_MOCKS();
2009 TEST_F(InputHandlerProxyTest, NoFlingBoostIfPreventBoostingFlagIsSet) {
2010 base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10);
2011 base::TimeTicks time = base::TimeTicks() + dt;
2012 WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
2013 WebPoint fling_point = WebPoint(7, 13);
2015 StartFling(
2016 time, blink::WebGestureDeviceTouchscreen, fling_delta, fling_point);
2018 EXPECT_CALL(mock_input_handler_, ScrollEnd());
2020 // Cancel the fling. The fling cancellation should not be deferred because of
2021 // prevent boosting flag set.
2022 gesture_.data.flingCancel.preventBoosting = true;
2023 time += dt;
2024 CancelFling(time);
2026 // VERIFY_AND_RESET_MOCKS already called by CancelFling
2029 TEST_F(InputHandlerProxyTest, FlingBoostTerminatedDuringScrollSequence) {
2030 base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10);
2031 base::TimeTicks time = base::TimeTicks() + dt;
2032 base::TimeTicks last_animate_time = time;
2033 WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
2034 WebPoint fling_point = WebPoint(7, 13);
2035 StartFling(
2036 time, blink::WebGestureDeviceTouchscreen, fling_delta, fling_point);
2038 // Now cancel the fling. The fling cancellation should be deferred to allow
2039 // fling boosting events to arrive.
2040 time += dt;
2041 CancelFling(time);
2043 // The GestureScrollBegin should be swallowed by the fling.
2044 time += dt;
2045 gesture_.timeStampSeconds = InSecondsF(time);
2046 gesture_.type = WebInputEvent::GestureScrollBegin;
2047 EXPECT_CALL(mock_input_handler_,
2048 IsCurrentlyScrollingLayerAt(testing::_, testing::_))
2049 .WillOnce(testing::Return(true));
2050 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
2052 VERIFY_AND_RESET_MOCKS();
2054 // Now animate the fling to completion (in this case, the fling should
2055 // terminate because the input handler reports a failed scroll). As the fling
2056 // was cancelled during an active scroll sequence, a synthetic
2057 // GestureScrollBegin should be processed, resuming the scroll.
2058 time += dt;
2059 float expected_delta =
2060 (time - last_animate_time).InSecondsF() * -fling_delta.x;
2061 EXPECT_CALL(mock_input_handler_,
2062 ScrollBy(testing::_,
2063 testing::Property(&gfx::Vector2dF::x,
2064 testing::Eq(expected_delta))))
2065 .WillOnce(testing::Return(scroll_result_did_not_scroll_));
2066 EXPECT_CALL(mock_input_handler_, ScrollEnd());
2067 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
2068 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
2069 input_handler_->Animate(time);
2071 VERIFY_AND_RESET_MOCKS();
2073 // Subsequent GestureScrollUpdates after the cancelled, boosted fling should
2074 // cause scrolling as usual.
2075 time += dt;
2076 expected_delta = 7.3f;
2077 gesture_.timeStampSeconds = InSecondsF(time);
2078 gesture_.type = WebInputEvent::GestureScrollUpdate;
2079 gesture_.data.scrollUpdate.deltaX = -expected_delta;
2080 EXPECT_CALL(mock_input_handler_,
2081 ScrollBy(testing::_,
2082 testing::Property(&gfx::Vector2dF::x,
2083 testing::Eq(expected_delta))))
2084 .WillOnce(testing::Return(scroll_result_did_scroll_));
2085 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
2087 VERIFY_AND_RESET_MOCKS();
2089 // GestureScrollEnd should terminate the resumed scroll properly.
2090 time += dt;
2091 gesture_.timeStampSeconds = InSecondsF(time);
2092 gesture_.type = WebInputEvent::GestureScrollEnd;
2093 EXPECT_CALL(mock_input_handler_, ScrollEnd());
2094 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
2096 VERIFY_AND_RESET_MOCKS();
2099 TEST_F(InputHandlerProxyTest, DidReceiveInputEvent_ForFling) {
2100 testing::StrictMock<MockInputHandlerProxyClientWithDidAnimateForInput>
2101 mock_client;
2102 input_handler_.reset(
2103 new content::InputHandlerProxy(&mock_input_handler_, &mock_client));
2105 gesture_.type = WebInputEvent::GestureFlingStart;
2106 WebFloatPoint fling_delta = WebFloatPoint(100, 100);
2107 gesture_.data.flingStart.velocityX = fling_delta.x;
2108 gesture_.data.flingStart.velocityY = fling_delta.y;
2109 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
2110 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
2111 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED));
2112 EXPECT_CALL(mock_input_handler_, ScrollEnd());
2113 EXPECT_EQ(InputHandlerProxy::DID_HANDLE,
2114 input_handler_->HandleInputEvent(gesture_));
2115 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
2116 testing::Mock::VerifyAndClearExpectations(&mock_client);
2118 EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
2119 EXPECT_CALL(mock_client, DidAnimateForInput());
2120 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
2121 input_handler_->Animate(time);
2123 testing::Mock::VerifyAndClearExpectations(&mock_client);
2126 } // namespace
2127 } // namespace content