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
;
31 using blink::WebTouchEvent
;
32 using blink::WebTouchPoint
;
38 enum InputHandlerProxyTestType
{
39 ROOT_SCROLL_NORMAL_HANDLER
,
40 ROOT_SCROLL_SYNCHRONOUS_HANDLER
,
41 CHILD_SCROLL_NORMAL_HANDLER
,
42 CHILD_SCROLL_SYNCHRONOUS_HANDLER
,
44 static const InputHandlerProxyTestType test_types
[] = {
45 ROOT_SCROLL_NORMAL_HANDLER
, ROOT_SCROLL_SYNCHRONOUS_HANDLER
,
46 CHILD_SCROLL_NORMAL_HANDLER
, CHILD_SCROLL_SYNCHRONOUS_HANDLER
};
48 double InSecondsF(const base::TimeTicks
& time
) {
49 return (time
- base::TimeTicks()).InSecondsF();
52 WebGestureEvent
CreateFling(base::TimeTicks timestamp
,
53 WebGestureDevice source_device
,
54 WebFloatPoint velocity
,
56 WebPoint global_point
,
58 WebGestureEvent fling
;
59 fling
.type
= WebInputEvent::GestureFlingStart
;
60 fling
.sourceDevice
= source_device
;
61 fling
.timeStampSeconds
= (timestamp
- base::TimeTicks()).InSecondsF();
62 fling
.data
.flingStart
.velocityX
= velocity
.x
;
63 fling
.data
.flingStart
.velocityY
= velocity
.y
;
66 fling
.globalX
= global_point
.x
;
67 fling
.globalY
= global_point
.y
;
68 fling
.modifiers
= modifiers
;
72 WebGestureEvent
CreateFling(WebGestureDevice source_device
,
73 WebFloatPoint velocity
,
75 WebPoint global_point
,
77 return CreateFling(base::TimeTicks(),
85 class MockInputHandler
: public cc::InputHandler
{
88 ~MockInputHandler() override
{}
90 MOCK_METHOD0(PinchGestureBegin
, void());
91 MOCK_METHOD2(PinchGestureUpdate
,
92 void(float magnify_delta
, const gfx::Point
& anchor
));
93 MOCK_METHOD0(PinchGestureEnd
, void());
95 MOCK_METHOD0(SetNeedsAnimateInput
, void());
97 MOCK_METHOD2(ScrollBegin
,
98 ScrollStatus(const gfx::Point
& viewport_point
,
99 cc::InputHandler::ScrollInputType type
));
100 MOCK_METHOD1(RootScrollBegin
,
101 ScrollStatus(cc::InputHandler::ScrollInputType type
));
102 MOCK_METHOD2(ScrollAnimated
,
103 ScrollStatus(const gfx::Point
& viewport_point
,
104 const gfx::Vector2dF
& scroll_delta
));
105 MOCK_METHOD2(ScrollBy
,
106 cc::InputHandlerScrollResult(
107 const gfx::Point
& viewport_point
,
108 const gfx::Vector2dF
& scroll_delta
));
109 MOCK_METHOD2(ScrollVerticallyByPage
,
110 bool(const gfx::Point
& viewport_point
,
111 cc::ScrollDirection direction
));
112 MOCK_METHOD0(ScrollEnd
, void());
113 MOCK_METHOD0(FlingScrollBegin
, cc::InputHandler::ScrollStatus());
115 scoped_ptr
<cc::SwapPromiseMonitor
> CreateLatencyInfoSwapPromiseMonitor(
116 ui::LatencyInfo
* latency
) override
{
117 return scoped_ptr
<cc::SwapPromiseMonitor
>();
120 cc::ScrollElasticityHelper
* CreateScrollElasticityHelper() override
{
124 void BindToClient(cc::InputHandlerClient
* client
) override
{}
126 void MouseMoveAt(const gfx::Point
& mouse_position
) override
{}
128 MOCK_CONST_METHOD2(IsCurrentlyScrollingLayerAt
,
129 bool(const gfx::Point
& point
,
130 cc::InputHandler::ScrollInputType type
));
132 MOCK_METHOD1(HaveWheelEventHandlersAt
, bool(const gfx::Point
& point
));
133 MOCK_METHOD1(DoTouchEventsBlockScrollAt
, bool(const gfx::Point
& point
));
135 void SetRootLayerScrollOffsetDelegate(
136 cc::LayerScrollOffsetDelegate
* root_layer_scroll_offset_delegate
)
139 void OnRootLayerDelegatedScrollOffsetChanged(
140 const gfx::ScrollOffset
& root_offset
) override
{}
142 bool IsCurrentlyScrollingRoot() const override
{ return is_scrolling_root_
; }
143 void set_is_scrolling_root(bool is
) { is_scrolling_root_
= is
; }
146 bool is_scrolling_root_
= true;
147 DISALLOW_COPY_AND_ASSIGN(MockInputHandler
);
150 class MockSynchronousInputHandler
: public content::SynchronousInputHandler
{
152 MOCK_METHOD0(SetNeedsSynchronousAnimateInput
, void());
155 // A simple WebGestureCurve implementation that flings at a constant velocity
157 class FakeWebGestureCurve
: public blink::WebGestureCurve
{
159 FakeWebGestureCurve(const blink::WebFloatSize
& velocity
,
160 const blink::WebFloatSize
& cumulative_scroll
)
161 : velocity_(velocity
), cumulative_scroll_(cumulative_scroll
) {}
163 virtual ~FakeWebGestureCurve() {}
165 // Returns false if curve has finished and can no longer be applied.
166 virtual bool apply(double time
, blink::WebGestureCurveTarget
* target
) {
167 blink::WebFloatSize
displacement(velocity_
.width
* time
,
168 velocity_
.height
* time
);
169 blink::WebFloatSize
increment(
170 displacement
.width
- cumulative_scroll_
.width
,
171 displacement
.height
- cumulative_scroll_
.height
);
172 cumulative_scroll_
= displacement
;
173 // scrollBy() could delete this curve if the animation is over, so don't
174 // touch any member variables after making that call.
175 return target
->scrollBy(increment
, velocity_
);
179 blink::WebFloatSize velocity_
;
180 blink::WebFloatSize cumulative_scroll_
;
182 DISALLOW_COPY_AND_ASSIGN(FakeWebGestureCurve
);
185 class MockInputHandlerProxyClient
186 : public content::InputHandlerProxyClient
{
188 MockInputHandlerProxyClient() {}
189 ~MockInputHandlerProxyClient() override
{}
191 void WillShutdown() override
{}
193 MOCK_METHOD1(TransferActiveWheelFlingAnimation
,
194 void(const WebActiveWheelFlingParameters
&));
196 blink::WebGestureCurve
* CreateFlingAnimationCurve(
197 WebGestureDevice deviceSource
,
198 const WebFloatPoint
& velocity
,
199 const WebSize
& cumulative_scroll
) override
{
200 return new FakeWebGestureCurve(
201 blink::WebFloatSize(velocity
.x
, velocity
.y
),
202 blink::WebFloatSize(cumulative_scroll
.width
, cumulative_scroll
.height
));
205 MOCK_METHOD1(DidOverscroll
, void(const DidOverscrollParams
&));
206 void DidStopFlinging() override
{}
207 void DidAnimateForInput() override
{}
210 DISALLOW_COPY_AND_ASSIGN(MockInputHandlerProxyClient
);
213 class MockInputHandlerProxyClientWithDidAnimateForInput
214 : public MockInputHandlerProxyClient
{
216 MockInputHandlerProxyClientWithDidAnimateForInput() {}
217 ~MockInputHandlerProxyClientWithDidAnimateForInput() override
{}
219 MOCK_METHOD0(DidAnimateForInput
, void());
222 DISALLOW_COPY_AND_ASSIGN(MockInputHandlerProxyClientWithDidAnimateForInput
);
225 WebTouchPoint
CreateWebTouchPoint(WebTouchPoint::State state
, float x
,
229 point
.screenPosition
= WebFloatPoint(x
, y
);
230 point
.position
= WebFloatPoint(x
, y
);
234 class InputHandlerProxyTest
235 : public testing::Test
,
236 public testing::WithParamInterface
<InputHandlerProxyTestType
> {
238 InputHandlerProxyTest()
239 : synchronous_root_scroll_(GetParam() == ROOT_SCROLL_SYNCHRONOUS_HANDLER
),
240 install_synchronous_handler_(
241 GetParam() == ROOT_SCROLL_SYNCHRONOUS_HANDLER
||
242 GetParam() == CHILD_SCROLL_SYNCHRONOUS_HANDLER
),
243 expected_disposition_(InputHandlerProxy::DID_HANDLE
) {
244 input_handler_
.reset(
245 new content::InputHandlerProxy(&mock_input_handler_
, &mock_client_
));
246 scroll_result_did_scroll_
.did_scroll
= true;
247 scroll_result_did_not_scroll_
.did_scroll
= false;
249 if (install_synchronous_handler_
) {
250 input_handler_
->SetOnlySynchronouslyAnimateRootFlings(
251 &mock_synchronous_input_handler_
);
253 mock_input_handler_
.set_is_scrolling_root(synchronous_root_scroll_
);
256 ~InputHandlerProxyTest() {
257 input_handler_
.reset();
260 // This is defined as a macro so the line numbers can be traced back to the
261 // correct spot when it fails.
262 #define EXPECT_SET_NEEDS_ANIMATE_INPUT(times) \
264 if (synchronous_root_scroll_) { \
265 EXPECT_CALL(mock_synchronous_input_handler_, \
266 SetNeedsSynchronousAnimateInput()) \
268 EXPECT_CALL(mock_input_handler_, SetNeedsAnimateInput()).Times(0); \
270 EXPECT_CALL(mock_input_handler_, SetNeedsAnimateInput()).Times(times); \
271 EXPECT_CALL(mock_synchronous_input_handler_, \
272 SetNeedsSynchronousAnimateInput()) \
277 // This is defined as a macro because when an expectation is not satisfied the
278 // only output you get out of gmock is the line number that set the expectation.
279 #define VERIFY_AND_RESET_MOCKS() \
281 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); \
282 testing::Mock::VerifyAndClearExpectations( \
283 &mock_synchronous_input_handler_); \
284 testing::Mock::VerifyAndClearExpectations(&mock_client_); \
287 void Animate(base::TimeTicks time
) {
288 if (synchronous_root_scroll_
) {
289 input_handler_
->SynchronouslyAnimate(time
);
291 input_handler_
->Animate(time
);
295 void StartFling(base::TimeTicks timestamp
,
296 WebGestureDevice source_device
,
297 WebFloatPoint velocity
,
299 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
300 VERIFY_AND_RESET_MOCKS();
302 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
303 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
304 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
305 gesture_
.sourceDevice
= source_device
;
306 EXPECT_EQ(expected_disposition_
,
307 input_handler_
->HandleInputEvent(gesture_
));
309 VERIFY_AND_RESET_MOCKS();
311 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
312 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
313 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
316 CreateFling(timestamp
, source_device
, velocity
, position
, position
, 0);
317 EXPECT_EQ(expected_disposition_
,
318 input_handler_
->HandleInputEvent(gesture_
));
320 VERIFY_AND_RESET_MOCKS();
323 void CancelFling(base::TimeTicks timestamp
) {
324 gesture_
.timeStampSeconds
= InSecondsF(timestamp
);
325 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
326 EXPECT_EQ(expected_disposition_
,
327 input_handler_
->HandleInputEvent(gesture_
));
329 VERIFY_AND_RESET_MOCKS();
333 const bool synchronous_root_scroll_
;
334 const bool install_synchronous_handler_
;
335 testing::StrictMock
<MockInputHandler
> mock_input_handler_
;
336 testing::StrictMock
<MockSynchronousInputHandler
>
337 mock_synchronous_input_handler_
;
338 scoped_ptr
<content::InputHandlerProxy
> input_handler_
;
339 testing::StrictMock
<MockInputHandlerProxyClient
> mock_client_
;
340 WebGestureEvent gesture_
;
341 InputHandlerProxy::EventDisposition expected_disposition_
;
342 cc::InputHandlerScrollResult scroll_result_did_scroll_
;
343 cc::InputHandlerScrollResult scroll_result_did_not_scroll_
;
346 TEST_P(InputHandlerProxyTest
, MouseWheelByPageMainThread
) {
347 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
348 WebMouseWheelEvent wheel
;
349 wheel
.type
= WebInputEvent::MouseWheel
;
350 wheel
.scrollByPage
= true;
352 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(wheel
));
353 VERIFY_AND_RESET_MOCKS();
356 TEST_P(InputHandlerProxyTest
, MouseWheelWithCtrlNotScroll
) {
357 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
358 WebMouseWheelEvent wheel
;
359 wheel
.type
= WebInputEvent::MouseWheel
;
360 wheel
.modifiers
= WebInputEvent::ControlKey
;
361 wheel
.canScroll
= false;
362 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(wheel
));
363 VERIFY_AND_RESET_MOCKS();
366 TEST_P(InputHandlerProxyTest
, GestureScrollStarted
) {
367 // We shouldn't send any events to the widget for this gesture.
368 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
369 VERIFY_AND_RESET_MOCKS();
371 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
372 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
374 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
375 EXPECT_EQ(expected_disposition_
,input_handler_
->HandleInputEvent(gesture_
));
377 // The event should not be marked as handled if scrolling is not possible.
378 expected_disposition_
= InputHandlerProxy::DROP_EVENT
;
379 VERIFY_AND_RESET_MOCKS();
381 gesture_
.type
= WebInputEvent::GestureScrollUpdate
;
382 gesture_
.data
.scrollUpdate
.deltaY
=
383 -40; // -Y means scroll down - i.e. in the +Y direction.
384 EXPECT_CALL(mock_input_handler_
,
386 testing::Property(&gfx::Vector2dF::y
, testing::Gt(0))))
387 .WillOnce(testing::Return(scroll_result_did_not_scroll_
));
388 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
390 // Mark the event as handled if scroll happens.
391 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
392 VERIFY_AND_RESET_MOCKS();
394 gesture_
.type
= WebInputEvent::GestureScrollUpdate
;
395 gesture_
.data
.scrollUpdate
.deltaY
=
396 -40; // -Y means scroll down - i.e. in the +Y direction.
397 EXPECT_CALL(mock_input_handler_
,
399 testing::Property(&gfx::Vector2dF::y
, testing::Gt(0))))
400 .WillOnce(testing::Return(scroll_result_did_scroll_
));
401 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
403 VERIFY_AND_RESET_MOCKS();
405 gesture_
.type
= WebInputEvent::GestureScrollEnd
;
406 gesture_
.data
.scrollUpdate
.deltaY
= 0;
407 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
408 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
410 VERIFY_AND_RESET_MOCKS();
413 TEST_P(InputHandlerProxyTest
, GestureScrollOnMainThread
) {
414 // We should send all events to the widget for this gesture.
415 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
416 VERIFY_AND_RESET_MOCKS();
418 EXPECT_CALL(mock_input_handler_
, ScrollBegin(::testing::_
, ::testing::_
))
419 .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD
));
421 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
422 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
424 VERIFY_AND_RESET_MOCKS();
426 gesture_
.type
= WebInputEvent::GestureScrollUpdate
;
427 gesture_
.data
.scrollUpdate
.deltaY
= 40;
428 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
430 VERIFY_AND_RESET_MOCKS();
432 gesture_
.type
= WebInputEvent::GestureScrollEnd
;
433 gesture_
.data
.scrollUpdate
.deltaY
= 0;
434 EXPECT_CALL(mock_input_handler_
, ScrollEnd()).WillOnce(testing::Return());
435 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
437 VERIFY_AND_RESET_MOCKS();
440 TEST_P(InputHandlerProxyTest
, GestureScrollIgnored
) {
441 // We shouldn't handle the GestureScrollBegin.
442 // Instead, we should get a DROP_EVENT result, indicating
443 // that we could determine that there's nothing that could scroll or otherwise
444 // react to this gesture sequence and thus we should drop the whole gesture
445 // sequence on the floor, except for the ScrollEnd.
446 expected_disposition_
= InputHandlerProxy::DROP_EVENT
;
447 VERIFY_AND_RESET_MOCKS();
449 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
450 .WillOnce(testing::Return(cc::InputHandler::SCROLL_IGNORED
));
452 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
453 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
455 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
456 gesture_
.type
= WebInputEvent::GestureScrollEnd
;
457 EXPECT_CALL(mock_input_handler_
, ScrollEnd()).WillOnce(testing::Return());
458 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
460 VERIFY_AND_RESET_MOCKS();
463 TEST_P(InputHandlerProxyTest
, GestureScrollBeginThatTargetViewport
) {
464 // We shouldn't send any events to the widget for this gesture.
465 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
466 VERIFY_AND_RESET_MOCKS();
468 EXPECT_CALL(mock_input_handler_
, RootScrollBegin(testing::_
))
469 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
471 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
472 gesture_
.data
.scrollBegin
.targetViewport
= true;
473 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
475 VERIFY_AND_RESET_MOCKS();
478 TEST_P(InputHandlerProxyTest
, GesturePinch
) {
479 // We shouldn't send any events to the widget for this gesture.
480 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
481 VERIFY_AND_RESET_MOCKS();
483 gesture_
.type
= WebInputEvent::GesturePinchBegin
;
484 EXPECT_CALL(mock_input_handler_
, HaveWheelEventHandlersAt(testing::_
))
485 .WillOnce(testing::Return(false));
486 EXPECT_CALL(mock_input_handler_
, PinchGestureBegin());
487 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
489 VERIFY_AND_RESET_MOCKS();
491 gesture_
.type
= WebInputEvent::GesturePinchUpdate
;
492 gesture_
.data
.pinchUpdate
.scale
= 1.5;
495 EXPECT_CALL(mock_input_handler_
, PinchGestureUpdate(1.5, gfx::Point(7, 13)));
496 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
498 VERIFY_AND_RESET_MOCKS();
500 gesture_
.type
= WebInputEvent::GesturePinchUpdate
;
501 gesture_
.data
.pinchUpdate
.scale
= 0.5;
502 gesture_
.data
.pinchUpdate
.zoomDisabled
= true;
505 EXPECT_EQ(InputHandlerProxy::DROP_EVENT
,
506 input_handler_
->HandleInputEvent(gesture_
));
507 gesture_
.data
.pinchUpdate
.zoomDisabled
= false;
509 VERIFY_AND_RESET_MOCKS();
511 gesture_
.type
= WebInputEvent::GesturePinchUpdate
;
512 gesture_
.data
.pinchUpdate
.scale
= 0.5;
515 EXPECT_CALL(mock_input_handler_
, PinchGestureUpdate(.5, gfx::Point(9, 6)));
516 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
518 VERIFY_AND_RESET_MOCKS();
520 gesture_
.type
= WebInputEvent::GesturePinchEnd
;
521 EXPECT_CALL(mock_input_handler_
, PinchGestureEnd());
522 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
524 VERIFY_AND_RESET_MOCKS();
527 TEST_P(InputHandlerProxyTest
, GesturePinchWithWheelHandler
) {
528 // We will send the synthetic wheel event to the widget.
529 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
530 VERIFY_AND_RESET_MOCKS();
532 gesture_
.type
= WebInputEvent::GesturePinchBegin
;
533 EXPECT_CALL(mock_input_handler_
, HaveWheelEventHandlersAt(testing::_
))
534 .WillOnce(testing::Return(true));
535 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
537 VERIFY_AND_RESET_MOCKS();
539 gesture_
.type
= WebInputEvent::GesturePinchUpdate
;
540 gesture_
.data
.pinchUpdate
.scale
= 1.5;
543 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
545 VERIFY_AND_RESET_MOCKS();
547 gesture_
.type
= WebInputEvent::GesturePinchUpdate
;
548 gesture_
.data
.pinchUpdate
.scale
= 0.5;
551 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
553 VERIFY_AND_RESET_MOCKS();
555 gesture_
.type
= WebInputEvent::GesturePinchEnd
;
556 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
559 TEST_P(InputHandlerProxyTest
, GesturePinchAfterScrollOnMainThread
) {
560 // Scrolls will start by being sent to the main thread.
561 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
562 VERIFY_AND_RESET_MOCKS();
564 EXPECT_CALL(mock_input_handler_
, ScrollBegin(::testing::_
, ::testing::_
))
565 .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD
));
567 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
568 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
570 VERIFY_AND_RESET_MOCKS();
572 gesture_
.type
= WebInputEvent::GestureScrollUpdate
;
573 gesture_
.data
.scrollUpdate
.deltaY
= 40;
574 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
576 // However, after the pinch gesture starts, they should go to the impl
578 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
579 VERIFY_AND_RESET_MOCKS();
581 gesture_
.type
= WebInputEvent::GesturePinchBegin
;
582 EXPECT_CALL(mock_input_handler_
, HaveWheelEventHandlersAt(testing::_
))
583 .WillOnce(testing::Return(false));
584 EXPECT_CALL(mock_input_handler_
, PinchGestureBegin());
585 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
587 VERIFY_AND_RESET_MOCKS();
589 gesture_
.type
= WebInputEvent::GesturePinchUpdate
;
590 gesture_
.data
.pinchUpdate
.scale
= 1.5;
593 EXPECT_CALL(mock_input_handler_
, PinchGestureUpdate(1.5, gfx::Point(7, 13)));
594 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
596 VERIFY_AND_RESET_MOCKS();
598 gesture_
.type
= WebInputEvent::GestureScrollUpdate
;
599 gesture_
.data
.scrollUpdate
.deltaY
=
600 -40; // -Y means scroll down - i.e. in the +Y direction.
601 EXPECT_CALL(mock_input_handler_
,
603 testing::Property(&gfx::Vector2dF::y
, testing::Gt(0))))
604 .WillOnce(testing::Return(scroll_result_did_scroll_
));
605 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
607 VERIFY_AND_RESET_MOCKS();
609 gesture_
.type
= WebInputEvent::GesturePinchUpdate
;
610 gesture_
.data
.pinchUpdate
.scale
= 0.5;
613 EXPECT_CALL(mock_input_handler_
, PinchGestureUpdate(.5, gfx::Point(9, 6)));
614 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
616 VERIFY_AND_RESET_MOCKS();
618 gesture_
.type
= WebInputEvent::GesturePinchEnd
;
619 EXPECT_CALL(mock_input_handler_
, PinchGestureEnd());
620 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
622 // After the pinch gesture ends, they should go to back to the main
624 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
625 VERIFY_AND_RESET_MOCKS();
627 gesture_
.type
= WebInputEvent::GestureScrollEnd
;
628 gesture_
.data
.scrollUpdate
.deltaY
= 0;
629 EXPECT_CALL(mock_input_handler_
, ScrollEnd())
630 .WillOnce(testing::Return());
631 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
633 VERIFY_AND_RESET_MOCKS();
636 TEST_P(InputHandlerProxyTest
, GestureFlingStartedTouchpad
) {
637 // We shouldn't send any events to the widget for this gesture.
638 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
639 VERIFY_AND_RESET_MOCKS();
641 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
642 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
643 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
644 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
646 gesture_
.type
= WebInputEvent::GestureFlingStart
;
647 gesture_
.data
.flingStart
.velocityX
= 10;
648 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchpad
;
649 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
651 VERIFY_AND_RESET_MOCKS();
653 // Verify that a GestureFlingCancel during an animation cancels it.
654 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
655 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchpad
;
656 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
659 TEST_P(InputHandlerProxyTest
, GestureFlingOnMainThreadTouchpad
) {
660 // We should send all events to the widget for this gesture.
661 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
662 VERIFY_AND_RESET_MOCKS();
664 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
665 .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD
));
667 gesture_
.type
= WebInputEvent::GestureFlingStart
;
668 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchpad
;
669 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
671 // Since we returned ScrollStatusOnMainThread from scrollBegin, ensure the
672 // input handler knows it's scrolling off the impl thread
673 ASSERT_FALSE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
675 VERIFY_AND_RESET_MOCKS();
677 // Even if we didn't start a fling ourselves, we still need to send the cancel
678 // event to the widget.
679 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
680 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchpad
;
681 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
684 TEST_P(InputHandlerProxyTest
, GestureFlingIgnoredTouchpad
) {
685 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
686 VERIFY_AND_RESET_MOCKS();
688 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
689 .WillOnce(testing::Return(cc::InputHandler::SCROLL_IGNORED
));
691 gesture_
.type
= WebInputEvent::GestureFlingStart
;
692 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchpad
;
693 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
695 expected_disposition_
= InputHandlerProxy::DROP_EVENT
;
696 VERIFY_AND_RESET_MOCKS();
698 // Since the previous fling was ignored, we should also be dropping the next
700 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
701 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchpad
;
702 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
705 TEST_P(InputHandlerProxyTest
, GestureFlingAnimatesTouchpad
) {
706 // We shouldn't send any events to the widget for this gesture.
707 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
708 VERIFY_AND_RESET_MOCKS();
710 // On the fling start, we should schedule an animation but not actually start
712 gesture_
.type
= WebInputEvent::GestureFlingStart
;
713 WebFloatPoint fling_delta
= WebFloatPoint(1000, 0);
714 WebPoint fling_point
= WebPoint(7, 13);
715 WebPoint fling_global_point
= WebPoint(17, 23);
716 // Note that for trackpad, wheel events with the Control modifier are
717 // special (reserved for zoom), so don't set that here.
718 int modifiers
= WebInputEvent::ShiftKey
| WebInputEvent::AltKey
;
719 gesture_
= CreateFling(blink::WebGestureDeviceTouchpad
,
724 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
725 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
726 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
727 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
728 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
730 VERIFY_AND_RESET_MOCKS();
731 // The first animate call should let us pick up an animation start time, but
732 // we shouldn't actually move anywhere just yet. The first frame after the
733 // fling start will typically include the last scroll from the gesture that
734 // lead to the scroll (either wheel or gesture scroll), so there should be no
736 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
737 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
739 base::TimeTicks time
= base::TimeTicks() + base::TimeDelta::FromSeconds(10);
742 VERIFY_AND_RESET_MOCKS();
744 // The second call should start scrolling in the -X direction.
745 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
746 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
747 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
748 EXPECT_CALL(mock_input_handler_
,
750 testing::Property(&gfx::Vector2dF::x
, testing::Lt(0))))
751 .WillOnce(testing::Return(scroll_result_did_scroll_
));
752 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
753 time
+= base::TimeDelta::FromMilliseconds(100);
756 VERIFY_AND_RESET_MOCKS();
758 // Let's say on the third call we hit a non-scrollable region. We should abort
759 // the fling and not scroll.
760 // We also should pass the current fling parameters out to the client so the
761 // rest of the fling can be
762 // transferred to the main thread.
763 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
764 .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD
));
765 EXPECT_CALL(mock_input_handler_
, ScrollBy(testing::_
, testing::_
)).Times(0);
766 EXPECT_CALL(mock_input_handler_
, ScrollEnd()).Times(0);
767 // Expected wheel fling animation parameters:
768 // *) fling_delta and fling_point should match the original GestureFlingStart
770 // *) startTime should be 10 to match the time parameter of the first
771 // Animate() call after the GestureFlingStart
772 // *) cumulativeScroll depends on the curve, but since we've animated in the
773 // -X direction the X value should be < 0
776 TransferActiveWheelFlingAnimation(testing::AllOf(
777 testing::Field(&WebActiveWheelFlingParameters::delta
,
778 testing::Eq(fling_delta
)),
779 testing::Field(&WebActiveWheelFlingParameters::point
,
780 testing::Eq(fling_point
)),
781 testing::Field(&WebActiveWheelFlingParameters::globalPoint
,
782 testing::Eq(fling_global_point
)),
783 testing::Field(&WebActiveWheelFlingParameters::modifiers
,
784 testing::Eq(modifiers
)),
785 testing::Field(&WebActiveWheelFlingParameters::startTime
,
787 testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll
,
788 testing::Field(&WebSize::width
, testing::Gt(0))))));
789 time
+= base::TimeDelta::FromMilliseconds(100);
792 VERIFY_AND_RESET_MOCKS();
794 // Since we've aborted the fling, the next animation should be a no-op and
795 // should not result in another
796 // frame being requested.
797 EXPECT_SET_NEEDS_ANIMATE_INPUT(0);
798 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
800 time
+= base::TimeDelta::FromMilliseconds(100);
803 // Since we've transferred the fling to the main thread, we need to pass the
804 // next GestureFlingCancel to the main
806 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
807 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
808 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
810 VERIFY_AND_RESET_MOCKS();
813 TEST_P(InputHandlerProxyTest
, GestureFlingTransferResetsTouchpad
) {
814 // We shouldn't send any events to the widget for this gesture.
815 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
816 VERIFY_AND_RESET_MOCKS();
818 // Start a gesture fling in the -X direction with zero Y movement.
819 WebFloatPoint fling_delta
= WebFloatPoint(1000, 0);
820 WebPoint fling_point
= WebPoint(7, 13);
821 WebPoint fling_global_point
= WebPoint(17, 23);
822 // Note that for trackpad, wheel events with the Control modifier are
823 // special (reserved for zoom), so don't set that here.
824 int modifiers
= WebInputEvent::ShiftKey
| WebInputEvent::AltKey
;
825 gesture_
= CreateFling(blink::WebGestureDeviceTouchpad
,
830 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
831 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
832 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
833 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
834 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
836 VERIFY_AND_RESET_MOCKS();
838 // Start the fling animation at time 10. This shouldn't actually scroll, just
839 // establish a start time.
840 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
841 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
843 base::TimeTicks time
= base::TimeTicks() + base::TimeDelta::FromSeconds(10);
846 VERIFY_AND_RESET_MOCKS();
848 // The second call should start scrolling in the -X direction.
849 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
850 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
851 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
852 EXPECT_CALL(mock_input_handler_
,
854 testing::Property(&gfx::Vector2dF::x
, testing::Lt(0))))
855 .WillOnce(testing::Return(scroll_result_did_scroll_
));
856 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
857 time
+= base::TimeDelta::FromMilliseconds(100);
860 VERIFY_AND_RESET_MOCKS();
862 // Let's say on the third call we hit a non-scrollable region. We should abort
863 // the fling and not scroll.
864 // We also should pass the current fling parameters out to the client so the
865 // rest of the fling can be
866 // transferred to the main thread.
867 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
868 .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD
));
869 EXPECT_CALL(mock_input_handler_
, ScrollBy(testing::_
, testing::_
)).Times(0);
870 EXPECT_CALL(mock_input_handler_
, ScrollEnd()).Times(0);
872 // Expected wheel fling animation parameters:
873 // *) fling_delta and fling_point should match the original GestureFlingStart
875 // *) startTime should be 10 to match the time parameter of the first
876 // Animate() call after the GestureFlingStart
877 // *) cumulativeScroll depends on the curve, but since we've animated in the
878 // -X direction the X value should be < 0
881 TransferActiveWheelFlingAnimation(testing::AllOf(
882 testing::Field(&WebActiveWheelFlingParameters::delta
,
883 testing::Eq(fling_delta
)),
884 testing::Field(&WebActiveWheelFlingParameters::point
,
885 testing::Eq(fling_point
)),
886 testing::Field(&WebActiveWheelFlingParameters::globalPoint
,
887 testing::Eq(fling_global_point
)),
888 testing::Field(&WebActiveWheelFlingParameters::modifiers
,
889 testing::Eq(modifiers
)),
890 testing::Field(&WebActiveWheelFlingParameters::startTime
,
892 testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll
,
893 testing::Field(&WebSize::width
, testing::Gt(0))))));
894 time
+= base::TimeDelta::FromMilliseconds(100);
897 VERIFY_AND_RESET_MOCKS();
899 // Since we've aborted the fling, the next animation should be a no-op and
900 // should not result in another
901 // frame being requested.
902 EXPECT_SET_NEEDS_ANIMATE_INPUT(0);
903 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
905 time
+= base::TimeDelta::FromMilliseconds(100);
908 VERIFY_AND_RESET_MOCKS();
910 // Since we've transferred the fling to the main thread, we need to pass the
911 // next GestureFlingCancel to the main
913 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
914 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
915 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
917 VERIFY_AND_RESET_MOCKS();
918 input_handler_
->MainThreadHasStoppedFlinging();
920 // Start a second gesture fling, this time in the +Y direction with no X.
921 fling_delta
= WebFloatPoint(0, -1000);
922 fling_point
= WebPoint(95, 87);
923 fling_global_point
= WebPoint(32, 71);
924 modifiers
= WebInputEvent::AltKey
;
925 gesture_
= CreateFling(blink::WebGestureDeviceTouchpad
,
930 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
931 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
932 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
933 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
934 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
935 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
937 VERIFY_AND_RESET_MOCKS();
939 // Start the second fling animation at time 30.
940 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
941 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
943 time
= base::TimeTicks() + base::TimeDelta::FromSeconds(30);
946 VERIFY_AND_RESET_MOCKS();
948 // Tick the second fling once normally.
949 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
950 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
951 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
952 EXPECT_CALL(mock_input_handler_
,
954 testing::Property(&gfx::Vector2dF::y
, testing::Gt(0))))
955 .WillOnce(testing::Return(scroll_result_did_scroll_
));
956 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
957 time
+= base::TimeDelta::FromMilliseconds(100);
960 VERIFY_AND_RESET_MOCKS();
962 // Then abort the second fling.
963 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
964 .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD
));
965 EXPECT_CALL(mock_input_handler_
, ScrollBy(testing::_
, testing::_
)).Times(0);
966 EXPECT_CALL(mock_input_handler_
, ScrollEnd()).Times(0);
968 // We should get parameters from the second fling, nothing from the first
969 // fling should "leak".
972 TransferActiveWheelFlingAnimation(testing::AllOf(
973 testing::Field(&WebActiveWheelFlingParameters::delta
,
974 testing::Eq(fling_delta
)),
975 testing::Field(&WebActiveWheelFlingParameters::point
,
976 testing::Eq(fling_point
)),
977 testing::Field(&WebActiveWheelFlingParameters::globalPoint
,
978 testing::Eq(fling_global_point
)),
979 testing::Field(&WebActiveWheelFlingParameters::modifiers
,
980 testing::Eq(modifiers
)),
981 testing::Field(&WebActiveWheelFlingParameters::startTime
,
983 testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll
,
984 testing::Field(&WebSize::height
, testing::Lt(0))))));
985 time
+= base::TimeDelta::FromMilliseconds(100);
988 VERIFY_AND_RESET_MOCKS();
991 TEST_P(InputHandlerProxyTest
, GestureFlingStartedTouchscreen
) {
992 // We shouldn't send any events to the widget for this gesture.
993 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
994 VERIFY_AND_RESET_MOCKS();
996 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
997 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
998 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
999 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1000 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1002 VERIFY_AND_RESET_MOCKS();
1004 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
1005 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1006 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1008 gesture_
.type
= WebInputEvent::GestureFlingStart
;
1009 gesture_
.data
.flingStart
.velocityX
= 10;
1010 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1011 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1013 VERIFY_AND_RESET_MOCKS();
1015 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1017 // Verify that a GestureFlingCancel during an animation cancels it.
1018 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
1019 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1020 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1022 VERIFY_AND_RESET_MOCKS();
1025 TEST_P(InputHandlerProxyTest
, GestureFlingOnMainThreadTouchscreen
) {
1026 // We should send all events to the widget for this gesture.
1027 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
1028 VERIFY_AND_RESET_MOCKS();
1030 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1031 .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD
));
1033 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1034 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1036 VERIFY_AND_RESET_MOCKS();
1038 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin()).Times(0);
1040 gesture_
.type
= WebInputEvent::GestureFlingStart
;
1041 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1042 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1044 VERIFY_AND_RESET_MOCKS();
1046 // Even if we didn't start a fling ourselves, we still need to send the cancel
1047 // event to the widget.
1048 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
1049 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1050 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1053 TEST_P(InputHandlerProxyTest
, GestureFlingIgnoredTouchscreen
) {
1054 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1055 VERIFY_AND_RESET_MOCKS();
1057 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1058 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1060 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1061 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1062 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1064 expected_disposition_
= InputHandlerProxy::DROP_EVENT
;
1065 VERIFY_AND_RESET_MOCKS();
1067 // Flings ignored by the InputHandler should be dropped, signalling the end
1068 // of the touch scroll sequence.
1069 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
1070 .WillOnce(testing::Return(cc::InputHandler::SCROLL_IGNORED
));
1072 gesture_
.type
= WebInputEvent::GestureFlingStart
;
1073 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1074 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1076 VERIFY_AND_RESET_MOCKS();
1078 // Subsequent scrolls should behave normally, even without an intervening
1079 // GestureFlingCancel, as the original GestureFlingStart was dropped.
1080 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1081 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1082 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1083 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1084 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1085 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1087 VERIFY_AND_RESET_MOCKS();
1090 TEST_P(InputHandlerProxyTest
, GestureFlingAnimatesTouchscreen
) {
1091 // We shouldn't send any events to the widget for this gesture.
1092 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1093 VERIFY_AND_RESET_MOCKS();
1095 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1096 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1098 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1099 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1100 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1102 VERIFY_AND_RESET_MOCKS();
1104 // On the fling start, we should schedule an animation but not actually start
1106 WebFloatPoint fling_delta
= WebFloatPoint(100, 0);
1107 WebPoint fling_point
= WebPoint(7, 13);
1108 WebPoint fling_global_point
= WebPoint(17, 23);
1109 // Note that for touchscreen the control modifier is not special.
1110 int modifiers
= WebInputEvent::ControlKey
;
1111 gesture_
= CreateFling(blink::WebGestureDeviceTouchscreen
,
1116 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1117 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
1118 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1119 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1121 VERIFY_AND_RESET_MOCKS();
1122 // The first animate call should let us pick up an animation start time, but
1123 // we shouldn't actually move anywhere just yet. The first frame after the
1124 // fling start will typically include the last scroll from the gesture that
1125 // lead to the scroll (either wheel or gesture scroll), so there should be no
1127 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1128 base::TimeTicks time
= base::TimeTicks() + base::TimeDelta::FromSeconds(10);
1131 VERIFY_AND_RESET_MOCKS();
1133 // The second call should start scrolling in the -X direction.
1134 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1135 EXPECT_CALL(mock_input_handler_
,
1136 ScrollBy(testing::_
,
1137 testing::Property(&gfx::Vector2dF::x
, testing::Lt(0))))
1138 .WillOnce(testing::Return(scroll_result_did_scroll_
));
1139 time
+= base::TimeDelta::FromMilliseconds(100);
1142 VERIFY_AND_RESET_MOCKS();
1144 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1145 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
1146 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1148 VERIFY_AND_RESET_MOCKS();
1151 TEST_P(InputHandlerProxyTest
, GestureFlingWithValidTimestamp
) {
1152 // We shouldn't send any events to the widget for this gesture.
1153 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1154 VERIFY_AND_RESET_MOCKS();
1156 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1157 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1159 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1160 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1161 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1163 VERIFY_AND_RESET_MOCKS();
1165 // On the fling start, we should schedule an animation but not actually start
1167 base::TimeDelta dt
= base::TimeDelta::FromMilliseconds(10);
1168 base::TimeTicks time
= base::TimeTicks() + dt
;
1169 WebFloatPoint fling_delta
= WebFloatPoint(100, 0);
1170 WebPoint fling_point
= WebPoint(7, 13);
1171 WebPoint fling_global_point
= WebPoint(17, 23);
1172 int modifiers
= WebInputEvent::ControlKey
;
1173 gesture_
= CreateFling(time
,
1174 blink::WebGestureDeviceTouchscreen
,
1179 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1180 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
1181 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1182 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1184 VERIFY_AND_RESET_MOCKS();
1185 // With a valid time stamp, the first animate call should skip start time
1186 // initialization and immediately begin scroll update production. This reduces
1187 // the likelihood of a hitch between the scroll preceding the fling and
1188 // the first scroll generated by the fling.
1189 // Scrolling should start in the -X direction.
1190 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1191 EXPECT_CALL(mock_input_handler_
,
1192 ScrollBy(testing::_
,
1193 testing::Property(&gfx::Vector2dF::x
, testing::Lt(0))))
1194 .WillOnce(testing::Return(scroll_result_did_scroll_
));
1198 VERIFY_AND_RESET_MOCKS();
1200 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1201 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
1202 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1204 VERIFY_AND_RESET_MOCKS();
1207 TEST_P(InputHandlerProxyTest
, GestureFlingWithInvalidTimestamp
) {
1208 // We shouldn't send any events to the widget for this gesture.
1209 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1210 VERIFY_AND_RESET_MOCKS();
1212 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1213 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1215 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1216 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1217 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1219 VERIFY_AND_RESET_MOCKS();
1221 // On the fling start, we should schedule an animation but not actually start
1223 base::TimeDelta start_time_offset
= base::TimeDelta::FromMilliseconds(10);
1224 gesture_
.type
= WebInputEvent::GestureFlingStart
;
1225 WebFloatPoint fling_delta
= WebFloatPoint(100, 0);
1226 WebPoint fling_point
= WebPoint(7, 13);
1227 WebPoint fling_global_point
= WebPoint(17, 23);
1228 int modifiers
= WebInputEvent::ControlKey
;
1229 gesture_
.timeStampSeconds
= start_time_offset
.InSecondsF();
1230 gesture_
.data
.flingStart
.velocityX
= fling_delta
.x
;
1231 gesture_
.data
.flingStart
.velocityY
= fling_delta
.y
;
1232 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1233 gesture_
.x
= fling_point
.x
;
1234 gesture_
.y
= fling_point
.y
;
1235 gesture_
.globalX
= fling_global_point
.x
;
1236 gesture_
.globalY
= fling_global_point
.y
;
1237 gesture_
.modifiers
= modifiers
;
1238 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1239 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
1240 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1241 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1243 VERIFY_AND_RESET_MOCKS();
1244 // Event though a time stamp was provided for the fling event, it will be
1245 // ignored as its too far in the past relative to the first animate call's
1247 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1248 base::TimeTicks time
=
1249 base::TimeTicks() + start_time_offset
+ base::TimeDelta::FromSeconds(1);
1252 VERIFY_AND_RESET_MOCKS();
1254 // Further animation ticks should update the fling as usual.
1255 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1256 EXPECT_CALL(mock_input_handler_
,
1257 ScrollBy(testing::_
,
1258 testing::Property(&gfx::Vector2dF::x
, testing::Lt(0))))
1259 .WillOnce(testing::Return(scroll_result_did_scroll_
));
1260 time
+= base::TimeDelta::FromMilliseconds(10);
1263 VERIFY_AND_RESET_MOCKS();
1265 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1266 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
1267 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1269 VERIFY_AND_RESET_MOCKS();
1272 TEST_P(InputHandlerProxyTest
, GestureScrollOnImplThreadFlagClearedAfterFling
) {
1273 // We shouldn't send any events to the widget for this gesture.
1274 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1275 VERIFY_AND_RESET_MOCKS();
1277 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1278 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1280 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1281 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1283 // After sending a GestureScrollBegin, the member variable
1284 // |gesture_scroll_on_impl_thread_| should be true.
1285 EXPECT_TRUE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1287 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1288 VERIFY_AND_RESET_MOCKS();
1290 // On the fling start, we should schedule an animation but not actually start
1292 WebFloatPoint fling_delta
= WebFloatPoint(100, 0);
1293 WebPoint fling_point
= WebPoint(7, 13);
1294 WebPoint fling_global_point
= WebPoint(17, 23);
1295 int modifiers
= WebInputEvent::ControlKey
| WebInputEvent::AltKey
;
1296 gesture_
= CreateFling(blink::WebGestureDeviceTouchscreen
,
1301 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1302 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
1303 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1304 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1306 // |gesture_scroll_on_impl_thread_| should still be true after
1307 // a GestureFlingStart is sent.
1308 EXPECT_TRUE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1310 VERIFY_AND_RESET_MOCKS();
1311 // The first animate call should let us pick up an animation start time, but
1312 // we shouldn't actually move anywhere just yet. The first frame after the
1313 // fling start will typically include the last scroll from the gesture that
1314 // lead to the scroll (either wheel or gesture scroll), so there should be no
1316 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1317 base::TimeTicks time
= base::TimeTicks() + base::TimeDelta::FromSeconds(10);
1320 VERIFY_AND_RESET_MOCKS();
1322 // The second call should start scrolling in the -X direction.
1323 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1324 EXPECT_CALL(mock_input_handler_
,
1325 ScrollBy(testing::_
,
1326 testing::Property(&gfx::Vector2dF::x
, testing::Lt(0))))
1327 .WillOnce(testing::Return(scroll_result_did_scroll_
));
1328 time
+= base::TimeDelta::FromMilliseconds(100);
1331 VERIFY_AND_RESET_MOCKS();
1333 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1334 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
1335 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1337 // |gesture_scroll_on_impl_thread_| should be false once
1338 // the fling has finished (note no GestureScrollEnd has been sent).
1339 EXPECT_TRUE(!input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1341 VERIFY_AND_RESET_MOCKS();
1344 TEST_P(InputHandlerProxyTest
,
1345 BeginScrollWhenGestureScrollOnImplThreadFlagIsSet
) {
1346 // We shouldn't send any events to the widget for this gesture.
1347 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1348 VERIFY_AND_RESET_MOCKS();
1350 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1351 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1353 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1354 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1356 // After sending a GestureScrollBegin, the member variable
1357 // |gesture_scroll_on_impl_thread_| should be true.
1358 EXPECT_TRUE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1360 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1361 VERIFY_AND_RESET_MOCKS();
1363 // On the fling start, we should schedule an animation but not actually start
1365 WebFloatPoint fling_delta
= WebFloatPoint(100, 0);
1366 WebPoint fling_point
= WebPoint(7, 13);
1367 WebPoint fling_global_point
= WebPoint(17, 23);
1368 int modifiers
= WebInputEvent::ControlKey
| WebInputEvent::AltKey
;
1369 gesture_
= CreateFling(blink::WebGestureDeviceTouchscreen
, fling_delta
,
1370 fling_point
, fling_global_point
, modifiers
);
1371 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1372 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
1373 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1374 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1376 // |gesture_scroll_on_impl_thread_| should still be true after
1377 // a GestureFlingStart is sent.
1378 EXPECT_TRUE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1380 VERIFY_AND_RESET_MOCKS();
1382 // gesture_scroll_on_impl_thread_ is still true when this scroll begins. As a
1383 // result, this scroll begin will cancel the previous fling.
1384 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1385 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1386 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1388 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1389 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1391 // After sending a GestureScrollBegin, the member variable
1392 // |gesture_scroll_on_impl_thread_| should be true.
1393 EXPECT_TRUE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1394 VERIFY_AND_RESET_MOCKS();
1397 TEST_P(InputHandlerProxyTest
, GestureFlingStopsAtContentEdge
) {
1398 // We shouldn't send any events to the widget for this gesture.
1399 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1400 VERIFY_AND_RESET_MOCKS();
1402 // On the fling start, we should schedule an animation but not actually start
1404 gesture_
.type
= WebInputEvent::GestureFlingStart
;
1405 WebFloatPoint fling_delta
= WebFloatPoint(100, 100);
1406 gesture_
.data
.flingStart
.velocityX
= fling_delta
.x
;
1407 gesture_
.data
.flingStart
.velocityY
= fling_delta
.y
;
1408 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1409 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1410 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1411 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1412 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1413 VERIFY_AND_RESET_MOCKS();
1415 // The first animate doesn't cause any scrolling.
1416 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1417 base::TimeTicks time
= base::TimeTicks() + base::TimeDelta::FromSeconds(10);
1419 VERIFY_AND_RESET_MOCKS();
1421 // The second animate starts scrolling in the positive X and Y directions.
1422 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1423 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1424 EXPECT_CALL(mock_input_handler_
,
1425 ScrollBy(testing::_
,
1426 testing::Property(&gfx::Vector2dF::y
, testing::Lt(0))))
1427 .WillOnce(testing::Return(scroll_result_did_scroll_
));
1428 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1429 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1430 time
+= base::TimeDelta::FromMilliseconds(100);
1432 VERIFY_AND_RESET_MOCKS();
1434 // The third animate overscrolls in the positive Y direction but scrolls
1436 cc::InputHandlerScrollResult overscroll
;
1437 overscroll
.did_scroll
= true;
1438 overscroll
.did_overscroll_root
= true;
1439 overscroll
.accumulated_root_overscroll
= gfx::Vector2dF(0, 100);
1440 overscroll
.unused_scroll_delta
= gfx::Vector2dF(0, 10);
1441 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1442 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1443 EXPECT_CALL(mock_input_handler_
,
1444 ScrollBy(testing::_
,
1445 testing::Property(&gfx::Vector2dF::y
, testing::Lt(0))))
1446 .WillOnce(testing::Return(overscroll
));
1449 DidOverscroll(testing::AllOf(
1451 &DidOverscrollParams::accumulated_overscroll
,
1452 testing::Eq(overscroll
.accumulated_root_overscroll
)),
1454 &DidOverscrollParams::latest_overscroll_delta
,
1455 testing::Eq(overscroll
.unused_scroll_delta
)),
1457 &DidOverscrollParams::current_fling_velocity
,
1458 testing::Property(&gfx::Vector2dF::y
, testing::Lt(0))))));
1459 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1460 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1461 time
+= base::TimeDelta::FromMilliseconds(100);
1463 VERIFY_AND_RESET_MOCKS();
1465 // The next call to animate will no longer scroll vertically.
1466 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1467 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1468 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1469 EXPECT_CALL(mock_input_handler_
,
1470 ScrollBy(testing::_
,
1471 testing::Property(&gfx::Vector2dF::y
, testing::Eq(0))))
1472 .WillOnce(testing::Return(scroll_result_did_scroll_
));
1473 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1474 time
+= base::TimeDelta::FromMilliseconds(100);
1476 VERIFY_AND_RESET_MOCKS();
1479 TEST_P(InputHandlerProxyTest
, GestureFlingNotCancelledBySmallTimeDelta
) {
1480 // We shouldn't send any events to the widget for this gesture.
1481 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1482 VERIFY_AND_RESET_MOCKS();
1484 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1485 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1487 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1488 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1489 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1491 VERIFY_AND_RESET_MOCKS();
1493 // On the fling start, we should schedule an animation but not actually start
1495 base::TimeDelta dt
= base::TimeDelta::FromMilliseconds(10);
1496 base::TimeTicks time
= base::TimeTicks() + dt
;
1497 WebFloatPoint fling_delta
= WebFloatPoint(100, 0);
1498 WebPoint fling_point
= WebPoint(7, 13);
1499 WebPoint fling_global_point
= WebPoint(17, 23);
1500 int modifiers
= WebInputEvent::ControlKey
;
1501 gesture_
= CreateFling(time
,
1502 blink::WebGestureDeviceTouchscreen
,
1507 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1508 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
1509 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1510 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1512 VERIFY_AND_RESET_MOCKS();
1513 // With an animation timestamp equivalent to the starting timestamp, the
1514 // animation will simply be rescheduled.
1515 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1518 VERIFY_AND_RESET_MOCKS();
1519 EXPECT_TRUE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1521 // A small time delta should not stop the fling, even if the client
1522 // reports no scrolling.
1523 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1524 EXPECT_CALL(mock_input_handler_
,
1525 ScrollBy(testing::_
,
1526 testing::Property(&gfx::Vector2dF::x
, testing::Lt(0))))
1527 .WillOnce(testing::Return(scroll_result_did_not_scroll_
));
1528 time
+= base::TimeDelta::FromMicroseconds(5);
1531 VERIFY_AND_RESET_MOCKS();
1532 EXPECT_TRUE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1534 // A time delta of zero should not stop the fling, and neither should it
1535 // trigger scrolling on the client.
1536 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1539 VERIFY_AND_RESET_MOCKS();
1540 EXPECT_TRUE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1542 // Lack of movement on the client, with a non-trivial scroll delta, should
1543 // terminate the fling.
1544 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1545 EXPECT_CALL(mock_input_handler_
,
1546 ScrollBy(testing::_
,
1547 testing::Property(&gfx::Vector2dF::x
, testing::Lt(1))))
1548 .WillOnce(testing::Return(scroll_result_did_not_scroll_
));
1549 time
+= base::TimeDelta::FromMilliseconds(100);
1552 VERIFY_AND_RESET_MOCKS();
1553 EXPECT_FALSE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1556 TEST_P(InputHandlerProxyTest
, GestureFlingCancelledAfterBothAxesStopScrolling
) {
1557 cc::InputHandlerScrollResult overscroll
;
1558 overscroll
.did_scroll
= true;
1559 overscroll
.did_overscroll_root
= true;
1561 // We shouldn't send any events to the widget for this gesture.
1562 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1563 VERIFY_AND_RESET_MOCKS();
1565 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1566 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1567 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1568 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1569 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1570 VERIFY_AND_RESET_MOCKS();
1572 // On the fling start, we should schedule an animation but not actually start
1574 gesture_
.type
= WebInputEvent::GestureFlingStart
;
1575 WebFloatPoint fling_delta
= WebFloatPoint(100, 100);
1576 gesture_
.data
.flingStart
.velocityX
= fling_delta
.x
;
1577 gesture_
.data
.flingStart
.velocityY
= fling_delta
.y
;
1578 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
1579 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1580 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1581 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1582 VERIFY_AND_RESET_MOCKS();
1584 // The first animate doesn't cause any scrolling.
1585 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1586 base::TimeTicks time
= base::TimeTicks() + base::TimeDelta::FromSeconds(10);
1588 VERIFY_AND_RESET_MOCKS();
1590 // The second animate starts scrolling in the positive X and Y directions.
1591 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1592 EXPECT_CALL(mock_input_handler_
,
1593 ScrollBy(testing::_
,
1594 testing::Property(&gfx::Vector2dF::y
, testing::Lt(0))))
1595 .WillOnce(testing::Return(scroll_result_did_scroll_
));
1596 time
+= base::TimeDelta::FromMilliseconds(10);
1598 VERIFY_AND_RESET_MOCKS();
1600 // The third animate hits the bottom content edge.
1601 overscroll
.accumulated_root_overscroll
= gfx::Vector2dF(0, 100);
1602 overscroll
.unused_scroll_delta
= gfx::Vector2dF(0, 100);
1603 EXPECT_CALL(mock_input_handler_
,
1604 ScrollBy(testing::_
,
1605 testing::Property(&gfx::Vector2dF::y
, testing::Lt(0))))
1606 .WillOnce(testing::Return(overscroll
));
1609 DidOverscroll(testing::AllOf(
1611 &DidOverscrollParams::accumulated_overscroll
,
1612 testing::Eq(overscroll
.accumulated_root_overscroll
)),
1614 &DidOverscrollParams::latest_overscroll_delta
,
1615 testing::Eq(overscroll
.unused_scroll_delta
)),
1617 &DidOverscrollParams::current_fling_velocity
,
1618 testing::Property(&gfx::Vector2dF::y
, testing::Lt(0))))));
1619 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1620 time
+= base::TimeDelta::FromMilliseconds(10);
1622 VERIFY_AND_RESET_MOCKS();
1624 // The next call to animate will no longer scroll vertically.
1625 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1626 EXPECT_CALL(mock_input_handler_
,
1627 ScrollBy(testing::_
,
1628 testing::Property(&gfx::Vector2dF::y
, testing::Eq(0))))
1629 .WillOnce(testing::Return(scroll_result_did_scroll_
));
1630 time
+= base::TimeDelta::FromMilliseconds(10);
1632 VERIFY_AND_RESET_MOCKS();
1634 // The next call will hit the right edge.
1635 overscroll
.accumulated_root_overscroll
= gfx::Vector2dF(100, 100);
1636 overscroll
.unused_scroll_delta
= gfx::Vector2dF(100, 0);
1637 EXPECT_CALL(mock_input_handler_
,
1638 ScrollBy(testing::_
,
1639 testing::Property(&gfx::Vector2dF::x
, testing::Lt(0))))
1640 .WillOnce(testing::Return(overscroll
));
1643 DidOverscroll(testing::AllOf(
1645 &DidOverscrollParams::accumulated_overscroll
,
1646 testing::Eq(overscroll
.accumulated_root_overscroll
)),
1648 &DidOverscrollParams::latest_overscroll_delta
,
1649 testing::Eq(overscroll
.unused_scroll_delta
)),
1651 &DidOverscrollParams::current_fling_velocity
,
1652 testing::Property(&gfx::Vector2dF::x
, testing::Lt(0))))));
1653 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1654 time
+= base::TimeDelta::FromMilliseconds(10);
1656 VERIFY_AND_RESET_MOCKS();
1658 // The next call to animate will no longer scroll horizontally or vertically,
1659 // and the fling should be cancelled.
1660 EXPECT_SET_NEEDS_ANIMATE_INPUT(0);
1661 EXPECT_CALL(mock_input_handler_
, ScrollBy(testing::_
, testing::_
)).Times(0);
1662 time
+= base::TimeDelta::FromMilliseconds(10);
1664 VERIFY_AND_RESET_MOCKS();
1665 EXPECT_FALSE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1668 TEST_P(InputHandlerProxyTest
, MultiTouchPointHitTestNegative
) {
1669 // None of the three touch points fall in the touch region. So the event
1670 // should be dropped.
1671 expected_disposition_
= InputHandlerProxy::DROP_EVENT
;
1672 VERIFY_AND_RESET_MOCKS();
1674 EXPECT_CALL(mock_input_handler_
,
1675 DoTouchEventsBlockScrollAt(
1676 testing::Property(&gfx::Point::x
, testing::Gt(0))))
1677 .WillOnce(testing::Return(false));
1678 EXPECT_CALL(mock_input_handler_
,
1679 DoTouchEventsBlockScrollAt(
1680 testing::Property(&gfx::Point::x
, testing::Lt(0))))
1681 .WillOnce(testing::Return(false));
1683 WebTouchEvent touch
;
1684 touch
.type
= WebInputEvent::TouchStart
;
1686 touch
.touchesLength
= 3;
1687 touch
.touches
[0] = CreateWebTouchPoint(WebTouchPoint::StateStationary
, 0, 0);
1688 touch
.touches
[1] = CreateWebTouchPoint(WebTouchPoint::StatePressed
, 10, 10);
1689 touch
.touches
[2] = CreateWebTouchPoint(WebTouchPoint::StatePressed
, -10, 10);
1690 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(touch
));
1692 VERIFY_AND_RESET_MOCKS();
1695 TEST_P(InputHandlerProxyTest
, MultiTouchPointHitTestPositive
) {
1696 // One of the touch points is on a touch-region. So the event should be sent
1697 // to the main thread.
1698 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
1699 VERIFY_AND_RESET_MOCKS();
1701 EXPECT_CALL(mock_input_handler_
,
1702 DoTouchEventsBlockScrollAt(
1703 testing::Property(&gfx::Point::x
, testing::Eq(0))))
1704 .WillOnce(testing::Return(false));
1705 EXPECT_CALL(mock_input_handler_
,
1706 DoTouchEventsBlockScrollAt(
1707 testing::Property(&gfx::Point::x
, testing::Gt(0))))
1708 .WillOnce(testing::Return(true));
1709 // Since the second touch point hits a touch-region, there should be no
1710 // hit-testing for the third touch point.
1712 WebTouchEvent touch
;
1713 touch
.type
= WebInputEvent::TouchStart
;
1715 touch
.touchesLength
= 3;
1716 touch
.touches
[0] = CreateWebTouchPoint(WebTouchPoint::StatePressed
, 0, 0);
1717 touch
.touches
[1] = CreateWebTouchPoint(WebTouchPoint::StatePressed
, 10, 10);
1718 touch
.touches
[2] = CreateWebTouchPoint(WebTouchPoint::StatePressed
, -10, 10);
1719 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(touch
));
1721 VERIFY_AND_RESET_MOCKS();
1724 TEST_P(InputHandlerProxyTest
, GestureFlingCancelledByKeyboardEvent
) {
1725 // We shouldn't send any events to the widget for this gesture.
1726 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1727 VERIFY_AND_RESET_MOCKS();
1729 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1730 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1731 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1732 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1733 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1734 EXPECT_TRUE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1735 VERIFY_AND_RESET_MOCKS();
1737 // Keyboard events received during a scroll should have no effect.
1738 WebKeyboardEvent key_event
;
1739 key_event
.type
= WebInputEvent::KeyDown
;
1740 EXPECT_EQ(InputHandlerProxy::DID_NOT_HANDLE
,
1741 input_handler_
->HandleInputEvent(key_event
));
1742 EXPECT_TRUE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1743 VERIFY_AND_RESET_MOCKS();
1745 // On the fling start, animation should be scheduled, but no scrolling occurs.
1746 gesture_
.type
= WebInputEvent::GestureFlingStart
;
1747 WebFloatPoint fling_delta
= WebFloatPoint(100, 100);
1748 gesture_
.data
.flingStart
.velocityX
= fling_delta
.x
;
1749 gesture_
.data
.flingStart
.velocityY
= fling_delta
.y
;
1750 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
1751 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1752 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1753 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1754 EXPECT_TRUE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1755 VERIFY_AND_RESET_MOCKS();
1757 // Keyboard events received during a fling should cancel the active fling.
1758 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1759 EXPECT_EQ(InputHandlerProxy::DID_NOT_HANDLE
,
1760 input_handler_
->HandleInputEvent(key_event
));
1761 EXPECT_FALSE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1762 VERIFY_AND_RESET_MOCKS();
1764 // The call to animate should have no effect, as the fling was cancelled.
1765 base::TimeTicks time
= base::TimeTicks() + base::TimeDelta::FromSeconds(10);
1767 VERIFY_AND_RESET_MOCKS();
1769 // A fling cancel should be dropped, as there is nothing to cancel.
1770 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
1771 EXPECT_EQ(InputHandlerProxy::DROP_EVENT
,
1772 input_handler_
->HandleInputEvent(gesture_
));
1773 EXPECT_FALSE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1776 TEST_P(InputHandlerProxyTest
, GestureFlingWithNegativeTimeDelta
) {
1777 // We shouldn't send any events to the widget for this gesture.
1778 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1779 VERIFY_AND_RESET_MOCKS();
1781 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1782 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1784 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1785 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1786 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1788 VERIFY_AND_RESET_MOCKS();
1790 // On the fling start, we should schedule an animation but not actually start
1792 base::TimeDelta dt
= base::TimeDelta::FromMilliseconds(10);
1793 base::TimeTicks time
= base::TimeTicks() + dt
;
1794 WebFloatPoint fling_delta
= WebFloatPoint(100, 0);
1795 WebPoint fling_point
= WebPoint(7, 13);
1796 WebPoint fling_global_point
= WebPoint(17, 23);
1797 int modifiers
= WebInputEvent::ControlKey
;
1798 gesture_
= CreateFling(time
,
1799 blink::WebGestureDeviceTouchscreen
,
1804 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1805 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
1806 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1807 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1809 VERIFY_AND_RESET_MOCKS();
1811 // If we get a negative time delta, that is, the Animation tick time happens
1812 // before the fling's start time then we should *not* try scrolling and
1813 // instead reset the fling start time.
1814 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1815 EXPECT_CALL(mock_input_handler_
,
1816 ScrollBy(testing::_
,
1817 testing::_
)).Times(0);
1818 time
-= base::TimeDelta::FromMilliseconds(5);
1821 VERIFY_AND_RESET_MOCKS();
1823 // The first call should have reset the start time so subsequent calls should
1824 // generate scroll events.
1825 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1826 EXPECT_CALL(mock_input_handler_
,
1827 ScrollBy(testing::_
,
1828 testing::Property(&gfx::Vector2dF::x
, testing::Lt(0))))
1829 .WillOnce(testing::Return(scroll_result_did_scroll_
));
1831 Animate(time
+ base::TimeDelta::FromMilliseconds(1));
1833 VERIFY_AND_RESET_MOCKS();
1835 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1836 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
1837 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1839 VERIFY_AND_RESET_MOCKS();
1842 TEST_P(InputHandlerProxyTest
, FlingBoost
) {
1843 base::TimeDelta dt
= base::TimeDelta::FromMilliseconds(10);
1844 base::TimeTicks time
= base::TimeTicks() + dt
;
1845 base::TimeTicks last_animate_time
= time
;
1846 WebFloatPoint fling_delta
= WebFloatPoint(1000, 0);
1847 WebPoint fling_point
= WebPoint(7, 13);
1849 time
, blink::WebGestureDeviceTouchscreen
, fling_delta
, fling_point
);
1851 // Now cancel the fling. The fling cancellation should be deferred to allow
1852 // fling boosting events to arrive.
1856 // The GestureScrollBegin should be swallowed by the fling if it hits the same
1858 EXPECT_CALL(mock_input_handler_
,
1859 IsCurrentlyScrollingLayerAt(testing::_
, testing::_
))
1860 .WillOnce(testing::Return(true));
1863 gesture_
.timeStampSeconds
= InSecondsF(time
);
1864 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1865 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1867 VERIFY_AND_RESET_MOCKS();
1869 // Animate calls within the deferred cancellation window should continue.
1871 float expected_delta
=
1872 (time
- last_animate_time
).InSecondsF() * -fling_delta
.x
;
1873 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1874 EXPECT_CALL(mock_input_handler_
,
1875 ScrollBy(testing::_
,
1876 testing::Property(&gfx::Vector2dF::x
,
1877 testing::Eq(expected_delta
))))
1878 .WillOnce(testing::Return(scroll_result_did_scroll_
));
1880 last_animate_time
= time
;
1882 VERIFY_AND_RESET_MOCKS();
1884 // GestureScrollUpdates in the same direction and at sufficient speed should
1885 // be swallowed by the fling.
1887 gesture_
.timeStampSeconds
= InSecondsF(time
);
1888 gesture_
.type
= WebInputEvent::GestureScrollUpdate
;
1889 gesture_
.data
.scrollUpdate
.deltaX
= fling_delta
.x
;
1890 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1892 VERIFY_AND_RESET_MOCKS();
1894 // Animate calls within the deferred cancellation window should continue.
1896 expected_delta
= (time
- last_animate_time
).InSecondsF() * -fling_delta
.x
;
1897 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1898 EXPECT_CALL(mock_input_handler_
,
1899 ScrollBy(testing::_
,
1900 testing::Property(&gfx::Vector2dF::x
,
1901 testing::Eq(expected_delta
))))
1902 .WillOnce(testing::Return(scroll_result_did_scroll_
));
1904 last_animate_time
= time
;
1906 VERIFY_AND_RESET_MOCKS();
1908 // GestureFlingStart in the same direction and at sufficient speed should
1909 // boost the active fling.
1911 gesture_
= CreateFling(time
,
1912 blink::WebGestureDeviceTouchscreen
,
1917 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1918 VERIFY_AND_RESET_MOCKS();
1921 // Note we get *2x* as much delta because 2 flings have combined.
1922 expected_delta
= 2 * (time
- last_animate_time
).InSecondsF() * -fling_delta
.x
;
1923 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1924 EXPECT_CALL(mock_input_handler_
,
1925 ScrollBy(testing::_
,
1926 testing::Property(&gfx::Vector2dF::x
,
1927 testing::Eq(expected_delta
))))
1928 .WillOnce(testing::Return(scroll_result_did_scroll_
));
1930 last_animate_time
= time
;
1932 VERIFY_AND_RESET_MOCKS();
1934 // Repeated GestureFlingStarts should accumulate.
1937 gesture_
= CreateFling(time
,
1938 blink::WebGestureDeviceTouchscreen
,
1943 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1944 VERIFY_AND_RESET_MOCKS();
1947 // Note we get *3x* as much delta because 3 flings have combined.
1948 expected_delta
= 3 * (time
- last_animate_time
).InSecondsF() * -fling_delta
.x
;
1949 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1950 EXPECT_CALL(mock_input_handler_
,
1951 ScrollBy(testing::_
,
1952 testing::Property(&gfx::Vector2dF::x
,
1953 testing::Eq(expected_delta
))))
1954 .WillOnce(testing::Return(scroll_result_did_scroll_
));
1956 last_animate_time
= time
;
1958 VERIFY_AND_RESET_MOCKS();
1960 // GestureFlingCancel should terminate the fling if no boosting gestures are
1961 // received within the timeout window.
1964 gesture_
.timeStampSeconds
= InSecondsF(time
);
1965 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
1966 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1968 VERIFY_AND_RESET_MOCKS();
1970 time
+= base::TimeDelta::FromMilliseconds(100);
1971 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1974 VERIFY_AND_RESET_MOCKS();
1977 TEST_P(InputHandlerProxyTest
, NoFlingBoostIfScrollTargetsDifferentLayer
) {
1978 base::TimeDelta dt
= base::TimeDelta::FromMilliseconds(10);
1979 base::TimeTicks time
= base::TimeTicks() + dt
;
1980 WebFloatPoint fling_delta
= WebFloatPoint(1000, 0);
1981 WebPoint fling_point
= WebPoint(7, 13);
1983 time
, blink::WebGestureDeviceTouchscreen
, fling_delta
, fling_point
);
1985 // Cancel the fling. The fling cancellation should be deferred to allow
1986 // fling boosting events to arrive.
1990 // If the GestureScrollBegin targets a different layer, the fling should be
1991 // cancelled and the scroll should be handled as usual.
1992 EXPECT_CALL(mock_input_handler_
,
1993 IsCurrentlyScrollingLayerAt(testing::_
, testing::_
))
1994 .WillOnce(testing::Return(false));
1995 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1996 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1997 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
2000 gesture_
.timeStampSeconds
= InSecondsF(time
);
2001 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
2002 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
2004 VERIFY_AND_RESET_MOCKS();
2007 TEST_P(InputHandlerProxyTest
, NoFlingBoostIfScrollDelayed
) {
2008 base::TimeDelta dt
= base::TimeDelta::FromMilliseconds(10);
2009 base::TimeTicks time
= base::TimeTicks() + dt
;
2010 WebFloatPoint fling_delta
= WebFloatPoint(1000, 0);
2011 WebPoint fling_point
= WebPoint(7, 13);
2013 time
, blink::WebGestureDeviceTouchscreen
, fling_delta
, fling_point
);
2015 // Cancel the fling. The fling cancellation should be deferred to allow
2016 // fling boosting events to arrive.
2020 // The GestureScrollBegin should be swallowed by the fling if it hits the same
2022 EXPECT_CALL(mock_input_handler_
,
2023 IsCurrentlyScrollingLayerAt(testing::_
, testing::_
))
2024 .WillOnce(testing::Return(true));
2027 gesture_
.timeStampSeconds
= InSecondsF(time
);
2028 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
2029 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
2031 VERIFY_AND_RESET_MOCKS();
2033 // If no GestureScrollUpdate or GestureFlingStart is received within the
2034 // timeout window, the fling should be cancelled and scrolling should resume.
2035 time
+= base::TimeDelta::FromMilliseconds(100);
2036 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
2037 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
2038 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
2041 VERIFY_AND_RESET_MOCKS();
2044 TEST_P(InputHandlerProxyTest
, NoFlingBoostIfNotAnimated
) {
2045 base::TimeDelta dt
= base::TimeDelta::FromMilliseconds(10);
2046 base::TimeTicks time
= base::TimeTicks() + dt
;
2047 WebFloatPoint fling_delta
= WebFloatPoint(1000, 0);
2048 WebPoint fling_point
= WebPoint(7, 13);
2050 time
, blink::WebGestureDeviceTouchscreen
, fling_delta
, fling_point
);
2052 // Animate fling once.
2054 EXPECT_CALL(mock_input_handler_
, ScrollBy(testing::_
, testing::_
))
2055 .WillOnce(testing::Return(scroll_result_did_scroll_
));
2056 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
2059 // Cancel the fling after long delay of no animate. The fling cancellation
2060 // should be deferred to allow fling boosting events to arrive.
2061 time
+= base::TimeDelta::FromMilliseconds(100);
2064 // The GestureScrollBegin should be swallowed by the fling if it hits the same
2066 EXPECT_CALL(mock_input_handler_
,
2067 IsCurrentlyScrollingLayerAt(testing::_
, testing::_
))
2068 .WillOnce(testing::Return(true));
2071 gesture_
.timeStampSeconds
= InSecondsF(time
);
2072 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
2073 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
2075 VERIFY_AND_RESET_MOCKS();
2077 // Should exit scroll bosting on GestureScrollUpdate due to long delay
2078 // since last animate. Cancel old fling and start new scroll.
2079 gesture_
.type
= WebInputEvent::GestureScrollUpdate
;
2080 gesture_
.data
.scrollUpdate
.deltaY
= -40;
2081 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
2082 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
2083 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
2084 EXPECT_CALL(mock_input_handler_
, ScrollBy(testing::_
, testing::_
))
2085 .WillOnce(testing::Return(scroll_result_did_scroll_
));
2086 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
2088 VERIFY_AND_RESET_MOCKS();
2091 TEST_P(InputHandlerProxyTest
, NoFlingBoostIfFlingInDifferentDirection
) {
2092 base::TimeDelta dt
= base::TimeDelta::FromMilliseconds(10);
2093 base::TimeTicks time
= base::TimeTicks() + dt
;
2094 WebFloatPoint fling_delta
= WebFloatPoint(1000, 0);
2095 WebPoint fling_point
= WebPoint(7, 13);
2097 time
, blink::WebGestureDeviceTouchscreen
, fling_delta
, fling_point
);
2099 // Cancel the fling. The fling cancellation should be deferred to allow
2100 // fling boosting events to arrive.
2104 // If the new fling is orthogonal to the existing fling, no boosting should
2105 // take place, with the new fling replacing the old.
2106 WebFloatPoint orthogonal_fling_delta
=
2107 WebFloatPoint(fling_delta
.y
, -fling_delta
.x
);
2108 gesture_
= CreateFling(time
,
2109 blink::WebGestureDeviceTouchscreen
,
2110 orthogonal_fling_delta
,
2114 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
2116 VERIFY_AND_RESET_MOCKS();
2118 // Note that the new fling delta uses the orthogonal, unboosted fling
2121 float expected_delta
= dt
.InSecondsF() * -orthogonal_fling_delta
.y
;
2122 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
2123 EXPECT_CALL(mock_input_handler_
,
2124 ScrollBy(testing::_
,
2125 testing::Property(&gfx::Vector2dF::y
,
2126 testing::Eq(expected_delta
))))
2127 .WillOnce(testing::Return(scroll_result_did_scroll_
));
2130 VERIFY_AND_RESET_MOCKS();
2133 TEST_P(InputHandlerProxyTest
, NoFlingBoostIfScrollInDifferentDirection
) {
2134 base::TimeDelta dt
= base::TimeDelta::FromMilliseconds(10);
2135 base::TimeTicks time
= base::TimeTicks() + dt
;
2136 WebFloatPoint fling_delta
= WebFloatPoint(1000, 0);
2137 WebPoint fling_point
= WebPoint(7, 13);
2139 time
, blink::WebGestureDeviceTouchscreen
, fling_delta
, fling_point
);
2141 // Cancel the fling. The fling cancellation should be deferred to allow
2142 // fling boosting events to arrive.
2146 // The GestureScrollBegin should be swallowed by the fling if it hits the same
2148 EXPECT_CALL(mock_input_handler_
,
2149 IsCurrentlyScrollingLayerAt(testing::_
, testing::_
))
2150 .WillOnce(testing::Return(true));
2153 gesture_
.timeStampSeconds
= InSecondsF(time
);
2154 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
2155 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
2157 VERIFY_AND_RESET_MOCKS();
2159 // If the GestureScrollUpdate is in a different direction than the fling,
2160 // the fling should be cancelled and scrolling should resume.
2162 gesture_
.timeStampSeconds
= InSecondsF(time
);
2163 gesture_
.type
= WebInputEvent::GestureScrollUpdate
;
2164 gesture_
.data
.scrollUpdate
.deltaX
= -fling_delta
.x
;
2165 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
2166 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
2167 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
2168 EXPECT_CALL(mock_input_handler_
,
2169 ScrollBy(testing::_
,
2170 testing::Property(&gfx::Vector2dF::x
,
2171 testing::Eq(fling_delta
.x
))))
2172 .WillOnce(testing::Return(scroll_result_did_scroll_
));
2173 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
2175 VERIFY_AND_RESET_MOCKS();
2178 TEST_P(InputHandlerProxyTest
, NoFlingBoostIfFlingTooSlow
) {
2179 base::TimeDelta dt
= base::TimeDelta::FromMilliseconds(10);
2180 base::TimeTicks time
= base::TimeTicks() + dt
;
2181 WebFloatPoint fling_delta
= WebFloatPoint(1000, 0);
2182 WebPoint fling_point
= WebPoint(7, 13);
2184 time
, blink::WebGestureDeviceTouchscreen
, fling_delta
, fling_point
);
2186 // Cancel the fling. The fling cancellation should be deferred to allow
2187 // fling boosting events to arrive.
2191 // If the new fling is too slow, no boosting should take place, with the new
2192 // fling replacing the old.
2193 WebFloatPoint small_fling_delta
= WebFloatPoint(100, 0);
2194 gesture_
= CreateFling(time
,
2195 blink::WebGestureDeviceTouchscreen
,
2200 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
2202 VERIFY_AND_RESET_MOCKS();
2204 // Note that the new fling delta uses the *slow*, unboosted fling velocity.
2206 float expected_delta
= dt
.InSecondsF() * -small_fling_delta
.x
;
2207 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
2208 EXPECT_CALL(mock_input_handler_
,
2209 ScrollBy(testing::_
,
2210 testing::Property(&gfx::Vector2dF::x
,
2211 testing::Eq(expected_delta
))))
2212 .WillOnce(testing::Return(scroll_result_did_scroll_
));
2215 VERIFY_AND_RESET_MOCKS();
2218 TEST_P(InputHandlerProxyTest
, NoFlingBoostIfPreventBoostingFlagIsSet
) {
2219 base::TimeDelta dt
= base::TimeDelta::FromMilliseconds(10);
2220 base::TimeTicks time
= base::TimeTicks() + dt
;
2221 WebFloatPoint fling_delta
= WebFloatPoint(1000, 0);
2222 WebPoint fling_point
= WebPoint(7, 13);
2225 time
, blink::WebGestureDeviceTouchscreen
, fling_delta
, fling_point
);
2227 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
2229 // Cancel the fling. The fling cancellation should not be deferred because of
2230 // prevent boosting flag set.
2231 gesture_
.data
.flingCancel
.preventBoosting
= true;
2235 // VERIFY_AND_RESET_MOCKS already called by CancelFling
2238 TEST_P(InputHandlerProxyTest
, FlingBoostTerminatedDuringScrollSequence
) {
2239 base::TimeDelta dt
= base::TimeDelta::FromMilliseconds(10);
2240 base::TimeTicks time
= base::TimeTicks() + dt
;
2241 base::TimeTicks last_animate_time
= time
;
2242 WebFloatPoint fling_delta
= WebFloatPoint(1000, 0);
2243 WebPoint fling_point
= WebPoint(7, 13);
2245 time
, blink::WebGestureDeviceTouchscreen
, fling_delta
, fling_point
);
2247 // Now cancel the fling. The fling cancellation should be deferred to allow
2248 // fling boosting events to arrive.
2252 // The GestureScrollBegin should be swallowed by the fling.
2254 gesture_
.timeStampSeconds
= InSecondsF(time
);
2255 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
2256 EXPECT_CALL(mock_input_handler_
,
2257 IsCurrentlyScrollingLayerAt(testing::_
, testing::_
))
2258 .WillOnce(testing::Return(true));
2259 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
2261 VERIFY_AND_RESET_MOCKS();
2263 // Now animate the fling to completion (in this case, the fling should
2264 // terminate because the input handler reports a failed scroll). As the fling
2265 // was cancelled during an active scroll sequence, a synthetic
2266 // GestureScrollBegin should be processed, resuming the scroll.
2268 float expected_delta
=
2269 (time
- last_animate_time
).InSecondsF() * -fling_delta
.x
;
2270 EXPECT_CALL(mock_input_handler_
,
2271 ScrollBy(testing::_
,
2272 testing::Property(&gfx::Vector2dF::x
,
2273 testing::Eq(expected_delta
))))
2274 .WillOnce(testing::Return(scroll_result_did_not_scroll_
));
2275 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
2276 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
2277 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
2280 VERIFY_AND_RESET_MOCKS();
2282 // Subsequent GestureScrollUpdates after the cancelled, boosted fling should
2283 // cause scrolling as usual.
2285 expected_delta
= 7.3f
;
2286 gesture_
.timeStampSeconds
= InSecondsF(time
);
2287 gesture_
.type
= WebInputEvent::GestureScrollUpdate
;
2288 gesture_
.data
.scrollUpdate
.deltaX
= -expected_delta
;
2289 EXPECT_CALL(mock_input_handler_
,
2290 ScrollBy(testing::_
,
2291 testing::Property(&gfx::Vector2dF::x
,
2292 testing::Eq(expected_delta
))))
2293 .WillOnce(testing::Return(scroll_result_did_scroll_
));
2294 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
2296 VERIFY_AND_RESET_MOCKS();
2298 // GestureScrollEnd should terminate the resumed scroll properly.
2300 gesture_
.timeStampSeconds
= InSecondsF(time
);
2301 gesture_
.type
= WebInputEvent::GestureScrollEnd
;
2302 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
2303 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
2305 VERIFY_AND_RESET_MOCKS();
2308 TEST_P(InputHandlerProxyTest
, DidReceiveInputEvent_ForFling
) {
2309 testing::StrictMock
<MockInputHandlerProxyClientWithDidAnimateForInput
>
2311 input_handler_
.reset(
2312 new content::InputHandlerProxy(&mock_input_handler_
, &mock_client
));
2313 if (install_synchronous_handler_
) {
2314 input_handler_
->SetOnlySynchronouslyAnimateRootFlings(
2315 &mock_synchronous_input_handler_
);
2317 mock_input_handler_
.set_is_scrolling_root(synchronous_root_scroll_
);
2319 gesture_
.type
= WebInputEvent::GestureFlingStart
;
2320 WebFloatPoint fling_delta
= WebFloatPoint(100, 100);
2321 gesture_
.data
.flingStart
.velocityX
= fling_delta
.x
;
2322 gesture_
.data
.flingStart
.velocityY
= fling_delta
.y
;
2323 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
2324 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
2325 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
2326 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
2327 EXPECT_EQ(InputHandlerProxy::DID_HANDLE
,
2328 input_handler_
->HandleInputEvent(gesture_
));
2329 VERIFY_AND_RESET_MOCKS();
2331 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
2332 EXPECT_CALL(mock_client
, DidAnimateForInput());
2333 base::TimeTicks time
= base::TimeTicks() + base::TimeDelta::FromSeconds(10);
2336 VERIFY_AND_RESET_MOCKS();
2339 INSTANTIATE_TEST_CASE_P(AnimateInput
,
2340 InputHandlerProxyTest
,
2341 testing::ValuesIn(test_types
));
2344 } // namespace content