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"
20 #include "ui/gfx/geometry/scroll_offset.h"
21 #include "ui/gfx/geometry/size_f.h"
23 using blink::WebActiveWheelFlingParameters
;
24 using blink::WebFloatPoint
;
25 using blink::WebFloatSize
;
26 using blink::WebGestureDevice
;
27 using blink::WebGestureEvent
;
28 using blink::WebInputEvent
;
29 using blink::WebKeyboardEvent
;
30 using blink::WebMouseWheelEvent
;
31 using blink::WebPoint
;
33 using blink::WebTouchEvent
;
34 using blink::WebTouchPoint
;
40 enum InputHandlerProxyTestType
{
41 ROOT_SCROLL_NORMAL_HANDLER
,
42 ROOT_SCROLL_SYNCHRONOUS_HANDLER
,
43 CHILD_SCROLL_NORMAL_HANDLER
,
44 CHILD_SCROLL_SYNCHRONOUS_HANDLER
,
46 static const InputHandlerProxyTestType test_types
[] = {
47 ROOT_SCROLL_NORMAL_HANDLER
, ROOT_SCROLL_SYNCHRONOUS_HANDLER
,
48 CHILD_SCROLL_NORMAL_HANDLER
, CHILD_SCROLL_SYNCHRONOUS_HANDLER
};
50 double InSecondsF(const base::TimeTicks
& time
) {
51 return (time
- base::TimeTicks()).InSecondsF();
54 WebGestureEvent
CreateFling(base::TimeTicks timestamp
,
55 WebGestureDevice source_device
,
56 WebFloatPoint velocity
,
58 WebPoint global_point
,
60 WebGestureEvent fling
;
61 fling
.type
= WebInputEvent::GestureFlingStart
;
62 fling
.sourceDevice
= source_device
;
63 fling
.timeStampSeconds
= (timestamp
- base::TimeTicks()).InSecondsF();
64 fling
.data
.flingStart
.velocityX
= velocity
.x
;
65 fling
.data
.flingStart
.velocityY
= velocity
.y
;
68 fling
.globalX
= global_point
.x
;
69 fling
.globalY
= global_point
.y
;
70 fling
.modifiers
= modifiers
;
74 WebGestureEvent
CreateFling(WebGestureDevice source_device
,
75 WebFloatPoint velocity
,
77 WebPoint global_point
,
79 return CreateFling(base::TimeTicks(),
87 class MockInputHandler
: public cc::InputHandler
{
90 ~MockInputHandler() override
{}
92 MOCK_METHOD0(PinchGestureBegin
, void());
93 MOCK_METHOD2(PinchGestureUpdate
,
94 void(float magnify_delta
, const gfx::Point
& anchor
));
95 MOCK_METHOD0(PinchGestureEnd
, void());
97 MOCK_METHOD0(SetNeedsAnimateInput
, void());
99 MOCK_METHOD2(ScrollBegin
,
100 ScrollStatus(const gfx::Point
& viewport_point
,
101 cc::InputHandler::ScrollInputType type
));
102 MOCK_METHOD1(RootScrollBegin
,
103 ScrollStatus(cc::InputHandler::ScrollInputType type
));
104 MOCK_METHOD2(ScrollAnimated
,
105 ScrollStatus(const gfx::Point
& viewport_point
,
106 const gfx::Vector2dF
& scroll_delta
));
107 MOCK_METHOD2(ScrollBy
,
108 cc::InputHandlerScrollResult(
109 const gfx::Point
& viewport_point
,
110 const gfx::Vector2dF
& scroll_delta
));
111 MOCK_METHOD2(ScrollVerticallyByPage
,
112 bool(const gfx::Point
& viewport_point
,
113 cc::ScrollDirection direction
));
114 MOCK_METHOD0(ScrollEnd
, void());
115 MOCK_METHOD0(FlingScrollBegin
, cc::InputHandler::ScrollStatus());
117 scoped_ptr
<cc::SwapPromiseMonitor
> CreateLatencyInfoSwapPromiseMonitor(
118 ui::LatencyInfo
* latency
) override
{
119 return scoped_ptr
<cc::SwapPromiseMonitor
>();
122 cc::ScrollElasticityHelper
* CreateScrollElasticityHelper() override
{
126 void BindToClient(cc::InputHandlerClient
* client
) override
{}
128 void MouseMoveAt(const gfx::Point
& mouse_position
) override
{}
130 MOCK_CONST_METHOD2(IsCurrentlyScrollingLayerAt
,
131 bool(const gfx::Point
& point
,
132 cc::InputHandler::ScrollInputType type
));
134 MOCK_METHOD1(HaveWheelEventHandlersAt
, bool(const gfx::Point
& point
));
135 MOCK_METHOD1(DoTouchEventsBlockScrollAt
, bool(const gfx::Point
& point
));
137 MOCK_METHOD0(RequestUpdateForSynchronousInputHandler
, void());
138 MOCK_METHOD1(SetSynchronousInputHandlerRootScrollOffset
,
139 void(const gfx::ScrollOffset
& root_offset
));
141 bool IsCurrentlyScrollingRoot() const override
{ return is_scrolling_root_
; }
142 void set_is_scrolling_root(bool is
) { is_scrolling_root_
= is
; }
145 bool is_scrolling_root_
= true;
146 DISALLOW_COPY_AND_ASSIGN(MockInputHandler
);
149 class MockSynchronousInputHandler
: public content::SynchronousInputHandler
{
151 MOCK_METHOD0(SetNeedsSynchronousAnimateInput
, void());
152 MOCK_METHOD6(UpdateRootLayerState
,
153 void(const gfx::ScrollOffset
& total_scroll_offset
,
154 const gfx::ScrollOffset
& max_scroll_offset
,
155 const gfx::SizeF
& scrollable_size
,
156 float page_scale_factor
,
157 float min_page_scale_factor
,
158 float max_page_scale_factor
));
161 // A simple WebGestureCurve implementation that flings at a constant velocity
163 class FakeWebGestureCurve
: public blink::WebGestureCurve
{
165 FakeWebGestureCurve(const blink::WebFloatSize
& velocity
,
166 const blink::WebFloatSize
& cumulative_scroll
)
167 : velocity_(velocity
), cumulative_scroll_(cumulative_scroll
) {}
169 virtual ~FakeWebGestureCurve() {}
171 // Returns false if curve has finished and can no longer be applied.
172 virtual bool apply(double time
, blink::WebGestureCurveTarget
* target
) {
173 blink::WebFloatSize
displacement(velocity_
.width
* time
,
174 velocity_
.height
* time
);
175 blink::WebFloatSize
increment(
176 displacement
.width
- cumulative_scroll_
.width
,
177 displacement
.height
- cumulative_scroll_
.height
);
178 cumulative_scroll_
= displacement
;
179 // scrollBy() could delete this curve if the animation is over, so don't
180 // touch any member variables after making that call.
181 return target
->scrollBy(increment
, velocity_
);
185 blink::WebFloatSize velocity_
;
186 blink::WebFloatSize cumulative_scroll_
;
188 DISALLOW_COPY_AND_ASSIGN(FakeWebGestureCurve
);
191 class MockInputHandlerProxyClient
192 : public content::InputHandlerProxyClient
{
194 MockInputHandlerProxyClient() {}
195 ~MockInputHandlerProxyClient() override
{}
197 void WillShutdown() override
{}
199 MOCK_METHOD1(TransferActiveWheelFlingAnimation
,
200 void(const WebActiveWheelFlingParameters
&));
202 blink::WebGestureCurve
* CreateFlingAnimationCurve(
203 WebGestureDevice deviceSource
,
204 const WebFloatPoint
& velocity
,
205 const WebSize
& cumulative_scroll
) override
{
206 return new FakeWebGestureCurve(
207 blink::WebFloatSize(velocity
.x
, velocity
.y
),
208 blink::WebFloatSize(cumulative_scroll
.width
, cumulative_scroll
.height
));
211 MOCK_METHOD1(DidOverscroll
, void(const DidOverscrollParams
&));
212 void DidStopFlinging() override
{}
213 void DidAnimateForInput() override
{}
216 DISALLOW_COPY_AND_ASSIGN(MockInputHandlerProxyClient
);
219 class MockInputHandlerProxyClientWithDidAnimateForInput
220 : public MockInputHandlerProxyClient
{
222 MockInputHandlerProxyClientWithDidAnimateForInput() {}
223 ~MockInputHandlerProxyClientWithDidAnimateForInput() override
{}
225 MOCK_METHOD0(DidAnimateForInput
, void());
228 DISALLOW_COPY_AND_ASSIGN(MockInputHandlerProxyClientWithDidAnimateForInput
);
231 WebTouchPoint
CreateWebTouchPoint(WebTouchPoint::State state
, float x
,
235 point
.screenPosition
= WebFloatPoint(x
, y
);
236 point
.position
= WebFloatPoint(x
, y
);
240 class InputHandlerProxyTest
241 : public testing::Test
,
242 public testing::WithParamInterface
<InputHandlerProxyTestType
> {
244 InputHandlerProxyTest()
245 : synchronous_root_scroll_(GetParam() == ROOT_SCROLL_SYNCHRONOUS_HANDLER
),
246 install_synchronous_handler_(
247 GetParam() == ROOT_SCROLL_SYNCHRONOUS_HANDLER
||
248 GetParam() == CHILD_SCROLL_SYNCHRONOUS_HANDLER
),
249 expected_disposition_(InputHandlerProxy::DID_HANDLE
) {
250 input_handler_
.reset(
251 new content::InputHandlerProxy(&mock_input_handler_
, &mock_client_
));
252 scroll_result_did_scroll_
.did_scroll
= true;
253 scroll_result_did_not_scroll_
.did_scroll
= false;
255 if (install_synchronous_handler_
) {
256 EXPECT_CALL(mock_input_handler_
,
257 RequestUpdateForSynchronousInputHandler())
259 input_handler_
->SetOnlySynchronouslyAnimateRootFlings(
260 &mock_synchronous_input_handler_
);
263 mock_input_handler_
.set_is_scrolling_root(synchronous_root_scroll_
);
266 ~InputHandlerProxyTest() {
267 input_handler_
.reset();
270 // This is defined as a macro so the line numbers can be traced back to the
271 // correct spot when it fails.
272 #define EXPECT_SET_NEEDS_ANIMATE_INPUT(times) \
274 if (synchronous_root_scroll_) { \
275 EXPECT_CALL(mock_synchronous_input_handler_, \
276 SetNeedsSynchronousAnimateInput()) \
278 EXPECT_CALL(mock_input_handler_, SetNeedsAnimateInput()).Times(0); \
280 EXPECT_CALL(mock_input_handler_, SetNeedsAnimateInput()).Times(times); \
281 EXPECT_CALL(mock_synchronous_input_handler_, \
282 SetNeedsSynchronousAnimateInput()) \
287 // This is defined as a macro because when an expectation is not satisfied the
288 // only output you get out of gmock is the line number that set the expectation.
289 #define VERIFY_AND_RESET_MOCKS() \
291 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); \
292 testing::Mock::VerifyAndClearExpectations( \
293 &mock_synchronous_input_handler_); \
294 testing::Mock::VerifyAndClearExpectations(&mock_client_); \
297 void Animate(base::TimeTicks time
) {
298 if (synchronous_root_scroll_
) {
299 input_handler_
->SynchronouslyAnimate(time
);
301 input_handler_
->Animate(time
);
305 void StartFling(base::TimeTicks timestamp
,
306 WebGestureDevice source_device
,
307 WebFloatPoint velocity
,
309 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
310 VERIFY_AND_RESET_MOCKS();
312 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
313 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
314 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
315 gesture_
.sourceDevice
= source_device
;
316 EXPECT_EQ(expected_disposition_
,
317 input_handler_
->HandleInputEvent(gesture_
));
319 VERIFY_AND_RESET_MOCKS();
321 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
322 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
323 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
326 CreateFling(timestamp
, source_device
, velocity
, position
, position
, 0);
327 EXPECT_EQ(expected_disposition_
,
328 input_handler_
->HandleInputEvent(gesture_
));
330 VERIFY_AND_RESET_MOCKS();
333 void CancelFling(base::TimeTicks timestamp
) {
334 gesture_
.timeStampSeconds
= InSecondsF(timestamp
);
335 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
336 EXPECT_EQ(expected_disposition_
,
337 input_handler_
->HandleInputEvent(gesture_
));
339 VERIFY_AND_RESET_MOCKS();
343 const bool synchronous_root_scroll_
;
344 const bool install_synchronous_handler_
;
345 testing::StrictMock
<MockInputHandler
> mock_input_handler_
;
346 testing::StrictMock
<MockSynchronousInputHandler
>
347 mock_synchronous_input_handler_
;
348 scoped_ptr
<content::InputHandlerProxy
> input_handler_
;
349 testing::StrictMock
<MockInputHandlerProxyClient
> mock_client_
;
350 WebGestureEvent gesture_
;
351 InputHandlerProxy::EventDisposition expected_disposition_
;
352 cc::InputHandlerScrollResult scroll_result_did_scroll_
;
353 cc::InputHandlerScrollResult scroll_result_did_not_scroll_
;
356 TEST_P(InputHandlerProxyTest
, MouseWheelByPageMainThread
) {
357 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
358 WebMouseWheelEvent wheel
;
359 wheel
.type
= WebInputEvent::MouseWheel
;
360 wheel
.scrollByPage
= true;
362 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(wheel
));
363 VERIFY_AND_RESET_MOCKS();
366 TEST_P(InputHandlerProxyTest
, MouseWheelWithCtrlNotScroll
) {
367 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
368 WebMouseWheelEvent wheel
;
369 wheel
.type
= WebInputEvent::MouseWheel
;
370 wheel
.modifiers
= WebInputEvent::ControlKey
;
371 wheel
.canScroll
= false;
372 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(wheel
));
373 VERIFY_AND_RESET_MOCKS();
376 TEST_P(InputHandlerProxyTest
, GestureScrollStarted
) {
377 // We shouldn't send any events to the widget for this gesture.
378 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
379 VERIFY_AND_RESET_MOCKS();
381 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
382 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
384 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
385 EXPECT_EQ(expected_disposition_
,input_handler_
->HandleInputEvent(gesture_
));
387 // The event should not be marked as handled if scrolling is not possible.
388 expected_disposition_
= InputHandlerProxy::DROP_EVENT
;
389 VERIFY_AND_RESET_MOCKS();
391 gesture_
.type
= WebInputEvent::GestureScrollUpdate
;
392 gesture_
.data
.scrollUpdate
.deltaY
=
393 -40; // -Y means scroll down - i.e. in the +Y direction.
394 EXPECT_CALL(mock_input_handler_
,
396 testing::Property(&gfx::Vector2dF::y
, testing::Gt(0))))
397 .WillOnce(testing::Return(scroll_result_did_not_scroll_
));
398 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
400 // Mark the event as handled if scroll happens.
401 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
402 VERIFY_AND_RESET_MOCKS();
404 gesture_
.type
= WebInputEvent::GestureScrollUpdate
;
405 gesture_
.data
.scrollUpdate
.deltaY
=
406 -40; // -Y means scroll down - i.e. in the +Y direction.
407 EXPECT_CALL(mock_input_handler_
,
409 testing::Property(&gfx::Vector2dF::y
, testing::Gt(0))))
410 .WillOnce(testing::Return(scroll_result_did_scroll_
));
411 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
413 VERIFY_AND_RESET_MOCKS();
415 gesture_
.type
= WebInputEvent::GestureScrollEnd
;
416 gesture_
.data
.scrollUpdate
.deltaY
= 0;
417 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
418 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
420 VERIFY_AND_RESET_MOCKS();
423 TEST_P(InputHandlerProxyTest
, GestureScrollOnMainThread
) {
424 // We should send all events to the widget for this gesture.
425 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
426 VERIFY_AND_RESET_MOCKS();
428 EXPECT_CALL(mock_input_handler_
, ScrollBegin(::testing::_
, ::testing::_
))
429 .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD
));
431 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
432 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
434 VERIFY_AND_RESET_MOCKS();
436 gesture_
.type
= WebInputEvent::GestureScrollUpdate
;
437 gesture_
.data
.scrollUpdate
.deltaY
= 40;
438 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
440 VERIFY_AND_RESET_MOCKS();
442 gesture_
.type
= WebInputEvent::GestureScrollEnd
;
443 gesture_
.data
.scrollUpdate
.deltaY
= 0;
444 EXPECT_CALL(mock_input_handler_
, ScrollEnd()).WillOnce(testing::Return());
445 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
447 VERIFY_AND_RESET_MOCKS();
450 TEST_P(InputHandlerProxyTest
, GestureScrollIgnored
) {
451 // We shouldn't handle the GestureScrollBegin.
452 // Instead, we should get a DROP_EVENT result, indicating
453 // that we could determine that there's nothing that could scroll or otherwise
454 // react to this gesture sequence and thus we should drop the whole gesture
455 // sequence on the floor, except for the ScrollEnd.
456 expected_disposition_
= InputHandlerProxy::DROP_EVENT
;
457 VERIFY_AND_RESET_MOCKS();
459 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
460 .WillOnce(testing::Return(cc::InputHandler::SCROLL_IGNORED
));
462 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
463 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
465 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
466 gesture_
.type
= WebInputEvent::GestureScrollEnd
;
467 EXPECT_CALL(mock_input_handler_
, ScrollEnd()).WillOnce(testing::Return());
468 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
470 VERIFY_AND_RESET_MOCKS();
473 TEST_P(InputHandlerProxyTest
, GestureScrollBeginThatTargetViewport
) {
474 // We shouldn't send any events to the widget for this gesture.
475 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
476 VERIFY_AND_RESET_MOCKS();
478 EXPECT_CALL(mock_input_handler_
, RootScrollBegin(testing::_
))
479 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
481 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
482 gesture_
.data
.scrollBegin
.targetViewport
= true;
483 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
485 VERIFY_AND_RESET_MOCKS();
488 TEST_P(InputHandlerProxyTest
, GesturePinch
) {
489 // We shouldn't send any events to the widget for this gesture.
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;
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::GesturePinchUpdate
;
511 gesture_
.data
.pinchUpdate
.scale
= 0.5;
512 gesture_
.data
.pinchUpdate
.zoomDisabled
= true;
515 EXPECT_EQ(InputHandlerProxy::DROP_EVENT
,
516 input_handler_
->HandleInputEvent(gesture_
));
517 gesture_
.data
.pinchUpdate
.zoomDisabled
= false;
519 VERIFY_AND_RESET_MOCKS();
521 gesture_
.type
= WebInputEvent::GesturePinchUpdate
;
522 gesture_
.data
.pinchUpdate
.scale
= 0.5;
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 VERIFY_AND_RESET_MOCKS();
537 TEST_P(InputHandlerProxyTest
, GesturePinchWithWheelHandler
) {
538 // We will send the synthetic wheel event to the widget.
539 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
540 VERIFY_AND_RESET_MOCKS();
542 gesture_
.type
= WebInputEvent::GesturePinchBegin
;
543 EXPECT_CALL(mock_input_handler_
, HaveWheelEventHandlersAt(testing::_
))
544 .WillOnce(testing::Return(true));
545 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
547 VERIFY_AND_RESET_MOCKS();
549 gesture_
.type
= WebInputEvent::GesturePinchUpdate
;
550 gesture_
.data
.pinchUpdate
.scale
= 1.5;
553 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
555 VERIFY_AND_RESET_MOCKS();
557 gesture_
.type
= WebInputEvent::GesturePinchUpdate
;
558 gesture_
.data
.pinchUpdate
.scale
= 0.5;
561 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
563 VERIFY_AND_RESET_MOCKS();
565 gesture_
.type
= WebInputEvent::GesturePinchEnd
;
566 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
569 TEST_P(InputHandlerProxyTest
, GesturePinchAfterScrollOnMainThread
) {
570 // Scrolls will start by being sent to the main thread.
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::GestureScrollBegin
;
578 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
580 VERIFY_AND_RESET_MOCKS();
582 gesture_
.type
= WebInputEvent::GestureScrollUpdate
;
583 gesture_
.data
.scrollUpdate
.deltaY
= 40;
584 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
586 // However, after the pinch gesture starts, they should go to the impl
588 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
589 VERIFY_AND_RESET_MOCKS();
591 gesture_
.type
= WebInputEvent::GesturePinchBegin
;
592 EXPECT_CALL(mock_input_handler_
, HaveWheelEventHandlersAt(testing::_
))
593 .WillOnce(testing::Return(false));
594 EXPECT_CALL(mock_input_handler_
, PinchGestureBegin());
595 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
597 VERIFY_AND_RESET_MOCKS();
599 gesture_
.type
= WebInputEvent::GesturePinchUpdate
;
600 gesture_
.data
.pinchUpdate
.scale
= 1.5;
603 EXPECT_CALL(mock_input_handler_
, PinchGestureUpdate(1.5, gfx::Point(7, 13)));
604 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
606 VERIFY_AND_RESET_MOCKS();
608 gesture_
.type
= WebInputEvent::GestureScrollUpdate
;
609 gesture_
.data
.scrollUpdate
.deltaY
=
610 -40; // -Y means scroll down - i.e. in the +Y direction.
611 EXPECT_CALL(mock_input_handler_
,
613 testing::Property(&gfx::Vector2dF::y
, testing::Gt(0))))
614 .WillOnce(testing::Return(scroll_result_did_scroll_
));
615 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
617 VERIFY_AND_RESET_MOCKS();
619 gesture_
.type
= WebInputEvent::GesturePinchUpdate
;
620 gesture_
.data
.pinchUpdate
.scale
= 0.5;
623 EXPECT_CALL(mock_input_handler_
, PinchGestureUpdate(.5, gfx::Point(9, 6)));
624 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
626 VERIFY_AND_RESET_MOCKS();
628 gesture_
.type
= WebInputEvent::GesturePinchEnd
;
629 EXPECT_CALL(mock_input_handler_
, PinchGestureEnd());
630 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
632 // After the pinch gesture ends, they should go to back to the main
634 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
635 VERIFY_AND_RESET_MOCKS();
637 gesture_
.type
= WebInputEvent::GestureScrollEnd
;
638 gesture_
.data
.scrollUpdate
.deltaY
= 0;
639 EXPECT_CALL(mock_input_handler_
, ScrollEnd())
640 .WillOnce(testing::Return());
641 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
643 VERIFY_AND_RESET_MOCKS();
646 TEST_P(InputHandlerProxyTest
, GestureFlingStartedTouchpad
) {
647 // We shouldn't send any events to the widget for this gesture.
648 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
649 VERIFY_AND_RESET_MOCKS();
651 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
652 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
653 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
654 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
656 gesture_
.type
= WebInputEvent::GestureFlingStart
;
657 gesture_
.data
.flingStart
.velocityX
= 10;
658 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchpad
;
659 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
661 VERIFY_AND_RESET_MOCKS();
663 // Verify that a GestureFlingCancel during an animation cancels it.
664 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
665 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchpad
;
666 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
669 TEST_P(InputHandlerProxyTest
, GestureFlingOnMainThreadTouchpad
) {
670 // We should send all events to the widget for this gesture.
671 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
672 VERIFY_AND_RESET_MOCKS();
674 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
675 .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD
));
677 gesture_
.type
= WebInputEvent::GestureFlingStart
;
678 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchpad
;
679 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
681 // Since we returned ScrollStatusOnMainThread from scrollBegin, ensure the
682 // input handler knows it's scrolling off the impl thread
683 ASSERT_FALSE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
685 VERIFY_AND_RESET_MOCKS();
687 // Even if we didn't start a fling ourselves, we still need to send the cancel
688 // event to the widget.
689 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
690 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchpad
;
691 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
694 TEST_P(InputHandlerProxyTest
, GestureFlingIgnoredTouchpad
) {
695 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
696 VERIFY_AND_RESET_MOCKS();
698 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
699 .WillOnce(testing::Return(cc::InputHandler::SCROLL_IGNORED
));
701 gesture_
.type
= WebInputEvent::GestureFlingStart
;
702 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchpad
;
703 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
705 expected_disposition_
= InputHandlerProxy::DROP_EVENT
;
706 VERIFY_AND_RESET_MOCKS();
708 // Since the previous fling was ignored, we should also be dropping the next
710 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
711 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchpad
;
712 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
715 TEST_P(InputHandlerProxyTest
, GestureFlingAnimatesTouchpad
) {
716 // We shouldn't send any events to the widget for this gesture.
717 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
718 VERIFY_AND_RESET_MOCKS();
720 // On the fling start, we should schedule an animation but not actually start
722 gesture_
.type
= WebInputEvent::GestureFlingStart
;
723 WebFloatPoint fling_delta
= WebFloatPoint(1000, 0);
724 WebPoint fling_point
= WebPoint(7, 13);
725 WebPoint fling_global_point
= WebPoint(17, 23);
726 // Note that for trackpad, wheel events with the Control modifier are
727 // special (reserved for zoom), so don't set that here.
728 int modifiers
= WebInputEvent::ShiftKey
| WebInputEvent::AltKey
;
729 gesture_
= CreateFling(blink::WebGestureDeviceTouchpad
,
734 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
735 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
736 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
737 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
738 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
740 VERIFY_AND_RESET_MOCKS();
741 // The first animate call should let us pick up an animation start time, but
742 // we shouldn't actually move anywhere just yet. The first frame after the
743 // fling start will typically include the last scroll from the gesture that
744 // lead to the scroll (either wheel or gesture scroll), so there should be no
746 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
747 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
749 base::TimeTicks time
= base::TimeTicks() + base::TimeDelta::FromSeconds(10);
752 VERIFY_AND_RESET_MOCKS();
754 // The second call should start scrolling in the -X direction.
755 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
756 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
757 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
758 EXPECT_CALL(mock_input_handler_
,
760 testing::Property(&gfx::Vector2dF::x
, testing::Lt(0))))
761 .WillOnce(testing::Return(scroll_result_did_scroll_
));
762 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
763 time
+= base::TimeDelta::FromMilliseconds(100);
766 VERIFY_AND_RESET_MOCKS();
768 // Let's say on the third call we hit a non-scrollable region. We should abort
769 // the fling and not scroll.
770 // We also should pass the current fling parameters out to the client so the
771 // rest of the fling can be
772 // transferred to the main thread.
773 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
774 .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD
));
775 EXPECT_CALL(mock_input_handler_
, ScrollBy(testing::_
, testing::_
)).Times(0);
776 EXPECT_CALL(mock_input_handler_
, ScrollEnd()).Times(0);
777 // Expected wheel fling animation parameters:
778 // *) fling_delta and fling_point should match the original GestureFlingStart
780 // *) startTime should be 10 to match the time parameter of the first
781 // Animate() call after the GestureFlingStart
782 // *) cumulativeScroll depends on the curve, but since we've animated in the
783 // -X direction the X value should be < 0
786 TransferActiveWheelFlingAnimation(testing::AllOf(
787 testing::Field(&WebActiveWheelFlingParameters::delta
,
788 testing::Eq(fling_delta
)),
789 testing::Field(&WebActiveWheelFlingParameters::point
,
790 testing::Eq(fling_point
)),
791 testing::Field(&WebActiveWheelFlingParameters::globalPoint
,
792 testing::Eq(fling_global_point
)),
793 testing::Field(&WebActiveWheelFlingParameters::modifiers
,
794 testing::Eq(modifiers
)),
795 testing::Field(&WebActiveWheelFlingParameters::startTime
,
797 testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll
,
798 testing::Field(&WebSize::width
, testing::Gt(0))))));
799 time
+= base::TimeDelta::FromMilliseconds(100);
802 VERIFY_AND_RESET_MOCKS();
804 // Since we've aborted the fling, the next animation should be a no-op and
805 // should not result in another
806 // frame being requested.
807 EXPECT_SET_NEEDS_ANIMATE_INPUT(0);
808 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
810 time
+= base::TimeDelta::FromMilliseconds(100);
813 // Since we've transferred the fling to the main thread, we need to pass the
814 // next GestureFlingCancel to the main
816 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
817 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
818 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
820 VERIFY_AND_RESET_MOCKS();
823 TEST_P(InputHandlerProxyTest
, GestureFlingTransferResetsTouchpad
) {
824 // We shouldn't send any events to the widget for this gesture.
825 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
826 VERIFY_AND_RESET_MOCKS();
828 // Start a gesture fling in the -X direction with zero Y movement.
829 WebFloatPoint fling_delta
= WebFloatPoint(1000, 0);
830 WebPoint fling_point
= WebPoint(7, 13);
831 WebPoint fling_global_point
= WebPoint(17, 23);
832 // Note that for trackpad, wheel events with the Control modifier are
833 // special (reserved for zoom), so don't set that here.
834 int modifiers
= WebInputEvent::ShiftKey
| WebInputEvent::AltKey
;
835 gesture_
= CreateFling(blink::WebGestureDeviceTouchpad
,
840 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
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 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
846 VERIFY_AND_RESET_MOCKS();
848 // Start the fling animation at time 10. This shouldn't actually scroll, just
849 // establish a start time.
850 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
851 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
853 base::TimeTicks time
= base::TimeTicks() + base::TimeDelta::FromSeconds(10);
856 VERIFY_AND_RESET_MOCKS();
858 // The second call should start scrolling in the -X direction.
859 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
860 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
861 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
862 EXPECT_CALL(mock_input_handler_
,
864 testing::Property(&gfx::Vector2dF::x
, testing::Lt(0))))
865 .WillOnce(testing::Return(scroll_result_did_scroll_
));
866 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
867 time
+= base::TimeDelta::FromMilliseconds(100);
870 VERIFY_AND_RESET_MOCKS();
872 // Let's say on the third call we hit a non-scrollable region. We should abort
873 // the fling and not scroll.
874 // We also should pass the current fling parameters out to the client so the
875 // rest of the fling can be
876 // transferred to the main thread.
877 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
878 .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD
));
879 EXPECT_CALL(mock_input_handler_
, ScrollBy(testing::_
, testing::_
)).Times(0);
880 EXPECT_CALL(mock_input_handler_
, ScrollEnd()).Times(0);
882 // Expected wheel fling animation parameters:
883 // *) fling_delta and fling_point should match the original GestureFlingStart
885 // *) startTime should be 10 to match the time parameter of the first
886 // Animate() call after the GestureFlingStart
887 // *) cumulativeScroll depends on the curve, but since we've animated in the
888 // -X direction the X value should be < 0
891 TransferActiveWheelFlingAnimation(testing::AllOf(
892 testing::Field(&WebActiveWheelFlingParameters::delta
,
893 testing::Eq(fling_delta
)),
894 testing::Field(&WebActiveWheelFlingParameters::point
,
895 testing::Eq(fling_point
)),
896 testing::Field(&WebActiveWheelFlingParameters::globalPoint
,
897 testing::Eq(fling_global_point
)),
898 testing::Field(&WebActiveWheelFlingParameters::modifiers
,
899 testing::Eq(modifiers
)),
900 testing::Field(&WebActiveWheelFlingParameters::startTime
,
902 testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll
,
903 testing::Field(&WebSize::width
, testing::Gt(0))))));
904 time
+= base::TimeDelta::FromMilliseconds(100);
907 VERIFY_AND_RESET_MOCKS();
909 // Since we've aborted the fling, the next animation should be a no-op and
910 // should not result in another
911 // frame being requested.
912 EXPECT_SET_NEEDS_ANIMATE_INPUT(0);
913 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
915 time
+= base::TimeDelta::FromMilliseconds(100);
918 VERIFY_AND_RESET_MOCKS();
920 // Since we've transferred the fling to the main thread, we need to pass the
921 // next GestureFlingCancel to the main
923 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
924 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
925 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
927 VERIFY_AND_RESET_MOCKS();
928 input_handler_
->MainThreadHasStoppedFlinging();
930 // Start a second gesture fling, this time in the +Y direction with no X.
931 fling_delta
= WebFloatPoint(0, -1000);
932 fling_point
= WebPoint(95, 87);
933 fling_global_point
= WebPoint(32, 71);
934 modifiers
= WebInputEvent::AltKey
;
935 gesture_
= CreateFling(blink::WebGestureDeviceTouchpad
,
940 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
941 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
942 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
943 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
944 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
945 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
947 VERIFY_AND_RESET_MOCKS();
949 // Start the second fling animation at time 30.
950 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
951 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
953 time
= base::TimeTicks() + base::TimeDelta::FromSeconds(30);
956 VERIFY_AND_RESET_MOCKS();
958 // Tick the second fling once normally.
959 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
960 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
961 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
962 EXPECT_CALL(mock_input_handler_
,
964 testing::Property(&gfx::Vector2dF::y
, testing::Gt(0))))
965 .WillOnce(testing::Return(scroll_result_did_scroll_
));
966 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
967 time
+= base::TimeDelta::FromMilliseconds(100);
970 VERIFY_AND_RESET_MOCKS();
972 // Then abort the second fling.
973 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
974 .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD
));
975 EXPECT_CALL(mock_input_handler_
, ScrollBy(testing::_
, testing::_
)).Times(0);
976 EXPECT_CALL(mock_input_handler_
, ScrollEnd()).Times(0);
978 // We should get parameters from the second fling, nothing from the first
979 // fling should "leak".
982 TransferActiveWheelFlingAnimation(testing::AllOf(
983 testing::Field(&WebActiveWheelFlingParameters::delta
,
984 testing::Eq(fling_delta
)),
985 testing::Field(&WebActiveWheelFlingParameters::point
,
986 testing::Eq(fling_point
)),
987 testing::Field(&WebActiveWheelFlingParameters::globalPoint
,
988 testing::Eq(fling_global_point
)),
989 testing::Field(&WebActiveWheelFlingParameters::modifiers
,
990 testing::Eq(modifiers
)),
991 testing::Field(&WebActiveWheelFlingParameters::startTime
,
993 testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll
,
994 testing::Field(&WebSize::height
, testing::Lt(0))))));
995 time
+= base::TimeDelta::FromMilliseconds(100);
998 VERIFY_AND_RESET_MOCKS();
1001 TEST_P(InputHandlerProxyTest
, GestureFlingStartedTouchscreen
) {
1002 // We shouldn't send any events to the widget for this gesture.
1003 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1004 VERIFY_AND_RESET_MOCKS();
1006 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1007 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1008 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1009 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1010 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1012 VERIFY_AND_RESET_MOCKS();
1014 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
1015 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1016 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1018 gesture_
.type
= WebInputEvent::GestureFlingStart
;
1019 gesture_
.data
.flingStart
.velocityX
= 10;
1020 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1021 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1023 VERIFY_AND_RESET_MOCKS();
1025 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1027 // Verify that a GestureFlingCancel during an animation cancels it.
1028 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
1029 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1030 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1032 VERIFY_AND_RESET_MOCKS();
1035 TEST_P(InputHandlerProxyTest
, GestureFlingOnMainThreadTouchscreen
) {
1036 // We should send all events to the widget for this gesture.
1037 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
1038 VERIFY_AND_RESET_MOCKS();
1040 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1041 .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD
));
1043 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1044 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1046 VERIFY_AND_RESET_MOCKS();
1048 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin()).Times(0);
1050 gesture_
.type
= WebInputEvent::GestureFlingStart
;
1051 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1052 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1054 VERIFY_AND_RESET_MOCKS();
1056 // Even if we didn't start a fling ourselves, we still need to send the cancel
1057 // event to the widget.
1058 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
1059 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1060 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1063 TEST_P(InputHandlerProxyTest
, GestureFlingIgnoredTouchscreen
) {
1064 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1065 VERIFY_AND_RESET_MOCKS();
1067 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1068 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1070 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1071 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1072 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1074 expected_disposition_
= InputHandlerProxy::DROP_EVENT
;
1075 VERIFY_AND_RESET_MOCKS();
1077 // Flings ignored by the InputHandler should be dropped, signalling the end
1078 // of the touch scroll sequence.
1079 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
1080 .WillOnce(testing::Return(cc::InputHandler::SCROLL_IGNORED
));
1082 gesture_
.type
= WebInputEvent::GestureFlingStart
;
1083 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1084 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1086 VERIFY_AND_RESET_MOCKS();
1088 // Subsequent scrolls should behave normally, even without an intervening
1089 // GestureFlingCancel, as the original GestureFlingStart was dropped.
1090 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1091 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1092 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1093 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1094 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1095 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1097 VERIFY_AND_RESET_MOCKS();
1100 TEST_P(InputHandlerProxyTest
, GestureFlingAnimatesTouchscreen
) {
1101 // We shouldn't send any events to the widget for this gesture.
1102 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1103 VERIFY_AND_RESET_MOCKS();
1105 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1106 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1108 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1109 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1110 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1112 VERIFY_AND_RESET_MOCKS();
1114 // On the fling start, we should schedule an animation but not actually start
1116 WebFloatPoint fling_delta
= WebFloatPoint(100, 0);
1117 WebPoint fling_point
= WebPoint(7, 13);
1118 WebPoint fling_global_point
= WebPoint(17, 23);
1119 // Note that for touchscreen the control modifier is not special.
1120 int modifiers
= WebInputEvent::ControlKey
;
1121 gesture_
= CreateFling(blink::WebGestureDeviceTouchscreen
,
1126 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1127 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
1128 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1129 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1131 VERIFY_AND_RESET_MOCKS();
1132 // The first animate call should let us pick up an animation start time, but
1133 // we shouldn't actually move anywhere just yet. The first frame after the
1134 // fling start will typically include the last scroll from the gesture that
1135 // lead to the scroll (either wheel or gesture scroll), so there should be no
1137 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1138 base::TimeTicks time
= base::TimeTicks() + base::TimeDelta::FromSeconds(10);
1141 VERIFY_AND_RESET_MOCKS();
1143 // The second call should start scrolling in the -X direction.
1144 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1145 EXPECT_CALL(mock_input_handler_
,
1146 ScrollBy(testing::_
,
1147 testing::Property(&gfx::Vector2dF::x
, testing::Lt(0))))
1148 .WillOnce(testing::Return(scroll_result_did_scroll_
));
1149 time
+= base::TimeDelta::FromMilliseconds(100);
1152 VERIFY_AND_RESET_MOCKS();
1154 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1155 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
1156 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1158 VERIFY_AND_RESET_MOCKS();
1161 TEST_P(InputHandlerProxyTest
, GestureFlingWithValidTimestamp
) {
1162 // We shouldn't send any events to the widget for this gesture.
1163 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1164 VERIFY_AND_RESET_MOCKS();
1166 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1167 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1169 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1170 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1171 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1173 VERIFY_AND_RESET_MOCKS();
1175 // On the fling start, we should schedule an animation but not actually start
1177 base::TimeDelta dt
= base::TimeDelta::FromMilliseconds(10);
1178 base::TimeTicks time
= base::TimeTicks() + dt
;
1179 WebFloatPoint fling_delta
= WebFloatPoint(100, 0);
1180 WebPoint fling_point
= WebPoint(7, 13);
1181 WebPoint fling_global_point
= WebPoint(17, 23);
1182 int modifiers
= WebInputEvent::ControlKey
;
1183 gesture_
= CreateFling(time
,
1184 blink::WebGestureDeviceTouchscreen
,
1189 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1190 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
1191 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1192 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1194 VERIFY_AND_RESET_MOCKS();
1195 // With a valid time stamp, the first animate call should skip start time
1196 // initialization and immediately begin scroll update production. This reduces
1197 // the likelihood of a hitch between the scroll preceding the fling and
1198 // the first scroll generated by the fling.
1199 // Scrolling should start in the -X direction.
1200 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1201 EXPECT_CALL(mock_input_handler_
,
1202 ScrollBy(testing::_
,
1203 testing::Property(&gfx::Vector2dF::x
, testing::Lt(0))))
1204 .WillOnce(testing::Return(scroll_result_did_scroll_
));
1208 VERIFY_AND_RESET_MOCKS();
1210 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1211 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
1212 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1214 VERIFY_AND_RESET_MOCKS();
1217 TEST_P(InputHandlerProxyTest
, GestureFlingWithInvalidTimestamp
) {
1218 // We shouldn't send any events to the widget for this gesture.
1219 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1220 VERIFY_AND_RESET_MOCKS();
1222 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1223 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1225 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1226 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1227 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1229 VERIFY_AND_RESET_MOCKS();
1231 // On the fling start, we should schedule an animation but not actually start
1233 base::TimeDelta start_time_offset
= base::TimeDelta::FromMilliseconds(10);
1234 gesture_
.type
= WebInputEvent::GestureFlingStart
;
1235 WebFloatPoint fling_delta
= WebFloatPoint(100, 0);
1236 WebPoint fling_point
= WebPoint(7, 13);
1237 WebPoint fling_global_point
= WebPoint(17, 23);
1238 int modifiers
= WebInputEvent::ControlKey
;
1239 gesture_
.timeStampSeconds
= start_time_offset
.InSecondsF();
1240 gesture_
.data
.flingStart
.velocityX
= fling_delta
.x
;
1241 gesture_
.data
.flingStart
.velocityY
= fling_delta
.y
;
1242 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1243 gesture_
.x
= fling_point
.x
;
1244 gesture_
.y
= fling_point
.y
;
1245 gesture_
.globalX
= fling_global_point
.x
;
1246 gesture_
.globalY
= fling_global_point
.y
;
1247 gesture_
.modifiers
= modifiers
;
1248 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1249 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
1250 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1251 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1253 VERIFY_AND_RESET_MOCKS();
1254 // Event though a time stamp was provided for the fling event, it will be
1255 // ignored as its too far in the past relative to the first animate call's
1257 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1258 base::TimeTicks time
=
1259 base::TimeTicks() + start_time_offset
+ base::TimeDelta::FromSeconds(1);
1262 VERIFY_AND_RESET_MOCKS();
1264 // Further animation ticks should update the fling as usual.
1265 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1266 EXPECT_CALL(mock_input_handler_
,
1267 ScrollBy(testing::_
,
1268 testing::Property(&gfx::Vector2dF::x
, testing::Lt(0))))
1269 .WillOnce(testing::Return(scroll_result_did_scroll_
));
1270 time
+= base::TimeDelta::FromMilliseconds(10);
1273 VERIFY_AND_RESET_MOCKS();
1275 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1276 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
1277 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1279 VERIFY_AND_RESET_MOCKS();
1282 TEST_P(InputHandlerProxyTest
, GestureScrollOnImplThreadFlagClearedAfterFling
) {
1283 // We shouldn't send any events to the widget for this gesture.
1284 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1285 VERIFY_AND_RESET_MOCKS();
1287 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1288 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1290 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1291 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1293 // After sending a GestureScrollBegin, the member variable
1294 // |gesture_scroll_on_impl_thread_| should be true.
1295 EXPECT_TRUE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1297 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1298 VERIFY_AND_RESET_MOCKS();
1300 // On the fling start, we should schedule an animation but not actually start
1302 WebFloatPoint fling_delta
= WebFloatPoint(100, 0);
1303 WebPoint fling_point
= WebPoint(7, 13);
1304 WebPoint fling_global_point
= WebPoint(17, 23);
1305 int modifiers
= WebInputEvent::ControlKey
| WebInputEvent::AltKey
;
1306 gesture_
= CreateFling(blink::WebGestureDeviceTouchscreen
,
1311 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1312 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
1313 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1314 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1316 // |gesture_scroll_on_impl_thread_| should still be true after
1317 // a GestureFlingStart is sent.
1318 EXPECT_TRUE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1320 VERIFY_AND_RESET_MOCKS();
1321 // The first animate call should let us pick up an animation start time, but
1322 // we shouldn't actually move anywhere just yet. The first frame after the
1323 // fling start will typically include the last scroll from the gesture that
1324 // lead to the scroll (either wheel or gesture scroll), so there should be no
1326 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1327 base::TimeTicks time
= base::TimeTicks() + base::TimeDelta::FromSeconds(10);
1330 VERIFY_AND_RESET_MOCKS();
1332 // The second call should start scrolling in the -X direction.
1333 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1334 EXPECT_CALL(mock_input_handler_
,
1335 ScrollBy(testing::_
,
1336 testing::Property(&gfx::Vector2dF::x
, testing::Lt(0))))
1337 .WillOnce(testing::Return(scroll_result_did_scroll_
));
1338 time
+= base::TimeDelta::FromMilliseconds(100);
1341 VERIFY_AND_RESET_MOCKS();
1343 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1344 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
1345 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1347 // |gesture_scroll_on_impl_thread_| should be false once
1348 // the fling has finished (note no GestureScrollEnd has been sent).
1349 EXPECT_TRUE(!input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1351 VERIFY_AND_RESET_MOCKS();
1354 TEST_P(InputHandlerProxyTest
,
1355 BeginScrollWhenGestureScrollOnImplThreadFlagIsSet
) {
1356 // We shouldn't send any events to the widget for this gesture.
1357 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1358 VERIFY_AND_RESET_MOCKS();
1360 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1361 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1363 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1364 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1366 // After sending a GestureScrollBegin, the member variable
1367 // |gesture_scroll_on_impl_thread_| should be true.
1368 EXPECT_TRUE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1370 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1371 VERIFY_AND_RESET_MOCKS();
1373 // On the fling start, we should schedule an animation but not actually start
1375 WebFloatPoint fling_delta
= WebFloatPoint(100, 0);
1376 WebPoint fling_point
= WebPoint(7, 13);
1377 WebPoint fling_global_point
= WebPoint(17, 23);
1378 int modifiers
= WebInputEvent::ControlKey
| WebInputEvent::AltKey
;
1379 gesture_
= CreateFling(blink::WebGestureDeviceTouchscreen
, fling_delta
,
1380 fling_point
, fling_global_point
, modifiers
);
1381 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1382 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
1383 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1384 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1386 // |gesture_scroll_on_impl_thread_| should still be true after
1387 // a GestureFlingStart is sent.
1388 EXPECT_TRUE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1390 VERIFY_AND_RESET_MOCKS();
1392 // gesture_scroll_on_impl_thread_ is still true when this scroll begins. As a
1393 // result, this scroll begin will cancel the previous fling.
1394 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1395 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1396 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1398 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1399 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1401 // After sending a GestureScrollBegin, the member variable
1402 // |gesture_scroll_on_impl_thread_| should be true.
1403 EXPECT_TRUE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1404 VERIFY_AND_RESET_MOCKS();
1407 TEST_P(InputHandlerProxyTest
, GestureFlingStopsAtContentEdge
) {
1408 // We shouldn't send any events to the widget for this gesture.
1409 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1410 VERIFY_AND_RESET_MOCKS();
1412 // On the fling start, we should schedule an animation but not actually start
1414 gesture_
.type
= WebInputEvent::GestureFlingStart
;
1415 WebFloatPoint fling_delta
= WebFloatPoint(100, 100);
1416 gesture_
.data
.flingStart
.velocityX
= fling_delta
.x
;
1417 gesture_
.data
.flingStart
.velocityY
= fling_delta
.y
;
1418 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1419 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1420 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1421 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1422 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1423 VERIFY_AND_RESET_MOCKS();
1425 // The first animate doesn't cause any scrolling.
1426 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1427 base::TimeTicks time
= base::TimeTicks() + base::TimeDelta::FromSeconds(10);
1429 VERIFY_AND_RESET_MOCKS();
1431 // The second animate starts scrolling in the positive X and Y directions.
1432 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1433 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1434 EXPECT_CALL(mock_input_handler_
,
1435 ScrollBy(testing::_
,
1436 testing::Property(&gfx::Vector2dF::y
, testing::Lt(0))))
1437 .WillOnce(testing::Return(scroll_result_did_scroll_
));
1438 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1439 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1440 time
+= base::TimeDelta::FromMilliseconds(100);
1442 VERIFY_AND_RESET_MOCKS();
1444 // The third animate overscrolls in the positive Y direction but scrolls
1446 cc::InputHandlerScrollResult overscroll
;
1447 overscroll
.did_scroll
= true;
1448 overscroll
.did_overscroll_root
= true;
1449 overscroll
.accumulated_root_overscroll
= gfx::Vector2dF(0, 100);
1450 overscroll
.unused_scroll_delta
= gfx::Vector2dF(0, 10);
1451 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1452 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1453 EXPECT_CALL(mock_input_handler_
,
1454 ScrollBy(testing::_
,
1455 testing::Property(&gfx::Vector2dF::y
, testing::Lt(0))))
1456 .WillOnce(testing::Return(overscroll
));
1459 DidOverscroll(testing::AllOf(
1461 &DidOverscrollParams::accumulated_overscroll
,
1462 testing::Eq(overscroll
.accumulated_root_overscroll
)),
1464 &DidOverscrollParams::latest_overscroll_delta
,
1465 testing::Eq(overscroll
.unused_scroll_delta
)),
1467 &DidOverscrollParams::current_fling_velocity
,
1468 testing::Property(&gfx::Vector2dF::y
, testing::Lt(0))))));
1469 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1470 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1471 time
+= base::TimeDelta::FromMilliseconds(100);
1473 VERIFY_AND_RESET_MOCKS();
1475 // The next call to animate will no longer scroll vertically.
1476 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1477 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1478 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1479 EXPECT_CALL(mock_input_handler_
,
1480 ScrollBy(testing::_
,
1481 testing::Property(&gfx::Vector2dF::y
, testing::Eq(0))))
1482 .WillOnce(testing::Return(scroll_result_did_scroll_
));
1483 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1484 time
+= base::TimeDelta::FromMilliseconds(100);
1486 VERIFY_AND_RESET_MOCKS();
1489 TEST_P(InputHandlerProxyTest
, GestureFlingNotCancelledBySmallTimeDelta
) {
1490 // We shouldn't send any events to the widget for this gesture.
1491 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1492 VERIFY_AND_RESET_MOCKS();
1494 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1495 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1497 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1498 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1499 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1501 VERIFY_AND_RESET_MOCKS();
1503 // On the fling start, we should schedule an animation but not actually start
1505 base::TimeDelta dt
= base::TimeDelta::FromMilliseconds(10);
1506 base::TimeTicks time
= base::TimeTicks() + dt
;
1507 WebFloatPoint fling_delta
= WebFloatPoint(100, 0);
1508 WebPoint fling_point
= WebPoint(7, 13);
1509 WebPoint fling_global_point
= WebPoint(17, 23);
1510 int modifiers
= WebInputEvent::ControlKey
;
1511 gesture_
= CreateFling(time
,
1512 blink::WebGestureDeviceTouchscreen
,
1517 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1518 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
1519 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1520 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1522 VERIFY_AND_RESET_MOCKS();
1523 // With an animation timestamp equivalent to the starting timestamp, the
1524 // animation will simply be rescheduled.
1525 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1528 VERIFY_AND_RESET_MOCKS();
1529 EXPECT_TRUE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1531 // A small time delta should not stop the fling, even if the client
1532 // reports no scrolling.
1533 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1534 EXPECT_CALL(mock_input_handler_
,
1535 ScrollBy(testing::_
,
1536 testing::Property(&gfx::Vector2dF::x
, testing::Lt(0))))
1537 .WillOnce(testing::Return(scroll_result_did_not_scroll_
));
1538 time
+= base::TimeDelta::FromMicroseconds(5);
1541 VERIFY_AND_RESET_MOCKS();
1542 EXPECT_TRUE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1544 // A time delta of zero should not stop the fling, and neither should it
1545 // trigger scrolling on the client.
1546 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1549 VERIFY_AND_RESET_MOCKS();
1550 EXPECT_TRUE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1552 // Lack of movement on the client, with a non-trivial scroll delta, should
1553 // terminate the fling.
1554 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1555 EXPECT_CALL(mock_input_handler_
,
1556 ScrollBy(testing::_
,
1557 testing::Property(&gfx::Vector2dF::x
, testing::Lt(1))))
1558 .WillOnce(testing::Return(scroll_result_did_not_scroll_
));
1559 time
+= base::TimeDelta::FromMilliseconds(100);
1562 VERIFY_AND_RESET_MOCKS();
1563 EXPECT_FALSE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1566 TEST_P(InputHandlerProxyTest
, GestureFlingCancelledAfterBothAxesStopScrolling
) {
1567 cc::InputHandlerScrollResult overscroll
;
1568 overscroll
.did_scroll
= true;
1569 overscroll
.did_overscroll_root
= true;
1571 // We shouldn't send any events to the widget for this gesture.
1572 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1573 VERIFY_AND_RESET_MOCKS();
1575 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1576 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1577 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1578 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1579 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1580 VERIFY_AND_RESET_MOCKS();
1582 // On the fling start, we should schedule an animation but not actually start
1584 gesture_
.type
= WebInputEvent::GestureFlingStart
;
1585 WebFloatPoint fling_delta
= WebFloatPoint(100, 100);
1586 gesture_
.data
.flingStart
.velocityX
= fling_delta
.x
;
1587 gesture_
.data
.flingStart
.velocityY
= fling_delta
.y
;
1588 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
1589 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1590 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1591 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1592 VERIFY_AND_RESET_MOCKS();
1594 // The first animate doesn't cause any scrolling.
1595 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1596 base::TimeTicks time
= base::TimeTicks() + base::TimeDelta::FromSeconds(10);
1598 VERIFY_AND_RESET_MOCKS();
1600 // The second animate starts scrolling in the positive X and Y directions.
1601 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1602 EXPECT_CALL(mock_input_handler_
,
1603 ScrollBy(testing::_
,
1604 testing::Property(&gfx::Vector2dF::y
, testing::Lt(0))))
1605 .WillOnce(testing::Return(scroll_result_did_scroll_
));
1606 time
+= base::TimeDelta::FromMilliseconds(10);
1608 VERIFY_AND_RESET_MOCKS();
1610 // The third animate hits the bottom content edge.
1611 overscroll
.accumulated_root_overscroll
= gfx::Vector2dF(0, 100);
1612 overscroll
.unused_scroll_delta
= gfx::Vector2dF(0, 100);
1613 EXPECT_CALL(mock_input_handler_
,
1614 ScrollBy(testing::_
,
1615 testing::Property(&gfx::Vector2dF::y
, testing::Lt(0))))
1616 .WillOnce(testing::Return(overscroll
));
1619 DidOverscroll(testing::AllOf(
1621 &DidOverscrollParams::accumulated_overscroll
,
1622 testing::Eq(overscroll
.accumulated_root_overscroll
)),
1624 &DidOverscrollParams::latest_overscroll_delta
,
1625 testing::Eq(overscroll
.unused_scroll_delta
)),
1627 &DidOverscrollParams::current_fling_velocity
,
1628 testing::Property(&gfx::Vector2dF::y
, testing::Lt(0))))));
1629 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1630 time
+= base::TimeDelta::FromMilliseconds(10);
1632 VERIFY_AND_RESET_MOCKS();
1634 // The next call to animate will no longer scroll vertically.
1635 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1636 EXPECT_CALL(mock_input_handler_
,
1637 ScrollBy(testing::_
,
1638 testing::Property(&gfx::Vector2dF::y
, testing::Eq(0))))
1639 .WillOnce(testing::Return(scroll_result_did_scroll_
));
1640 time
+= base::TimeDelta::FromMilliseconds(10);
1642 VERIFY_AND_RESET_MOCKS();
1644 // The next call will hit the right edge.
1645 overscroll
.accumulated_root_overscroll
= gfx::Vector2dF(100, 100);
1646 overscroll
.unused_scroll_delta
= gfx::Vector2dF(100, 0);
1647 EXPECT_CALL(mock_input_handler_
,
1648 ScrollBy(testing::_
,
1649 testing::Property(&gfx::Vector2dF::x
, testing::Lt(0))))
1650 .WillOnce(testing::Return(overscroll
));
1653 DidOverscroll(testing::AllOf(
1655 &DidOverscrollParams::accumulated_overscroll
,
1656 testing::Eq(overscroll
.accumulated_root_overscroll
)),
1658 &DidOverscrollParams::latest_overscroll_delta
,
1659 testing::Eq(overscroll
.unused_scroll_delta
)),
1661 &DidOverscrollParams::current_fling_velocity
,
1662 testing::Property(&gfx::Vector2dF::x
, testing::Lt(0))))));
1663 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1664 time
+= base::TimeDelta::FromMilliseconds(10);
1666 VERIFY_AND_RESET_MOCKS();
1668 // The next call to animate will no longer scroll horizontally or vertically,
1669 // and the fling should be cancelled.
1670 EXPECT_SET_NEEDS_ANIMATE_INPUT(0);
1671 EXPECT_CALL(mock_input_handler_
, ScrollBy(testing::_
, testing::_
)).Times(0);
1672 time
+= base::TimeDelta::FromMilliseconds(10);
1674 VERIFY_AND_RESET_MOCKS();
1675 EXPECT_FALSE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1678 TEST_P(InputHandlerProxyTest
, MultiTouchPointHitTestNegative
) {
1679 // None of the three touch points fall in the touch region. So the event
1680 // should be dropped.
1681 expected_disposition_
= InputHandlerProxy::DROP_EVENT
;
1682 VERIFY_AND_RESET_MOCKS();
1684 EXPECT_CALL(mock_input_handler_
,
1685 DoTouchEventsBlockScrollAt(
1686 testing::Property(&gfx::Point::x
, testing::Gt(0))))
1687 .WillOnce(testing::Return(false));
1688 EXPECT_CALL(mock_input_handler_
,
1689 DoTouchEventsBlockScrollAt(
1690 testing::Property(&gfx::Point::x
, testing::Lt(0))))
1691 .WillOnce(testing::Return(false));
1693 WebTouchEvent touch
;
1694 touch
.type
= WebInputEvent::TouchStart
;
1696 touch
.touchesLength
= 3;
1697 touch
.touches
[0] = CreateWebTouchPoint(WebTouchPoint::StateStationary
, 0, 0);
1698 touch
.touches
[1] = CreateWebTouchPoint(WebTouchPoint::StatePressed
, 10, 10);
1699 touch
.touches
[2] = CreateWebTouchPoint(WebTouchPoint::StatePressed
, -10, 10);
1700 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(touch
));
1702 VERIFY_AND_RESET_MOCKS();
1705 TEST_P(InputHandlerProxyTest
, MultiTouchPointHitTestPositive
) {
1706 // One of the touch points is on a touch-region. So the event should be sent
1707 // to the main thread.
1708 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
1709 VERIFY_AND_RESET_MOCKS();
1711 EXPECT_CALL(mock_input_handler_
,
1712 DoTouchEventsBlockScrollAt(
1713 testing::Property(&gfx::Point::x
, testing::Eq(0))))
1714 .WillOnce(testing::Return(false));
1715 EXPECT_CALL(mock_input_handler_
,
1716 DoTouchEventsBlockScrollAt(
1717 testing::Property(&gfx::Point::x
, testing::Gt(0))))
1718 .WillOnce(testing::Return(true));
1719 // Since the second touch point hits a touch-region, there should be no
1720 // hit-testing for the third touch point.
1722 WebTouchEvent touch
;
1723 touch
.type
= WebInputEvent::TouchStart
;
1725 touch
.touchesLength
= 3;
1726 touch
.touches
[0] = CreateWebTouchPoint(WebTouchPoint::StatePressed
, 0, 0);
1727 touch
.touches
[1] = CreateWebTouchPoint(WebTouchPoint::StatePressed
, 10, 10);
1728 touch
.touches
[2] = CreateWebTouchPoint(WebTouchPoint::StatePressed
, -10, 10);
1729 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(touch
));
1731 VERIFY_AND_RESET_MOCKS();
1734 TEST_P(InputHandlerProxyTest
, GestureFlingCancelledByKeyboardEvent
) {
1735 // We shouldn't send any events to the widget for this gesture.
1736 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1737 VERIFY_AND_RESET_MOCKS();
1739 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1740 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1741 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1742 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1743 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1744 EXPECT_TRUE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1745 VERIFY_AND_RESET_MOCKS();
1747 // Keyboard events received during a scroll should have no effect.
1748 WebKeyboardEvent key_event
;
1749 key_event
.type
= WebInputEvent::KeyDown
;
1750 EXPECT_EQ(InputHandlerProxy::DID_NOT_HANDLE
,
1751 input_handler_
->HandleInputEvent(key_event
));
1752 EXPECT_TRUE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1753 VERIFY_AND_RESET_MOCKS();
1755 // On the fling start, animation should be scheduled, but no scrolling occurs.
1756 gesture_
.type
= WebInputEvent::GestureFlingStart
;
1757 WebFloatPoint fling_delta
= WebFloatPoint(100, 100);
1758 gesture_
.data
.flingStart
.velocityX
= fling_delta
.x
;
1759 gesture_
.data
.flingStart
.velocityY
= fling_delta
.y
;
1760 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
1761 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1762 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1763 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1764 EXPECT_TRUE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1765 VERIFY_AND_RESET_MOCKS();
1767 // Keyboard events received during a fling should cancel the active fling.
1768 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1769 EXPECT_EQ(InputHandlerProxy::DID_NOT_HANDLE
,
1770 input_handler_
->HandleInputEvent(key_event
));
1771 EXPECT_FALSE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1772 VERIFY_AND_RESET_MOCKS();
1774 // The call to animate should have no effect, as the fling was cancelled.
1775 base::TimeTicks time
= base::TimeTicks() + base::TimeDelta::FromSeconds(10);
1777 VERIFY_AND_RESET_MOCKS();
1779 // A fling cancel should be dropped, as there is nothing to cancel.
1780 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
1781 EXPECT_EQ(InputHandlerProxy::DROP_EVENT
,
1782 input_handler_
->HandleInputEvent(gesture_
));
1783 EXPECT_FALSE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1786 TEST_P(InputHandlerProxyTest
, GestureFlingWithNegativeTimeDelta
) {
1787 // We shouldn't send any events to the widget for this gesture.
1788 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1789 VERIFY_AND_RESET_MOCKS();
1791 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1792 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1794 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1795 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1796 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1798 VERIFY_AND_RESET_MOCKS();
1800 // On the fling start, we should schedule an animation but not actually start
1802 base::TimeDelta dt
= base::TimeDelta::FromMilliseconds(10);
1803 base::TimeTicks time
= base::TimeTicks() + dt
;
1804 WebFloatPoint fling_delta
= WebFloatPoint(100, 0);
1805 WebPoint fling_point
= WebPoint(7, 13);
1806 WebPoint fling_global_point
= WebPoint(17, 23);
1807 int modifiers
= WebInputEvent::ControlKey
;
1808 gesture_
= CreateFling(time
,
1809 blink::WebGestureDeviceTouchscreen
,
1814 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1815 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
1816 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
1817 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1819 VERIFY_AND_RESET_MOCKS();
1821 // If we get a negative time delta, that is, the Animation tick time happens
1822 // before the fling's start time then we should *not* try scrolling and
1823 // instead reset the fling start time.
1824 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1825 EXPECT_CALL(mock_input_handler_
,
1826 ScrollBy(testing::_
,
1827 testing::_
)).Times(0);
1828 time
-= base::TimeDelta::FromMilliseconds(5);
1831 VERIFY_AND_RESET_MOCKS();
1833 // The first call should have reset the start time so subsequent calls should
1834 // generate scroll events.
1835 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1836 EXPECT_CALL(mock_input_handler_
,
1837 ScrollBy(testing::_
,
1838 testing::Property(&gfx::Vector2dF::x
, testing::Lt(0))))
1839 .WillOnce(testing::Return(scroll_result_did_scroll_
));
1841 Animate(time
+ base::TimeDelta::FromMilliseconds(1));
1843 VERIFY_AND_RESET_MOCKS();
1845 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1846 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
1847 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1849 VERIFY_AND_RESET_MOCKS();
1852 TEST_P(InputHandlerProxyTest
, FlingBoost
) {
1853 base::TimeDelta dt
= base::TimeDelta::FromMilliseconds(10);
1854 base::TimeTicks time
= base::TimeTicks() + dt
;
1855 base::TimeTicks last_animate_time
= time
;
1856 WebFloatPoint fling_delta
= WebFloatPoint(1000, 0);
1857 WebPoint fling_point
= WebPoint(7, 13);
1859 time
, blink::WebGestureDeviceTouchscreen
, fling_delta
, fling_point
);
1861 // Now cancel the fling. The fling cancellation should be deferred to allow
1862 // fling boosting events to arrive.
1866 // The GestureScrollBegin should be swallowed by the fling if it hits the same
1868 EXPECT_CALL(mock_input_handler_
,
1869 IsCurrentlyScrollingLayerAt(testing::_
, testing::_
))
1870 .WillOnce(testing::Return(true));
1873 gesture_
.timeStampSeconds
= InSecondsF(time
);
1874 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1875 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1877 VERIFY_AND_RESET_MOCKS();
1879 // Animate calls within the deferred cancellation window should continue.
1881 float expected_delta
=
1882 (time
- last_animate_time
).InSecondsF() * -fling_delta
.x
;
1883 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1884 EXPECT_CALL(mock_input_handler_
,
1885 ScrollBy(testing::_
,
1886 testing::Property(&gfx::Vector2dF::x
,
1887 testing::Eq(expected_delta
))))
1888 .WillOnce(testing::Return(scroll_result_did_scroll_
));
1890 last_animate_time
= time
;
1892 VERIFY_AND_RESET_MOCKS();
1894 // GestureScrollUpdates in the same direction and at sufficient speed should
1895 // be swallowed by the fling.
1897 gesture_
.timeStampSeconds
= InSecondsF(time
);
1898 gesture_
.type
= WebInputEvent::GestureScrollUpdate
;
1899 gesture_
.data
.scrollUpdate
.deltaX
= fling_delta
.x
;
1900 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1902 VERIFY_AND_RESET_MOCKS();
1904 // Animate calls within the deferred cancellation window should continue.
1906 expected_delta
= (time
- last_animate_time
).InSecondsF() * -fling_delta
.x
;
1907 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1908 EXPECT_CALL(mock_input_handler_
,
1909 ScrollBy(testing::_
,
1910 testing::Property(&gfx::Vector2dF::x
,
1911 testing::Eq(expected_delta
))))
1912 .WillOnce(testing::Return(scroll_result_did_scroll_
));
1914 last_animate_time
= time
;
1916 VERIFY_AND_RESET_MOCKS();
1918 // GestureFlingStart in the same direction and at sufficient speed should
1919 // boost the active fling.
1921 gesture_
= CreateFling(time
,
1922 blink::WebGestureDeviceTouchscreen
,
1927 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1928 VERIFY_AND_RESET_MOCKS();
1931 // Note we get *2x* as much delta because 2 flings have combined.
1932 expected_delta
= 2 * (time
- last_animate_time
).InSecondsF() * -fling_delta
.x
;
1933 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1934 EXPECT_CALL(mock_input_handler_
,
1935 ScrollBy(testing::_
,
1936 testing::Property(&gfx::Vector2dF::x
,
1937 testing::Eq(expected_delta
))))
1938 .WillOnce(testing::Return(scroll_result_did_scroll_
));
1940 last_animate_time
= time
;
1942 VERIFY_AND_RESET_MOCKS();
1944 // Repeated GestureFlingStarts should accumulate.
1947 gesture_
= CreateFling(time
,
1948 blink::WebGestureDeviceTouchscreen
,
1953 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1954 VERIFY_AND_RESET_MOCKS();
1957 // Note we get *3x* as much delta because 3 flings have combined.
1958 expected_delta
= 3 * (time
- last_animate_time
).InSecondsF() * -fling_delta
.x
;
1959 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1960 EXPECT_CALL(mock_input_handler_
,
1961 ScrollBy(testing::_
,
1962 testing::Property(&gfx::Vector2dF::x
,
1963 testing::Eq(expected_delta
))))
1964 .WillOnce(testing::Return(scroll_result_did_scroll_
));
1966 last_animate_time
= time
;
1968 VERIFY_AND_RESET_MOCKS();
1970 // GestureFlingCancel should terminate the fling if no boosting gestures are
1971 // received within the timeout window.
1974 gesture_
.timeStampSeconds
= InSecondsF(time
);
1975 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
1976 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1978 VERIFY_AND_RESET_MOCKS();
1980 time
+= base::TimeDelta::FromMilliseconds(100);
1981 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1984 VERIFY_AND_RESET_MOCKS();
1987 TEST_P(InputHandlerProxyTest
, NoFlingBoostIfScrollTargetsDifferentLayer
) {
1988 base::TimeDelta dt
= base::TimeDelta::FromMilliseconds(10);
1989 base::TimeTicks time
= base::TimeTicks() + dt
;
1990 WebFloatPoint fling_delta
= WebFloatPoint(1000, 0);
1991 WebPoint fling_point
= WebPoint(7, 13);
1993 time
, blink::WebGestureDeviceTouchscreen
, fling_delta
, fling_point
);
1995 // Cancel the fling. The fling cancellation should be deferred to allow
1996 // fling boosting events to arrive.
2000 // If the GestureScrollBegin targets a different layer, the fling should be
2001 // cancelled and the scroll should be handled as usual.
2002 EXPECT_CALL(mock_input_handler_
,
2003 IsCurrentlyScrollingLayerAt(testing::_
, testing::_
))
2004 .WillOnce(testing::Return(false));
2005 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
2006 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
2007 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
2010 gesture_
.timeStampSeconds
= InSecondsF(time
);
2011 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
2012 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
2014 VERIFY_AND_RESET_MOCKS();
2017 TEST_P(InputHandlerProxyTest
, NoFlingBoostIfScrollDelayed
) {
2018 base::TimeDelta dt
= base::TimeDelta::FromMilliseconds(10);
2019 base::TimeTicks time
= base::TimeTicks() + dt
;
2020 WebFloatPoint fling_delta
= WebFloatPoint(1000, 0);
2021 WebPoint fling_point
= WebPoint(7, 13);
2023 time
, blink::WebGestureDeviceTouchscreen
, fling_delta
, fling_point
);
2025 // Cancel the fling. The fling cancellation should be deferred to allow
2026 // fling boosting events to arrive.
2030 // The GestureScrollBegin should be swallowed by the fling if it hits the same
2032 EXPECT_CALL(mock_input_handler_
,
2033 IsCurrentlyScrollingLayerAt(testing::_
, testing::_
))
2034 .WillOnce(testing::Return(true));
2037 gesture_
.timeStampSeconds
= InSecondsF(time
);
2038 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
2039 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
2041 VERIFY_AND_RESET_MOCKS();
2043 // If no GestureScrollUpdate or GestureFlingStart is received within the
2044 // timeout window, the fling should be cancelled and scrolling should resume.
2045 time
+= base::TimeDelta::FromMilliseconds(100);
2046 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
2047 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
2048 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
2051 VERIFY_AND_RESET_MOCKS();
2054 TEST_P(InputHandlerProxyTest
, NoFlingBoostIfNotAnimated
) {
2055 base::TimeDelta dt
= base::TimeDelta::FromMilliseconds(10);
2056 base::TimeTicks time
= base::TimeTicks() + dt
;
2057 WebFloatPoint fling_delta
= WebFloatPoint(1000, 0);
2058 WebPoint fling_point
= WebPoint(7, 13);
2060 time
, blink::WebGestureDeviceTouchscreen
, fling_delta
, fling_point
);
2062 // Animate fling once.
2064 EXPECT_CALL(mock_input_handler_
, ScrollBy(testing::_
, testing::_
))
2065 .WillOnce(testing::Return(scroll_result_did_scroll_
));
2066 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
2069 // Cancel the fling after long delay of no animate. The fling cancellation
2070 // should be deferred to allow fling boosting events to arrive.
2071 time
+= base::TimeDelta::FromMilliseconds(100);
2074 // The GestureScrollBegin should be swallowed by the fling if it hits the same
2076 EXPECT_CALL(mock_input_handler_
,
2077 IsCurrentlyScrollingLayerAt(testing::_
, testing::_
))
2078 .WillOnce(testing::Return(true));
2081 gesture_
.timeStampSeconds
= InSecondsF(time
);
2082 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
2083 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
2085 VERIFY_AND_RESET_MOCKS();
2087 // Should exit scroll bosting on GestureScrollUpdate due to long delay
2088 // since last animate. Cancel old fling and start new scroll.
2089 gesture_
.type
= WebInputEvent::GestureScrollUpdate
;
2090 gesture_
.data
.scrollUpdate
.deltaY
= -40;
2091 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
2092 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
2093 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
2094 EXPECT_CALL(mock_input_handler_
, ScrollBy(testing::_
, testing::_
))
2095 .WillOnce(testing::Return(scroll_result_did_scroll_
));
2096 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
2098 VERIFY_AND_RESET_MOCKS();
2101 TEST_P(InputHandlerProxyTest
, NoFlingBoostIfFlingInDifferentDirection
) {
2102 base::TimeDelta dt
= base::TimeDelta::FromMilliseconds(10);
2103 base::TimeTicks time
= base::TimeTicks() + dt
;
2104 WebFloatPoint fling_delta
= WebFloatPoint(1000, 0);
2105 WebPoint fling_point
= WebPoint(7, 13);
2107 time
, blink::WebGestureDeviceTouchscreen
, fling_delta
, fling_point
);
2109 // Cancel the fling. The fling cancellation should be deferred to allow
2110 // fling boosting events to arrive.
2114 // If the new fling is orthogonal to the existing fling, no boosting should
2115 // take place, with the new fling replacing the old.
2116 WebFloatPoint orthogonal_fling_delta
=
2117 WebFloatPoint(fling_delta
.y
, -fling_delta
.x
);
2118 gesture_
= CreateFling(time
,
2119 blink::WebGestureDeviceTouchscreen
,
2120 orthogonal_fling_delta
,
2124 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
2126 VERIFY_AND_RESET_MOCKS();
2128 // Note that the new fling delta uses the orthogonal, unboosted fling
2131 float expected_delta
= dt
.InSecondsF() * -orthogonal_fling_delta
.y
;
2132 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
2133 EXPECT_CALL(mock_input_handler_
,
2134 ScrollBy(testing::_
,
2135 testing::Property(&gfx::Vector2dF::y
,
2136 testing::Eq(expected_delta
))))
2137 .WillOnce(testing::Return(scroll_result_did_scroll_
));
2140 VERIFY_AND_RESET_MOCKS();
2143 TEST_P(InputHandlerProxyTest
, NoFlingBoostIfScrollInDifferentDirection
) {
2144 base::TimeDelta dt
= base::TimeDelta::FromMilliseconds(10);
2145 base::TimeTicks time
= base::TimeTicks() + dt
;
2146 WebFloatPoint fling_delta
= WebFloatPoint(1000, 0);
2147 WebPoint fling_point
= WebPoint(7, 13);
2149 time
, blink::WebGestureDeviceTouchscreen
, fling_delta
, fling_point
);
2151 // Cancel the fling. The fling cancellation should be deferred to allow
2152 // fling boosting events to arrive.
2156 // The GestureScrollBegin should be swallowed by the fling if it hits the same
2158 EXPECT_CALL(mock_input_handler_
,
2159 IsCurrentlyScrollingLayerAt(testing::_
, testing::_
))
2160 .WillOnce(testing::Return(true));
2163 gesture_
.timeStampSeconds
= InSecondsF(time
);
2164 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
2165 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
2167 VERIFY_AND_RESET_MOCKS();
2169 // If the GestureScrollUpdate is in a different direction than the fling,
2170 // the fling should be cancelled and scrolling should resume.
2172 gesture_
.timeStampSeconds
= InSecondsF(time
);
2173 gesture_
.type
= WebInputEvent::GestureScrollUpdate
;
2174 gesture_
.data
.scrollUpdate
.deltaX
= -fling_delta
.x
;
2175 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
2176 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
2177 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
2178 EXPECT_CALL(mock_input_handler_
,
2179 ScrollBy(testing::_
,
2180 testing::Property(&gfx::Vector2dF::x
,
2181 testing::Eq(fling_delta
.x
))))
2182 .WillOnce(testing::Return(scroll_result_did_scroll_
));
2183 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
2185 VERIFY_AND_RESET_MOCKS();
2188 TEST_P(InputHandlerProxyTest
, NoFlingBoostIfFlingTooSlow
) {
2189 base::TimeDelta dt
= base::TimeDelta::FromMilliseconds(10);
2190 base::TimeTicks time
= base::TimeTicks() + dt
;
2191 WebFloatPoint fling_delta
= WebFloatPoint(1000, 0);
2192 WebPoint fling_point
= WebPoint(7, 13);
2194 time
, blink::WebGestureDeviceTouchscreen
, fling_delta
, fling_point
);
2196 // Cancel the fling. The fling cancellation should be deferred to allow
2197 // fling boosting events to arrive.
2201 // If the new fling is too slow, no boosting should take place, with the new
2202 // fling replacing the old.
2203 WebFloatPoint small_fling_delta
= WebFloatPoint(100, 0);
2204 gesture_
= CreateFling(time
,
2205 blink::WebGestureDeviceTouchscreen
,
2210 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
2212 VERIFY_AND_RESET_MOCKS();
2214 // Note that the new fling delta uses the *slow*, unboosted fling velocity.
2216 float expected_delta
= dt
.InSecondsF() * -small_fling_delta
.x
;
2217 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
2218 EXPECT_CALL(mock_input_handler_
,
2219 ScrollBy(testing::_
,
2220 testing::Property(&gfx::Vector2dF::x
,
2221 testing::Eq(expected_delta
))))
2222 .WillOnce(testing::Return(scroll_result_did_scroll_
));
2225 VERIFY_AND_RESET_MOCKS();
2228 TEST_P(InputHandlerProxyTest
, NoFlingBoostIfPreventBoostingFlagIsSet
) {
2229 base::TimeDelta dt
= base::TimeDelta::FromMilliseconds(10);
2230 base::TimeTicks time
= base::TimeTicks() + dt
;
2231 WebFloatPoint fling_delta
= WebFloatPoint(1000, 0);
2232 WebPoint fling_point
= WebPoint(7, 13);
2235 time
, blink::WebGestureDeviceTouchscreen
, fling_delta
, fling_point
);
2237 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
2239 // Cancel the fling. The fling cancellation should not be deferred because of
2240 // prevent boosting flag set.
2241 gesture_
.data
.flingCancel
.preventBoosting
= true;
2245 // VERIFY_AND_RESET_MOCKS already called by CancelFling
2248 TEST_P(InputHandlerProxyTest
, FlingBoostTerminatedDuringScrollSequence
) {
2249 base::TimeDelta dt
= base::TimeDelta::FromMilliseconds(10);
2250 base::TimeTicks time
= base::TimeTicks() + dt
;
2251 base::TimeTicks last_animate_time
= time
;
2252 WebFloatPoint fling_delta
= WebFloatPoint(1000, 0);
2253 WebPoint fling_point
= WebPoint(7, 13);
2255 time
, blink::WebGestureDeviceTouchscreen
, fling_delta
, fling_point
);
2257 // Now cancel the fling. The fling cancellation should be deferred to allow
2258 // fling boosting events to arrive.
2262 // The GestureScrollBegin should be swallowed by the fling.
2264 gesture_
.timeStampSeconds
= InSecondsF(time
);
2265 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
2266 EXPECT_CALL(mock_input_handler_
,
2267 IsCurrentlyScrollingLayerAt(testing::_
, testing::_
))
2268 .WillOnce(testing::Return(true));
2269 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
2271 VERIFY_AND_RESET_MOCKS();
2273 // Now animate the fling to completion (in this case, the fling should
2274 // terminate because the input handler reports a failed scroll). As the fling
2275 // was cancelled during an active scroll sequence, a synthetic
2276 // GestureScrollBegin should be processed, resuming the scroll.
2278 float expected_delta
=
2279 (time
- last_animate_time
).InSecondsF() * -fling_delta
.x
;
2280 EXPECT_CALL(mock_input_handler_
,
2281 ScrollBy(testing::_
,
2282 testing::Property(&gfx::Vector2dF::x
,
2283 testing::Eq(expected_delta
))))
2284 .WillOnce(testing::Return(scroll_result_did_not_scroll_
));
2285 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
2286 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
2287 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
2290 VERIFY_AND_RESET_MOCKS();
2292 // Subsequent GestureScrollUpdates after the cancelled, boosted fling should
2293 // cause scrolling as usual.
2295 expected_delta
= 7.3f
;
2296 gesture_
.timeStampSeconds
= InSecondsF(time
);
2297 gesture_
.type
= WebInputEvent::GestureScrollUpdate
;
2298 gesture_
.data
.scrollUpdate
.deltaX
= -expected_delta
;
2299 EXPECT_CALL(mock_input_handler_
,
2300 ScrollBy(testing::_
,
2301 testing::Property(&gfx::Vector2dF::x
,
2302 testing::Eq(expected_delta
))))
2303 .WillOnce(testing::Return(scroll_result_did_scroll_
));
2304 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
2306 VERIFY_AND_RESET_MOCKS();
2308 // GestureScrollEnd should terminate the resumed scroll properly.
2310 gesture_
.timeStampSeconds
= InSecondsF(time
);
2311 gesture_
.type
= WebInputEvent::GestureScrollEnd
;
2312 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
2313 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
2315 VERIFY_AND_RESET_MOCKS();
2318 TEST_P(InputHandlerProxyTest
, DidReceiveInputEvent_ForFling
) {
2319 testing::StrictMock
<MockInputHandlerProxyClientWithDidAnimateForInput
>
2321 input_handler_
.reset(
2322 new content::InputHandlerProxy(&mock_input_handler_
, &mock_client
));
2323 if (install_synchronous_handler_
) {
2324 EXPECT_CALL(mock_input_handler_
, RequestUpdateForSynchronousInputHandler())
2326 input_handler_
->SetOnlySynchronouslyAnimateRootFlings(
2327 &mock_synchronous_input_handler_
);
2329 mock_input_handler_
.set_is_scrolling_root(synchronous_root_scroll_
);
2331 gesture_
.type
= WebInputEvent::GestureFlingStart
;
2332 WebFloatPoint fling_delta
= WebFloatPoint(100, 100);
2333 gesture_
.data
.flingStart
.velocityX
= fling_delta
.x
;
2334 gesture_
.data
.flingStart
.velocityY
= fling_delta
.y
;
2335 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
2336 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
2337 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED
));
2338 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
2339 EXPECT_EQ(InputHandlerProxy::DID_HANDLE
,
2340 input_handler_
->HandleInputEvent(gesture_
));
2341 VERIFY_AND_RESET_MOCKS();
2343 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
2344 EXPECT_CALL(mock_client
, DidAnimateForInput());
2345 base::TimeTicks time
= base::TimeTicks() + base::TimeDelta::FromSeconds(10);
2348 VERIFY_AND_RESET_MOCKS();
2351 TEST(SynchronousInputHandlerProxyTest
, StartupShutdown
) {
2352 testing::StrictMock
<MockInputHandler
> mock_input_handler
;
2353 testing::StrictMock
<MockInputHandlerProxyClient
> mock_client
;
2354 testing::StrictMock
<MockSynchronousInputHandler
>
2355 mock_synchronous_input_handler
;
2356 content::InputHandlerProxy
proxy(&mock_input_handler
, &mock_client
);
2358 // When adding a SynchronousInputHandler, immediately request an
2359 // UpdateRootLayerStateForSynchronousInputHandler() call.
2360 EXPECT_CALL(mock_input_handler
, RequestUpdateForSynchronousInputHandler())
2362 proxy
.SetOnlySynchronouslyAnimateRootFlings(&mock_synchronous_input_handler
);
2364 testing::Mock::VerifyAndClearExpectations(&mock_input_handler
);
2365 testing::Mock::VerifyAndClearExpectations(&mock_client
);
2366 testing::Mock::VerifyAndClearExpectations(&mock_synchronous_input_handler
);
2368 EXPECT_CALL(mock_input_handler
, RequestUpdateForSynchronousInputHandler())
2370 proxy
.SetOnlySynchronouslyAnimateRootFlings(nullptr);
2372 testing::Mock::VerifyAndClearExpectations(&mock_input_handler
);
2373 testing::Mock::VerifyAndClearExpectations(&mock_client
);
2374 testing::Mock::VerifyAndClearExpectations(&mock_synchronous_input_handler
);
2377 TEST(SynchronousInputHandlerProxyTest
, UpdateRootLayerState
) {
2378 testing::NiceMock
<MockInputHandler
> mock_input_handler
;
2379 testing::StrictMock
<MockInputHandlerProxyClient
> mock_client
;
2380 testing::StrictMock
<MockSynchronousInputHandler
>
2381 mock_synchronous_input_handler
;
2382 content::InputHandlerProxy
proxy(&mock_input_handler
, &mock_client
);
2384 proxy
.SetOnlySynchronouslyAnimateRootFlings(&mock_synchronous_input_handler
);
2386 // When adding a SynchronousInputHandler, immediately request an
2387 // UpdateRootLayerStateForSynchronousInputHandler() call.
2389 mock_synchronous_input_handler
,
2390 UpdateRootLayerState(gfx::ScrollOffset(1, 2), gfx::ScrollOffset(3, 4),
2391 gfx::SizeF(5, 6), 7, 8, 9))
2393 proxy
.UpdateRootLayerStateForSynchronousInputHandler(
2394 gfx::ScrollOffset(1, 2), gfx::ScrollOffset(3, 4), gfx::SizeF(5, 6), 7, 8,
2397 testing::Mock::VerifyAndClearExpectations(&mock_input_handler
);
2398 testing::Mock::VerifyAndClearExpectations(&mock_client
);
2399 testing::Mock::VerifyAndClearExpectations(&mock_synchronous_input_handler
);
2402 TEST(SynchronousInputHandlerProxyTest
, SetOffset
) {
2403 testing::NiceMock
<MockInputHandler
> mock_input_handler
;
2404 testing::StrictMock
<MockInputHandlerProxyClient
> mock_client
;
2405 testing::StrictMock
<MockSynchronousInputHandler
>
2406 mock_synchronous_input_handler
;
2407 content::InputHandlerProxy
proxy(&mock_input_handler
, &mock_client
);
2409 proxy
.SetOnlySynchronouslyAnimateRootFlings(&mock_synchronous_input_handler
);
2411 EXPECT_CALL(mock_input_handler
, SetSynchronousInputHandlerRootScrollOffset(
2412 gfx::ScrollOffset(5, 6)));
2413 proxy
.SynchronouslySetRootScrollOffset(gfx::ScrollOffset(5, 6));
2415 testing::Mock::VerifyAndClearExpectations(&mock_input_handler
);
2416 testing::Mock::VerifyAndClearExpectations(&mock_client
);
2417 testing::Mock::VerifyAndClearExpectations(&mock_synchronous_input_handler
);
2420 INSTANTIATE_TEST_CASE_P(AnimateInput
,
2421 InputHandlerProxyTest
,
2422 testing::ValuesIn(test_types
));
2425 } // namespace content