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/base/swap_promise_monitor.h"
10 #include "content/common/input/did_overscroll_params.h"
11 #include "content/renderer/input/input_handler_proxy_client.h"
12 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "third_party/WebKit/public/platform/WebFloatPoint.h"
15 #include "third_party/WebKit/public/platform/WebFloatSize.h"
16 #include "third_party/WebKit/public/platform/WebGestureCurve.h"
17 #include "third_party/WebKit/public/platform/WebPoint.h"
18 #include "third_party/WebKit/public/web/WebInputEvent.h"
19 #include "ui/events/latency_info.h"
21 using blink::WebActiveWheelFlingParameters
;
22 using blink::WebFloatPoint
;
23 using blink::WebFloatSize
;
24 using blink::WebGestureDevice
;
25 using blink::WebGestureEvent
;
26 using blink::WebInputEvent
;
27 using blink::WebKeyboardEvent
;
28 using blink::WebMouseWheelEvent
;
29 using blink::WebPoint
;
31 using blink::WebTouchEvent
;
32 using blink::WebTouchPoint
;
37 double InSecondsF(const base::TimeTicks
& time
) {
38 return (time
- base::TimeTicks()).InSecondsF();
41 WebGestureEvent
CreateFling(base::TimeTicks timestamp
,
42 WebGestureDevice source_device
,
43 WebFloatPoint velocity
,
45 WebPoint global_point
,
47 WebGestureEvent fling
;
48 fling
.type
= WebInputEvent::GestureFlingStart
;
49 fling
.sourceDevice
= source_device
;
50 fling
.timeStampSeconds
= (timestamp
- base::TimeTicks()).InSecondsF();
51 fling
.data
.flingStart
.velocityX
= velocity
.x
;
52 fling
.data
.flingStart
.velocityY
= velocity
.y
;
55 fling
.globalX
= global_point
.x
;
56 fling
.globalY
= global_point
.y
;
57 fling
.modifiers
= modifiers
;
61 WebGestureEvent
CreateFling(WebGestureDevice source_device
,
62 WebFloatPoint velocity
,
64 WebPoint global_point
,
66 return CreateFling(base::TimeTicks(),
74 class MockInputHandler
: public cc::InputHandler
{
77 virtual ~MockInputHandler() {}
79 MOCK_METHOD0(PinchGestureBegin
, void());
80 MOCK_METHOD2(PinchGestureUpdate
,
81 void(float magnify_delta
, const gfx::Point
& anchor
));
82 MOCK_METHOD0(PinchGestureEnd
, void());
84 MOCK_METHOD0(SetNeedsAnimate
, void());
86 MOCK_METHOD2(ScrollBegin
,
87 ScrollStatus(const gfx::Point
& viewport_point
,
88 cc::InputHandler::ScrollInputType type
));
89 MOCK_METHOD2(ScrollAnimated
,
90 ScrollStatus(const gfx::Point
& viewport_point
,
91 const gfx::Vector2dF
& scroll_delta
));
92 MOCK_METHOD2(ScrollBy
,
93 bool(const gfx::Point
& viewport_point
,
94 const gfx::Vector2dF
& scroll_delta
));
95 MOCK_METHOD2(ScrollVerticallyByPage
,
96 bool(const gfx::Point
& viewport_point
,
97 cc::ScrollDirection direction
));
98 MOCK_METHOD0(ScrollEnd
, void());
99 MOCK_METHOD0(FlingScrollBegin
, cc::InputHandler::ScrollStatus());
101 virtual scoped_ptr
<cc::SwapPromiseMonitor
>
102 CreateLatencyInfoSwapPromiseMonitor(ui::LatencyInfo
* latency
) OVERRIDE
{
103 return scoped_ptr
<cc::SwapPromiseMonitor
>();
106 virtual void BindToClient(cc::InputHandlerClient
* client
) OVERRIDE
{}
108 virtual void StartPageScaleAnimation(const gfx::Vector2d
& target_offset
,
111 base::TimeDelta duration
) OVERRIDE
{}
113 virtual void MouseMoveAt(const gfx::Point
& mouse_position
) OVERRIDE
{}
115 MOCK_METHOD2(IsCurrentlyScrollingLayerAt
,
116 bool(const gfx::Point
& point
,
117 cc::InputHandler::ScrollInputType type
));
119 MOCK_METHOD1(HaveTouchEventHandlersAt
, bool(const gfx::Point
& point
));
121 virtual void SetRootLayerScrollOffsetDelegate(
122 cc::LayerScrollOffsetDelegate
* root_layer_scroll_offset_delegate
)
125 virtual void OnRootLayerDelegatedScrollOffsetChanged() OVERRIDE
{}
127 DISALLOW_COPY_AND_ASSIGN(MockInputHandler
);
130 // A simple WebGestureCurve implementation that flings at a constant velocity
132 class FakeWebGestureCurve
: public blink::WebGestureCurve
{
134 FakeWebGestureCurve(const blink::WebFloatSize
& velocity
,
135 const blink::WebFloatSize
& cumulative_scroll
)
136 : velocity_(velocity
), cumulative_scroll_(cumulative_scroll
) {}
138 virtual ~FakeWebGestureCurve() {}
140 // Returns false if curve has finished and can no longer be applied.
141 virtual bool apply(double time
, blink::WebGestureCurveTarget
* target
) {
142 blink::WebFloatSize
displacement(velocity_
.width
* time
,
143 velocity_
.height
* time
);
144 blink::WebFloatSize
increment(
145 displacement
.width
- cumulative_scroll_
.width
,
146 displacement
.height
- cumulative_scroll_
.height
);
147 cumulative_scroll_
= displacement
;
148 // scrollBy() could delete this curve if the animation is over, so don't
149 // touch any member variables after making that call.
150 return target
->scrollBy(increment
, velocity_
);
154 blink::WebFloatSize velocity_
;
155 blink::WebFloatSize cumulative_scroll_
;
157 DISALLOW_COPY_AND_ASSIGN(FakeWebGestureCurve
);
160 class MockInputHandlerProxyClient
161 : public content::InputHandlerProxyClient
{
163 MockInputHandlerProxyClient() {}
164 virtual ~MockInputHandlerProxyClient() {}
166 virtual void WillShutdown() OVERRIDE
{}
168 MOCK_METHOD1(TransferActiveWheelFlingAnimation
,
169 void(const WebActiveWheelFlingParameters
&));
171 virtual blink::WebGestureCurve
* CreateFlingAnimationCurve(
172 WebGestureDevice deviceSource
,
173 const WebFloatPoint
& velocity
,
174 const WebSize
& cumulative_scroll
) OVERRIDE
{
175 return new FakeWebGestureCurve(
176 blink::WebFloatSize(velocity
.x
, velocity
.y
),
177 blink::WebFloatSize(cumulative_scroll
.width
, cumulative_scroll
.height
));
180 MOCK_METHOD1(DidOverscroll
, void(const DidOverscrollParams
&));
181 virtual void DidStopFlinging() OVERRIDE
{}
184 DISALLOW_COPY_AND_ASSIGN(MockInputHandlerProxyClient
);
187 WebTouchPoint
CreateWebTouchPoint(WebTouchPoint::State state
, float x
,
191 point
.screenPosition
= WebFloatPoint(x
, y
);
192 point
.position
= WebFloatPoint(x
, y
);
196 class InputHandlerProxyTest
: public testing::Test
{
198 InputHandlerProxyTest()
199 : expected_disposition_(InputHandlerProxy::DID_HANDLE
) {
200 input_handler_
.reset(
201 new content::InputHandlerProxy(&mock_input_handler_
, &mock_client_
));
204 ~InputHandlerProxyTest() {
205 input_handler_
.reset();
208 // This is defined as a macro because when an expectation is not satisfied the
209 // only output you get
210 // out of gmock is the line number that set the expectation.
211 #define VERIFY_AND_RESET_MOCKS() \
213 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); \
214 testing::Mock::VerifyAndClearExpectations(&mock_client_); \
217 void StartFling(base::TimeTicks timestamp
,
218 WebGestureDevice source_device
,
219 WebFloatPoint velocity
,
221 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
222 VERIFY_AND_RESET_MOCKS();
224 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
225 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
226 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
227 gesture_
.sourceDevice
= source_device
;
228 EXPECT_EQ(expected_disposition_
,
229 input_handler_
->HandleInputEvent(gesture_
));
231 VERIFY_AND_RESET_MOCKS();
233 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
234 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
235 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
238 CreateFling(timestamp
, source_device
, velocity
, position
, position
, 0);
239 EXPECT_EQ(expected_disposition_
,
240 input_handler_
->HandleInputEvent(gesture_
));
242 VERIFY_AND_RESET_MOCKS();
245 void CancelFling(base::TimeTicks timestamp
) {
246 gesture_
.timeStampSeconds
= InSecondsF(timestamp
);
247 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
248 EXPECT_EQ(expected_disposition_
,
249 input_handler_
->HandleInputEvent(gesture_
));
251 VERIFY_AND_RESET_MOCKS();
255 testing::StrictMock
<MockInputHandler
> mock_input_handler_
;
256 scoped_ptr
<content::InputHandlerProxy
> input_handler_
;
257 testing::StrictMock
<MockInputHandlerProxyClient
> mock_client_
;
258 WebGestureEvent gesture_
;
260 InputHandlerProxy::EventDisposition expected_disposition_
;
263 TEST_F(InputHandlerProxyTest
, MouseWheelByPageMainThread
) {
264 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
265 WebMouseWheelEvent wheel
;
266 wheel
.type
= WebInputEvent::MouseWheel
;
267 wheel
.scrollByPage
= true;
269 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(wheel
));
270 testing::Mock::VerifyAndClearExpectations(&mock_client_
);
273 TEST_F(InputHandlerProxyTest
, MouseWheelWithCtrl
) {
274 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
275 WebMouseWheelEvent wheel
;
276 wheel
.type
= WebInputEvent::MouseWheel
;
277 wheel
.modifiers
= WebInputEvent::ControlKey
;
279 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(wheel
));
280 testing::Mock::VerifyAndClearExpectations(&mock_client_
);
283 TEST_F(InputHandlerProxyTest
, GestureScrollStarted
) {
284 // We shouldn't send any events to the widget for this gesture.
285 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
286 VERIFY_AND_RESET_MOCKS();
288 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
289 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
291 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
292 EXPECT_EQ(expected_disposition_
,input_handler_
->HandleInputEvent(gesture_
));
294 // The event should not be marked as handled if scrolling is not possible.
295 expected_disposition_
= InputHandlerProxy::DROP_EVENT
;
296 VERIFY_AND_RESET_MOCKS();
298 gesture_
.type
= WebInputEvent::GestureScrollUpdate
;
299 gesture_
.data
.scrollUpdate
.deltaY
=
300 -40; // -Y means scroll down - i.e. in the +Y direction.
301 EXPECT_CALL(mock_input_handler_
,
303 testing::Property(&gfx::Vector2dF::y
, testing::Gt(0))))
304 .WillOnce(testing::Return(false));
305 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
307 // Mark the event as handled if scroll happens.
308 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
309 VERIFY_AND_RESET_MOCKS();
311 gesture_
.type
= WebInputEvent::GestureScrollUpdate
;
312 gesture_
.data
.scrollUpdate
.deltaY
=
313 -40; // -Y means scroll down - i.e. in the +Y direction.
314 EXPECT_CALL(mock_input_handler_
,
316 testing::Property(&gfx::Vector2dF::y
, testing::Gt(0))))
317 .WillOnce(testing::Return(true));
318 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
320 VERIFY_AND_RESET_MOCKS();
322 gesture_
.type
= WebInputEvent::GestureScrollEnd
;
323 gesture_
.data
.scrollUpdate
.deltaY
= 0;
324 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
325 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
328 TEST_F(InputHandlerProxyTest
, GestureScrollOnMainThread
) {
329 // We should send all events to the widget for this gesture.
330 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
331 VERIFY_AND_RESET_MOCKS();
333 EXPECT_CALL(mock_input_handler_
, ScrollBegin(::testing::_
, ::testing::_
))
334 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread
));
336 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
337 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
339 VERIFY_AND_RESET_MOCKS();
341 gesture_
.type
= WebInputEvent::GestureScrollUpdate
;
342 gesture_
.data
.scrollUpdate
.deltaY
= 40;
343 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
345 VERIFY_AND_RESET_MOCKS();
347 gesture_
.type
= WebInputEvent::GestureScrollEnd
;
348 gesture_
.data
.scrollUpdate
.deltaY
= 0;
349 EXPECT_CALL(mock_input_handler_
, ScrollEnd()).WillOnce(testing::Return());
350 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
353 TEST_F(InputHandlerProxyTest
, GestureScrollIgnored
) {
354 // We shouldn't handle the GestureScrollBegin.
355 // Instead, we should get a DROP_EVENT result, indicating
356 // that we could determine that there's nothing that could scroll or otherwise
357 // react to this gesture sequence and thus we should drop the whole gesture
358 // sequence on the floor, except for the ScrollEnd.
359 expected_disposition_
= InputHandlerProxy::DROP_EVENT
;
360 VERIFY_AND_RESET_MOCKS();
362 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
363 .WillOnce(testing::Return(cc::InputHandler::ScrollIgnored
));
365 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
366 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
368 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
369 gesture_
.type
= WebInputEvent::GestureScrollEnd
;
370 EXPECT_CALL(mock_input_handler_
, ScrollEnd()).WillOnce(testing::Return());
371 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
374 TEST_F(InputHandlerProxyTest
, GesturePinch
) {
375 // We shouldn't send any events to the widget for this gesture.
376 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
377 VERIFY_AND_RESET_MOCKS();
379 gesture_
.type
= WebInputEvent::GesturePinchBegin
;
380 EXPECT_CALL(mock_input_handler_
, PinchGestureBegin());
381 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
383 VERIFY_AND_RESET_MOCKS();
385 gesture_
.type
= WebInputEvent::GesturePinchUpdate
;
386 gesture_
.data
.pinchUpdate
.scale
= 1.5;
389 EXPECT_CALL(mock_input_handler_
, PinchGestureUpdate(1.5, gfx::Point(7, 13)));
390 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
392 VERIFY_AND_RESET_MOCKS();
394 gesture_
.type
= WebInputEvent::GesturePinchUpdate
;
395 gesture_
.data
.pinchUpdate
.scale
= 0.5;
398 EXPECT_CALL(mock_input_handler_
, PinchGestureUpdate(.5, gfx::Point(9, 6)));
399 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
401 VERIFY_AND_RESET_MOCKS();
403 gesture_
.type
= WebInputEvent::GesturePinchEnd
;
404 EXPECT_CALL(mock_input_handler_
, PinchGestureEnd());
405 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
408 TEST_F(InputHandlerProxyTest
, GesturePinchAfterScrollOnMainThread
) {
409 // Scrolls will start by being sent to the main thread.
410 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
411 VERIFY_AND_RESET_MOCKS();
413 EXPECT_CALL(mock_input_handler_
, ScrollBegin(::testing::_
, ::testing::_
))
414 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread
));
416 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
417 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
419 VERIFY_AND_RESET_MOCKS();
421 gesture_
.type
= WebInputEvent::GestureScrollUpdate
;
422 gesture_
.data
.scrollUpdate
.deltaY
= 40;
423 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
425 // However, after the pinch gesture starts, they should go to the impl
427 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
428 VERIFY_AND_RESET_MOCKS();
430 gesture_
.type
= WebInputEvent::GesturePinchBegin
;
431 EXPECT_CALL(mock_input_handler_
, PinchGestureBegin());
432 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
434 VERIFY_AND_RESET_MOCKS();
436 gesture_
.type
= WebInputEvent::GesturePinchUpdate
;
437 gesture_
.data
.pinchUpdate
.scale
= 1.5;
440 EXPECT_CALL(mock_input_handler_
, PinchGestureUpdate(1.5, gfx::Point(7, 13)));
441 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
443 VERIFY_AND_RESET_MOCKS();
445 gesture_
.type
= WebInputEvent::GestureScrollUpdate
;
446 gesture_
.data
.scrollUpdate
.deltaY
=
447 -40; // -Y means scroll down - i.e. in the +Y direction.
448 EXPECT_CALL(mock_input_handler_
,
450 testing::Property(&gfx::Vector2dF::y
, testing::Gt(0))))
451 .WillOnce(testing::Return(true));
452 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
454 VERIFY_AND_RESET_MOCKS();
456 gesture_
.type
= WebInputEvent::GesturePinchUpdate
;
457 gesture_
.data
.pinchUpdate
.scale
= 0.5;
460 EXPECT_CALL(mock_input_handler_
, PinchGestureUpdate(.5, gfx::Point(9, 6)));
461 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
463 VERIFY_AND_RESET_MOCKS();
465 gesture_
.type
= WebInputEvent::GesturePinchEnd
;
466 EXPECT_CALL(mock_input_handler_
, PinchGestureEnd());
467 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
469 // After the pinch gesture ends, they should go to back to the main
471 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
472 VERIFY_AND_RESET_MOCKS();
474 gesture_
.type
= WebInputEvent::GestureScrollEnd
;
475 gesture_
.data
.scrollUpdate
.deltaY
= 0;
476 EXPECT_CALL(mock_input_handler_
, ScrollEnd())
477 .WillOnce(testing::Return());
478 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
481 TEST_F(InputHandlerProxyTest
, GestureFlingStartedTouchpad
) {
482 // We shouldn't send any events to the widget for this gesture.
483 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
484 VERIFY_AND_RESET_MOCKS();
486 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
487 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
488 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
489 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
491 gesture_
.type
= WebInputEvent::GestureFlingStart
;
492 gesture_
.data
.flingStart
.velocityX
= 10;
493 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchpad
;
494 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
496 VERIFY_AND_RESET_MOCKS();
498 // Verify that a GestureFlingCancel during an animation cancels it.
499 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
500 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchpad
;
501 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
504 TEST_F(InputHandlerProxyTest
, GestureFlingOnMainThreadTouchpad
) {
505 // We should send all events to the widget for this gesture.
506 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
507 VERIFY_AND_RESET_MOCKS();
509 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
510 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread
));
512 gesture_
.type
= WebInputEvent::GestureFlingStart
;
513 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchpad
;
514 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
516 // Since we returned ScrollStatusOnMainThread from scrollBegin, ensure the
517 // input handler knows it's scrolling off the impl thread
518 ASSERT_FALSE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
520 VERIFY_AND_RESET_MOCKS();
522 // Even if we didn't start a fling ourselves, we still need to send the cancel
523 // event to the widget.
524 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
525 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchpad
;
526 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
529 TEST_F(InputHandlerProxyTest
, GestureFlingIgnoredTouchpad
) {
530 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
531 VERIFY_AND_RESET_MOCKS();
533 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
534 .WillOnce(testing::Return(cc::InputHandler::ScrollIgnored
));
536 gesture_
.type
= WebInputEvent::GestureFlingStart
;
537 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchpad
;
538 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
540 expected_disposition_
= InputHandlerProxy::DROP_EVENT
;
541 VERIFY_AND_RESET_MOCKS();
543 // Since the previous fling was ignored, we should also be dropping the next
545 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
546 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchpad
;
547 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
550 TEST_F(InputHandlerProxyTest
, GestureFlingAnimatesTouchpad
) {
551 // We shouldn't send any events to the widget for this gesture.
552 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
553 VERIFY_AND_RESET_MOCKS();
555 // On the fling start, we should schedule an animation but not actually start
557 gesture_
.type
= WebInputEvent::GestureFlingStart
;
558 WebFloatPoint fling_delta
= WebFloatPoint(1000, 0);
559 WebPoint fling_point
= WebPoint(7, 13);
560 WebPoint fling_global_point
= WebPoint(17, 23);
561 // Note that for trackpad, wheel events with the Control modifier are
562 // special (reserved for zoom), so don't set that here.
563 int modifiers
= WebInputEvent::ShiftKey
| WebInputEvent::AltKey
;
564 gesture_
= CreateFling(blink::WebGestureDeviceTouchpad
,
569 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
570 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
571 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
572 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
573 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
575 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
576 // The first animate call should let us pick up an animation start time, but
577 // we shouldn't actually move anywhere just yet. The first frame after the
578 // fling start will typically include the last scroll from the gesture that
579 // lead to the scroll (either wheel or gesture scroll), so there should be no
581 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
582 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
584 base::TimeTicks time
= base::TimeTicks() + base::TimeDelta::FromSeconds(10);
585 input_handler_
->Animate(time
);
587 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
589 // The second call should start scrolling in the -X direction.
590 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
591 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
592 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
593 EXPECT_CALL(mock_input_handler_
,
595 testing::Property(&gfx::Vector2dF::x
, testing::Lt(0))))
596 .WillOnce(testing::Return(true));
597 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
598 time
+= base::TimeDelta::FromMilliseconds(100);
599 input_handler_
->Animate(time
);
601 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
603 // Let's say on the third call we hit a non-scrollable region. We should abort
604 // the fling and not scroll.
605 // We also should pass the current fling parameters out to the client so the
606 // rest of the fling can be
607 // transferred to the main thread.
608 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
609 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread
));
610 EXPECT_CALL(mock_input_handler_
, ScrollBy(testing::_
, testing::_
)).Times(0);
611 EXPECT_CALL(mock_input_handler_
, ScrollEnd()).Times(0);
612 // Expected wheel fling animation parameters:
613 // *) fling_delta and fling_point should match the original GestureFlingStart
615 // *) startTime should be 10 to match the time parameter of the first
616 // Animate() call after the GestureFlingStart
617 // *) cumulativeScroll depends on the curve, but since we've animated in the
618 // -X direction the X value should be < 0
621 TransferActiveWheelFlingAnimation(testing::AllOf(
622 testing::Field(&WebActiveWheelFlingParameters::delta
,
623 testing::Eq(fling_delta
)),
624 testing::Field(&WebActiveWheelFlingParameters::point
,
625 testing::Eq(fling_point
)),
626 testing::Field(&WebActiveWheelFlingParameters::globalPoint
,
627 testing::Eq(fling_global_point
)),
628 testing::Field(&WebActiveWheelFlingParameters::modifiers
,
629 testing::Eq(modifiers
)),
630 testing::Field(&WebActiveWheelFlingParameters::startTime
,
632 testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll
,
633 testing::Field(&WebSize::width
, testing::Gt(0))))));
634 time
+= base::TimeDelta::FromMilliseconds(100);
635 input_handler_
->Animate(time
);
637 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
638 testing::Mock::VerifyAndClearExpectations(&mock_client_
);
640 // Since we've aborted the fling, the next animation should be a no-op and
641 // should not result in another
642 // frame being requested.
643 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate()).Times(0);
644 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
646 time
+= base::TimeDelta::FromMilliseconds(100);
647 input_handler_
->Animate(time
);
649 // Since we've transferred the fling to the main thread, we need to pass the
650 // next GestureFlingCancel to the main
652 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
653 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
654 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
657 TEST_F(InputHandlerProxyTest
, GestureFlingTransferResetsTouchpad
) {
658 // We shouldn't send any events to the widget for this gesture.
659 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
660 VERIFY_AND_RESET_MOCKS();
662 // Start a gesture fling in the -X direction with zero Y movement.
663 WebFloatPoint fling_delta
= WebFloatPoint(1000, 0);
664 WebPoint fling_point
= WebPoint(7, 13);
665 WebPoint fling_global_point
= WebPoint(17, 23);
666 // Note that for trackpad, wheel events with the Control modifier are
667 // special (reserved for zoom), so don't set that here.
668 int modifiers
= WebInputEvent::ShiftKey
| WebInputEvent::AltKey
;
669 gesture_
= CreateFling(blink::WebGestureDeviceTouchpad
,
674 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
675 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
676 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
677 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
678 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
680 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
682 // Start the fling animation at time 10. This shouldn't actually scroll, just
683 // establish a start time.
684 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
685 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
687 base::TimeTicks time
= base::TimeTicks() + base::TimeDelta::FromSeconds(10);
688 input_handler_
->Animate(time
);
690 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
692 // The second call should start scrolling in the -X direction.
693 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
694 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
695 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
696 EXPECT_CALL(mock_input_handler_
,
698 testing::Property(&gfx::Vector2dF::x
, testing::Lt(0))))
699 .WillOnce(testing::Return(true));
700 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
701 time
+= base::TimeDelta::FromMilliseconds(100);
702 input_handler_
->Animate(time
);
704 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
706 // Let's say on the third call we hit a non-scrollable region. We should abort
707 // the fling and not scroll.
708 // We also should pass the current fling parameters out to the client so the
709 // rest of the fling can be
710 // transferred to the main thread.
711 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
712 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread
));
713 EXPECT_CALL(mock_input_handler_
, ScrollBy(testing::_
, testing::_
)).Times(0);
714 EXPECT_CALL(mock_input_handler_
, ScrollEnd()).Times(0);
716 // Expected wheel fling animation parameters:
717 // *) fling_delta and fling_point should match the original GestureFlingStart
719 // *) startTime should be 10 to match the time parameter of the first
720 // Animate() call after the GestureFlingStart
721 // *) cumulativeScroll depends on the curve, but since we've animated in the
722 // -X direction the X value should be < 0
725 TransferActiveWheelFlingAnimation(testing::AllOf(
726 testing::Field(&WebActiveWheelFlingParameters::delta
,
727 testing::Eq(fling_delta
)),
728 testing::Field(&WebActiveWheelFlingParameters::point
,
729 testing::Eq(fling_point
)),
730 testing::Field(&WebActiveWheelFlingParameters::globalPoint
,
731 testing::Eq(fling_global_point
)),
732 testing::Field(&WebActiveWheelFlingParameters::modifiers
,
733 testing::Eq(modifiers
)),
734 testing::Field(&WebActiveWheelFlingParameters::startTime
,
736 testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll
,
737 testing::Field(&WebSize::width
, testing::Gt(0))))));
738 time
+= base::TimeDelta::FromMilliseconds(100);
739 input_handler_
->Animate(time
);
741 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
742 testing::Mock::VerifyAndClearExpectations(&mock_client_
);
744 // Since we've aborted the fling, the next animation should be a no-op and
745 // should not result in another
746 // frame being requested.
747 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate()).Times(0);
748 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
750 time
+= base::TimeDelta::FromMilliseconds(100);
751 input_handler_
->Animate(time
);
753 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
755 // Since we've transferred the fling to the main thread, we need to pass the
756 // next GestureFlingCancel to the main
758 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
759 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
760 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
762 VERIFY_AND_RESET_MOCKS();
763 input_handler_
->MainThreadHasStoppedFlinging();
765 // Start a second gesture fling, this time in the +Y direction with no X.
766 fling_delta
= WebFloatPoint(0, -1000);
767 fling_point
= WebPoint(95, 87);
768 fling_global_point
= WebPoint(32, 71);
769 modifiers
= WebInputEvent::AltKey
;
770 gesture_
= CreateFling(blink::WebGestureDeviceTouchpad
,
775 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
776 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
777 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
778 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
779 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
780 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
782 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
784 // Start the second fling animation at time 30.
785 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
786 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
788 time
= base::TimeTicks() + base::TimeDelta::FromSeconds(30);
789 input_handler_
->Animate(time
);
791 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
793 // Tick the second fling once normally.
794 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
795 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
796 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
797 EXPECT_CALL(mock_input_handler_
,
799 testing::Property(&gfx::Vector2dF::y
, testing::Gt(0))))
800 .WillOnce(testing::Return(true));
801 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
802 time
+= base::TimeDelta::FromMilliseconds(100);
803 input_handler_
->Animate(time
);
805 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
807 // Then abort the second fling.
808 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
809 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread
));
810 EXPECT_CALL(mock_input_handler_
, ScrollBy(testing::_
, testing::_
)).Times(0);
811 EXPECT_CALL(mock_input_handler_
, ScrollEnd()).Times(0);
813 // We should get parameters from the second fling, nothing from the first
814 // fling should "leak".
817 TransferActiveWheelFlingAnimation(testing::AllOf(
818 testing::Field(&WebActiveWheelFlingParameters::delta
,
819 testing::Eq(fling_delta
)),
820 testing::Field(&WebActiveWheelFlingParameters::point
,
821 testing::Eq(fling_point
)),
822 testing::Field(&WebActiveWheelFlingParameters::globalPoint
,
823 testing::Eq(fling_global_point
)),
824 testing::Field(&WebActiveWheelFlingParameters::modifiers
,
825 testing::Eq(modifiers
)),
826 testing::Field(&WebActiveWheelFlingParameters::startTime
,
828 testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll
,
829 testing::Field(&WebSize::height
, testing::Lt(0))))));
830 time
+= base::TimeDelta::FromMilliseconds(100);
831 input_handler_
->Animate(time
);
834 TEST_F(InputHandlerProxyTest
, GestureFlingStartedTouchscreen
) {
835 // We shouldn't send any events to the widget for this gesture.
836 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
837 VERIFY_AND_RESET_MOCKS();
839 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
840 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
841 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
842 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
843 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
845 VERIFY_AND_RESET_MOCKS();
847 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
848 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
849 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
851 gesture_
.type
= WebInputEvent::GestureFlingStart
;
852 gesture_
.data
.flingStart
.velocityX
= 10;
853 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
854 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
856 VERIFY_AND_RESET_MOCKS();
858 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
860 // Verify that a GestureFlingCancel during an animation cancels it.
861 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
862 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
863 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
866 TEST_F(InputHandlerProxyTest
, GestureFlingOnMainThreadTouchscreen
) {
867 // We should send all events to the widget for this gesture.
868 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
869 VERIFY_AND_RESET_MOCKS();
871 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
872 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread
));
874 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
875 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
877 VERIFY_AND_RESET_MOCKS();
879 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin()).Times(0);
881 gesture_
.type
= WebInputEvent::GestureFlingStart
;
882 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
883 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
885 VERIFY_AND_RESET_MOCKS();
887 // Even if we didn't start a fling ourselves, we still need to send the cancel
888 // event to the widget.
889 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
890 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
891 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
894 TEST_F(InputHandlerProxyTest
, GestureFlingIgnoredTouchscreen
) {
895 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
896 VERIFY_AND_RESET_MOCKS();
898 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
899 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
901 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
902 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
903 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
905 expected_disposition_
= InputHandlerProxy::DROP_EVENT
;
906 VERIFY_AND_RESET_MOCKS();
908 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
909 .WillOnce(testing::Return(cc::InputHandler::ScrollIgnored
));
911 gesture_
.type
= WebInputEvent::GestureFlingStart
;
912 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
913 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
915 VERIFY_AND_RESET_MOCKS();
917 // Even if we didn't start a fling ourselves, we still need to send the cancel
918 // event to the widget.
919 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
920 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
921 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
924 TEST_F(InputHandlerProxyTest
, GestureFlingAnimatesTouchscreen
) {
925 // We shouldn't send any events to the widget for this gesture.
926 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
927 VERIFY_AND_RESET_MOCKS();
929 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
930 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
932 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
933 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
934 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
936 VERIFY_AND_RESET_MOCKS();
938 // On the fling start, we should schedule an animation but not actually start
940 WebFloatPoint fling_delta
= WebFloatPoint(100, 0);
941 WebPoint fling_point
= WebPoint(7, 13);
942 WebPoint fling_global_point
= WebPoint(17, 23);
943 // Note that for touchscreen the control modifier is not special.
944 int modifiers
= WebInputEvent::ControlKey
;
945 gesture_
= CreateFling(blink::WebGestureDeviceTouchscreen
,
950 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
951 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
952 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
953 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
955 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
956 // The first animate call should let us pick up an animation start time, but
957 // we shouldn't actually move anywhere just yet. The first frame after the
958 // fling start will typically include the last scroll from the gesture that
959 // lead to the scroll (either wheel or gesture scroll), so there should be no
961 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
962 base::TimeTicks time
= base::TimeTicks() + base::TimeDelta::FromSeconds(10);
963 input_handler_
->Animate(time
);
965 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
967 // The second call should start scrolling in the -X direction.
968 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
969 EXPECT_CALL(mock_input_handler_
,
971 testing::Property(&gfx::Vector2dF::x
, testing::Lt(0))))
972 .WillOnce(testing::Return(true));
973 time
+= base::TimeDelta::FromMilliseconds(100);
974 input_handler_
->Animate(time
);
976 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
978 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
979 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
980 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
983 TEST_F(InputHandlerProxyTest
, GestureFlingWithValidTimestamp
) {
984 // We shouldn't send any events to the widget for this gesture.
985 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
986 VERIFY_AND_RESET_MOCKS();
988 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
989 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
991 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
992 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
993 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
995 VERIFY_AND_RESET_MOCKS();
997 // On the fling start, we should schedule an animation but not actually start
999 base::TimeDelta dt
= base::TimeDelta::FromMilliseconds(10);
1000 base::TimeTicks time
= base::TimeTicks() + dt
;
1001 WebFloatPoint fling_delta
= WebFloatPoint(100, 0);
1002 WebPoint fling_point
= WebPoint(7, 13);
1003 WebPoint fling_global_point
= WebPoint(17, 23);
1004 int modifiers
= WebInputEvent::ControlKey
;
1005 gesture_
= CreateFling(time
,
1006 blink::WebGestureDeviceTouchscreen
,
1011 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
1012 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
1013 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
1014 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1016 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
1017 // With a valid time stamp, the first animate call should skip start time
1018 // initialization and immediately begin scroll update production. This reduces
1019 // the likelihood of a hitch between the scroll preceding the fling and
1020 // the first scroll generated by the fling.
1021 // Scrolling should start in the -X direction.
1022 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
1023 EXPECT_CALL(mock_input_handler_
,
1024 ScrollBy(testing::_
,
1025 testing::Property(&gfx::Vector2dF::x
, testing::Lt(0))))
1026 .WillOnce(testing::Return(true));
1028 input_handler_
->Animate(time
);
1030 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
1032 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1033 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
1034 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1037 TEST_F(InputHandlerProxyTest
, GestureFlingWithInvalidTimestamp
) {
1038 // We shouldn't send any events to the widget for this gesture.
1039 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1040 VERIFY_AND_RESET_MOCKS();
1042 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1043 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
1045 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1046 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1047 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1049 VERIFY_AND_RESET_MOCKS();
1051 // On the fling start, we should schedule an animation but not actually start
1053 base::TimeDelta start_time_offset
= base::TimeDelta::FromMilliseconds(10);
1054 gesture_
.type
= WebInputEvent::GestureFlingStart
;
1055 WebFloatPoint fling_delta
= WebFloatPoint(100, 0);
1056 WebPoint fling_point
= WebPoint(7, 13);
1057 WebPoint fling_global_point
= WebPoint(17, 23);
1058 int modifiers
= WebInputEvent::ControlKey
;
1059 gesture_
.timeStampSeconds
= start_time_offset
.InSecondsF();
1060 gesture_
.data
.flingStart
.velocityX
= fling_delta
.x
;
1061 gesture_
.data
.flingStart
.velocityY
= fling_delta
.y
;
1062 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1063 gesture_
.x
= fling_point
.x
;
1064 gesture_
.y
= fling_point
.y
;
1065 gesture_
.globalX
= fling_global_point
.x
;
1066 gesture_
.globalY
= fling_global_point
.y
;
1067 gesture_
.modifiers
= modifiers
;
1068 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
1069 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
1070 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
1071 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1073 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
1074 // Event though a time stamp was provided for the fling event, it will be
1075 // ignored as its too far in the past relative to the first animate call's
1077 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
1078 base::TimeTicks time
=
1079 base::TimeTicks() + start_time_offset
+ base::TimeDelta::FromSeconds(1);
1080 input_handler_
->Animate(time
);
1082 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
1084 // Further animation ticks should update the fling as usual.
1085 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
1086 EXPECT_CALL(mock_input_handler_
,
1087 ScrollBy(testing::_
,
1088 testing::Property(&gfx::Vector2dF::x
, testing::Lt(0))))
1089 .WillOnce(testing::Return(true));
1090 time
+= base::TimeDelta::FromMilliseconds(10);
1091 input_handler_
->Animate(time
);
1093 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
1095 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1096 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
1097 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1100 TEST_F(InputHandlerProxyTest
,
1101 GestureScrollOnImplThreadFlagClearedAfterFling
) {
1102 // We shouldn't send any events to the widget for this gesture.
1103 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1104 VERIFY_AND_RESET_MOCKS();
1106 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1107 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
1109 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1110 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1112 // After sending a GestureScrollBegin, the member variable
1113 // |gesture_scroll_on_impl_thread_| should be true.
1114 EXPECT_TRUE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1116 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1117 VERIFY_AND_RESET_MOCKS();
1119 // On the fling start, we should schedule an animation but not actually start
1121 WebFloatPoint fling_delta
= WebFloatPoint(100, 0);
1122 WebPoint fling_point
= WebPoint(7, 13);
1123 WebPoint fling_global_point
= WebPoint(17, 23);
1124 int modifiers
= WebInputEvent::ControlKey
| WebInputEvent::AltKey
;
1125 gesture_
= CreateFling(blink::WebGestureDeviceTouchscreen
,
1130 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
1131 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
1132 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
1133 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1135 // |gesture_scroll_on_impl_thread_| should still be true after
1136 // a GestureFlingStart is sent.
1137 EXPECT_TRUE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1139 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
1140 // The first animate call should let us pick up an animation start time, but
1141 // we shouldn't actually move anywhere just yet. The first frame after the
1142 // fling start will typically include the last scroll from the gesture that
1143 // lead to the scroll (either wheel or gesture scroll), so there should be no
1145 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
1146 base::TimeTicks time
= base::TimeTicks() + base::TimeDelta::FromSeconds(10);
1147 input_handler_
->Animate(time
);
1149 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
1151 // The second call should start scrolling in the -X direction.
1152 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
1153 EXPECT_CALL(mock_input_handler_
,
1154 ScrollBy(testing::_
,
1155 testing::Property(&gfx::Vector2dF::x
, testing::Lt(0))))
1156 .WillOnce(testing::Return(true));
1157 time
+= base::TimeDelta::FromMilliseconds(100);
1158 input_handler_
->Animate(time
);
1160 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
1162 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1163 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
1164 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1166 // |gesture_scroll_on_impl_thread_| should be false once
1167 // the fling has finished (note no GestureScrollEnd has been sent).
1168 EXPECT_TRUE(!input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1171 TEST_F(InputHandlerProxyTest
, GestureFlingStopsAtContentEdge
) {
1172 // We shouldn't send any events to the widget for this gesture.
1173 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1174 VERIFY_AND_RESET_MOCKS();
1176 // On the fling start, we should schedule an animation but not actually start
1178 gesture_
.type
= WebInputEvent::GestureFlingStart
;
1179 WebFloatPoint fling_delta
= WebFloatPoint(100, 100);
1180 gesture_
.data
.flingStart
.velocityX
= fling_delta
.x
;
1181 gesture_
.data
.flingStart
.velocityY
= fling_delta
.y
;
1182 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
1183 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1184 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
1185 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1186 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1187 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
1189 // The first animate doesn't cause any scrolling.
1190 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
1191 base::TimeTicks time
= base::TimeTicks() + base::TimeDelta::FromSeconds(10);
1192 input_handler_
->Animate(time
);
1193 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
1195 // The second animate starts scrolling in the positive X and Y directions.
1196 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
1197 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1198 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
1199 EXPECT_CALL(mock_input_handler_
,
1200 ScrollBy(testing::_
,
1201 testing::Property(&gfx::Vector2dF::y
, testing::Lt(0))))
1202 .WillOnce(testing::Return(true));
1203 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1204 time
+= base::TimeDelta::FromMilliseconds(100);
1205 input_handler_
->Animate(time
);
1206 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
1208 // Simulate hitting the bottom content edge.
1209 gfx::Vector2dF
accumulated_overscroll(0, 100);
1210 gfx::Vector2dF
latest_overscroll_delta(0, 10);
1211 gfx::PointF
scroll_point(10, 0);
1214 DidOverscroll(testing::AllOf(
1215 testing::Field(&DidOverscrollParams::accumulated_overscroll
,
1216 testing::Eq(accumulated_overscroll
)),
1217 testing::Field(&DidOverscrollParams::latest_overscroll_delta
,
1218 testing::Eq(latest_overscroll_delta
)),
1219 testing::Field(&DidOverscrollParams::current_fling_velocity
,
1220 testing::Property(&gfx::Vector2dF::y
, testing::Lt(0))),
1221 testing::Field(&DidOverscrollParams::causal_event_viewport_point
,
1222 testing::Eq(scroll_point
)))));
1223 input_handler_
->DidOverscroll(
1224 scroll_point
, accumulated_overscroll
, latest_overscroll_delta
);
1226 // The next call to animate will no longer scroll vertically.
1227 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
1228 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1229 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
1230 EXPECT_CALL(mock_input_handler_
,
1231 ScrollBy(testing::_
,
1232 testing::Property(&gfx::Vector2dF::y
, testing::Eq(0))))
1233 .WillOnce(testing::Return(true));
1234 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1235 time
+= base::TimeDelta::FromMilliseconds(100);
1236 input_handler_
->Animate(time
);
1237 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
1240 TEST_F(InputHandlerProxyTest
, GestureFlingNotCancelledBySmallTimeDelta
) {
1241 // We shouldn't send any events to the widget for this gesture.
1242 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1243 VERIFY_AND_RESET_MOCKS();
1245 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1246 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
1248 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1249 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1250 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1252 VERIFY_AND_RESET_MOCKS();
1254 // On the fling start, we should schedule an animation but not actually start
1256 base::TimeDelta dt
= base::TimeDelta::FromMilliseconds(10);
1257 base::TimeTicks time
= base::TimeTicks() + dt
;
1258 WebFloatPoint fling_delta
= WebFloatPoint(100, 0);
1259 WebPoint fling_point
= WebPoint(7, 13);
1260 WebPoint fling_global_point
= WebPoint(17, 23);
1261 int modifiers
= WebInputEvent::ControlKey
;
1262 gesture_
= CreateFling(time
,
1263 blink::WebGestureDeviceTouchscreen
,
1268 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
1269 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
1270 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
1271 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1273 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
1274 // With an animation timestamp equivalent to the starting timestamp, the
1275 // animation will simply be rescheduled.
1276 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
1277 input_handler_
->Animate(time
);
1279 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
1280 EXPECT_TRUE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1282 // A small time delta should not stop the fling, even if the client
1283 // reports no scrolling.
1284 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
1285 EXPECT_CALL(mock_input_handler_
,
1286 ScrollBy(testing::_
,
1287 testing::Property(&gfx::Vector2dF::x
, testing::Lt(0))))
1288 .WillOnce(testing::Return(false));
1289 time
+= base::TimeDelta::FromMicroseconds(5);
1290 input_handler_
->Animate(time
);
1292 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
1293 EXPECT_TRUE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1295 // A time delta of zero should not stop the fling, and neither should it
1296 // trigger scrolling on the client.
1297 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
1298 input_handler_
->Animate(time
);
1300 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
1301 EXPECT_TRUE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1303 // Lack of movement on the client, with a non-trivial scroll delta, should
1304 // terminate the fling.
1305 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1306 EXPECT_CALL(mock_input_handler_
,
1307 ScrollBy(testing::_
,
1308 testing::Property(&gfx::Vector2dF::x
, testing::Lt(1))))
1309 .WillOnce(testing::Return(false));
1310 time
+= base::TimeDelta::FromMilliseconds(100);
1311 input_handler_
->Animate(time
);
1313 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
1314 EXPECT_FALSE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1317 TEST_F(InputHandlerProxyTest
, GestureFlingCancelledAfterBothAxesStopScrolling
) {
1318 // We shouldn't send any events to the widget for this gesture.
1319 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1320 VERIFY_AND_RESET_MOCKS();
1322 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1323 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
1324 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1325 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1326 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1327 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
1329 // On the fling start, we should schedule an animation but not actually start
1331 gesture_
.type
= WebInputEvent::GestureFlingStart
;
1332 WebFloatPoint fling_delta
= WebFloatPoint(100, 100);
1333 gesture_
.data
.flingStart
.velocityX
= fling_delta
.x
;
1334 gesture_
.data
.flingStart
.velocityY
= fling_delta
.y
;
1335 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
1336 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
1337 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
1338 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1339 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
1341 // The first animate doesn't cause any scrolling.
1342 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
1343 base::TimeTicks time
= base::TimeTicks() + base::TimeDelta::FromSeconds(10);
1344 input_handler_
->Animate(time
);
1345 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
1347 // The second animate starts scrolling in the positive X and Y directions.
1348 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
1349 EXPECT_CALL(mock_input_handler_
,
1350 ScrollBy(testing::_
,
1351 testing::Property(&gfx::Vector2dF::y
, testing::Lt(0))))
1352 .WillOnce(testing::Return(true));
1353 time
+= base::TimeDelta::FromMilliseconds(10);
1354 input_handler_
->Animate(time
);
1355 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
1357 // Simulate hitting the bottom content edge.
1358 gfx::Vector2dF
accumulated_overscroll(0, 100);
1359 gfx::Vector2dF
latest_overscroll_delta(0, 100);
1360 gfx::PointF
scroll_point(10, -50);
1363 DidOverscroll(testing::AllOf(
1364 testing::Field(&DidOverscrollParams::accumulated_overscroll
,
1365 testing::Eq(accumulated_overscroll
)),
1366 testing::Field(&DidOverscrollParams::latest_overscroll_delta
,
1367 testing::Eq(latest_overscroll_delta
)),
1368 testing::Field(&DidOverscrollParams::current_fling_velocity
,
1369 testing::Property(&gfx::Vector2dF::y
, testing::Lt(0))),
1370 testing::Field(&DidOverscrollParams::causal_event_viewport_point
,
1371 testing::Eq(scroll_point
)))));
1372 input_handler_
->DidOverscroll(
1373 scroll_point
, accumulated_overscroll
, latest_overscroll_delta
);
1375 // The next call to animate will no longer scroll vertically.
1376 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
1377 EXPECT_CALL(mock_input_handler_
,
1378 ScrollBy(testing::_
,
1379 testing::Property(&gfx::Vector2dF::y
, testing::Eq(0))))
1380 .WillOnce(testing::Return(true));
1381 time
+= base::TimeDelta::FromMilliseconds(10);
1382 input_handler_
->Animate(time
);
1383 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
1385 // Simulate hitting the right content edge.
1386 accumulated_overscroll
= gfx::Vector2dF(100, 100);
1387 latest_overscroll_delta
= gfx::Vector2dF(100, 0);
1388 scroll_point
= gfx::PointF(50, 0);
1391 DidOverscroll(testing::AllOf(
1392 testing::Field(&DidOverscrollParams::accumulated_overscroll
,
1393 testing::Eq(accumulated_overscroll
)),
1394 testing::Field(&DidOverscrollParams::latest_overscroll_delta
,
1395 testing::Eq(latest_overscroll_delta
)),
1396 testing::Field(&DidOverscrollParams::current_fling_velocity
,
1397 testing::Property(&gfx::Vector2dF::x
, testing::Lt(0))),
1398 testing::Field(&DidOverscrollParams::causal_event_viewport_point
,
1399 testing::Eq(scroll_point
)))));
1400 input_handler_
->DidOverscroll(
1401 scroll_point
, accumulated_overscroll
, latest_overscroll_delta
);
1402 // The next call to animate will no longer scroll horizontally or vertically,
1403 // and the fling should be cancelled.
1404 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate()).Times(0);
1405 EXPECT_CALL(mock_input_handler_
, ScrollBy(testing::_
, testing::_
)).Times(0);
1406 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1407 time
+= base::TimeDelta::FromMilliseconds(10);
1408 input_handler_
->Animate(time
);
1409 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
1410 EXPECT_FALSE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1413 TEST_F(InputHandlerProxyTest
, MultiTouchPointHitTestNegative
) {
1414 // None of the three touch points fall in the touch region. So the event
1415 // should be dropped.
1416 expected_disposition_
= InputHandlerProxy::DROP_EVENT
;
1417 VERIFY_AND_RESET_MOCKS();
1419 EXPECT_CALL(mock_input_handler_
,
1420 HaveTouchEventHandlersAt(
1421 testing::Property(&gfx::Point::x
, testing::Gt(0))))
1422 .WillOnce(testing::Return(false));
1423 EXPECT_CALL(mock_input_handler_
,
1424 HaveTouchEventHandlersAt(
1425 testing::Property(&gfx::Point::x
, testing::Lt(0))))
1426 .WillOnce(testing::Return(false));
1428 WebTouchEvent touch
;
1429 touch
.type
= WebInputEvent::TouchStart
;
1431 touch
.touchesLength
= 3;
1432 touch
.touches
[0] = CreateWebTouchPoint(WebTouchPoint::StateStationary
, 0, 0);
1433 touch
.touches
[1] = CreateWebTouchPoint(WebTouchPoint::StatePressed
, 10, 10);
1434 touch
.touches
[2] = CreateWebTouchPoint(WebTouchPoint::StatePressed
, -10, 10);
1435 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(touch
));
1438 TEST_F(InputHandlerProxyTest
, MultiTouchPointHitTestPositive
) {
1439 // One of the touch points is on a touch-region. So the event should be sent
1440 // to the main thread.
1441 expected_disposition_
= InputHandlerProxy::DID_NOT_HANDLE
;
1442 VERIFY_AND_RESET_MOCKS();
1444 EXPECT_CALL(mock_input_handler_
,
1445 HaveTouchEventHandlersAt(
1446 testing::Property(&gfx::Point::x
, testing::Eq(0))))
1447 .WillOnce(testing::Return(false));
1448 EXPECT_CALL(mock_input_handler_
,
1449 HaveTouchEventHandlersAt(
1450 testing::Property(&gfx::Point::x
, testing::Gt(0))))
1451 .WillOnce(testing::Return(true));
1452 // Since the second touch point hits a touch-region, there should be no
1453 // hit-testing for the third touch point.
1455 WebTouchEvent touch
;
1456 touch
.type
= WebInputEvent::TouchStart
;
1458 touch
.touchesLength
= 3;
1459 touch
.touches
[0] = CreateWebTouchPoint(WebTouchPoint::StatePressed
, 0, 0);
1460 touch
.touches
[1] = CreateWebTouchPoint(WebTouchPoint::StatePressed
, 10, 10);
1461 touch
.touches
[2] = CreateWebTouchPoint(WebTouchPoint::StatePressed
, -10, 10);
1462 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(touch
));
1465 TEST_F(InputHandlerProxyTest
, GestureFlingCancelledByKeyboardEvent
) {
1466 // We shouldn't send any events to the widget for this gesture.
1467 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1468 VERIFY_AND_RESET_MOCKS();
1470 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1471 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
1472 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1473 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1474 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1475 EXPECT_TRUE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1476 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
1478 // Keyboard events received during a scroll should have no effect.
1479 WebKeyboardEvent key_event
;
1480 key_event
.type
= WebInputEvent::KeyDown
;
1481 EXPECT_EQ(InputHandlerProxy::DID_NOT_HANDLE
,
1482 input_handler_
->HandleInputEvent(key_event
));
1483 EXPECT_TRUE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1484 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
1486 // On the fling start, animation should be scheduled, but no scrolling occurs.
1487 gesture_
.type
= WebInputEvent::GestureFlingStart
;
1488 WebFloatPoint fling_delta
= WebFloatPoint(100, 100);
1489 gesture_
.data
.flingStart
.velocityX
= fling_delta
.x
;
1490 gesture_
.data
.flingStart
.velocityY
= fling_delta
.y
;
1491 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
1492 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
1493 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
1494 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1495 EXPECT_TRUE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1496 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
1498 // Keyboard events received during a fling should cancel the active fling.
1499 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1500 EXPECT_EQ(InputHandlerProxy::DID_NOT_HANDLE
,
1501 input_handler_
->HandleInputEvent(key_event
));
1502 EXPECT_FALSE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1503 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
1505 // The call to animate should have no effect, as the fling was cancelled.
1506 base::TimeTicks time
= base::TimeTicks() + base::TimeDelta::FromSeconds(10);
1507 input_handler_
->Animate(time
);
1508 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
1510 // A fling cancel should be dropped, as there is nothing to cancel.
1511 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
1512 EXPECT_EQ(InputHandlerProxy::DROP_EVENT
,
1513 input_handler_
->HandleInputEvent(gesture_
));
1514 EXPECT_FALSE(input_handler_
->gesture_scroll_on_impl_thread_for_testing());
1517 TEST_F(InputHandlerProxyTest
, GestureFlingWithNegativeTimeDelta
) {
1518 // We shouldn't send any events to the widget for this gesture.
1519 expected_disposition_
= InputHandlerProxy::DID_HANDLE
;
1520 VERIFY_AND_RESET_MOCKS();
1522 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1523 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
1525 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1526 gesture_
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1527 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1529 VERIFY_AND_RESET_MOCKS();
1531 // On the fling start, we should schedule an animation but not actually start
1533 base::TimeDelta dt
= base::TimeDelta::FromMilliseconds(10);
1534 base::TimeTicks time
= base::TimeTicks() + dt
;
1535 WebFloatPoint fling_delta
= WebFloatPoint(100, 0);
1536 WebPoint fling_point
= WebPoint(7, 13);
1537 WebPoint fling_global_point
= WebPoint(17, 23);
1538 int modifiers
= WebInputEvent::ControlKey
;
1539 gesture_
= CreateFling(time
,
1540 blink::WebGestureDeviceTouchscreen
,
1545 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
1546 EXPECT_CALL(mock_input_handler_
, FlingScrollBegin())
1547 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
1548 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1550 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
1552 // If we get a negative time delta, that is, the Animation tick time happens
1553 // before the fling's start time then we should *not* try scrolling and
1554 // instead reset the fling start time.
1555 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
1556 EXPECT_CALL(mock_input_handler_
,
1557 ScrollBy(testing::_
,
1558 testing::_
)).Times(0);
1559 time
-= base::TimeDelta::FromMilliseconds(5);
1560 input_handler_
->Animate(time
);
1562 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
1564 // The first call should have reset the start time so subsequent calls should
1565 // generate scroll events.
1566 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
1567 EXPECT_CALL(mock_input_handler_
,
1568 ScrollBy(testing::_
,
1569 testing::Property(&gfx::Vector2dF::x
, testing::Lt(0))))
1570 .WillOnce(testing::Return(true));
1572 input_handler_
->Animate(time
+ base::TimeDelta::FromMilliseconds(1));
1574 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_
);
1576 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1577 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
1578 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1581 TEST_F(InputHandlerProxyTest
, FlingBoost
) {
1582 base::TimeDelta dt
= base::TimeDelta::FromMilliseconds(10);
1583 base::TimeTicks time
= base::TimeTicks() + dt
;
1584 base::TimeTicks last_animate_time
= time
;
1585 WebFloatPoint fling_delta
= WebFloatPoint(1000, 0);
1586 WebPoint fling_point
= WebPoint(7, 13);
1588 time
, blink::WebGestureDeviceTouchscreen
, fling_delta
, fling_point
);
1590 // Now cancel the fling. The fling cancellation should be deferred to allow
1591 // fling boosting events to arrive.
1595 // The GestureScrollBegin should be swallowed by the fling if it hits the same
1597 EXPECT_CALL(mock_input_handler_
,
1598 IsCurrentlyScrollingLayerAt(testing::_
, testing::_
))
1599 .WillOnce(testing::Return(true));
1602 gesture_
.timeStampSeconds
= InSecondsF(time
);
1603 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1604 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1606 VERIFY_AND_RESET_MOCKS();
1608 // Animate calls within the deferred cancellation window should continue.
1610 float expected_delta
=
1611 (time
- last_animate_time
).InSecondsF() * -fling_delta
.x
;
1612 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
1613 EXPECT_CALL(mock_input_handler_
,
1614 ScrollBy(testing::_
,
1615 testing::Property(&gfx::Vector2dF::x
,
1616 testing::Eq(expected_delta
))))
1617 .WillOnce(testing::Return(true));
1618 input_handler_
->Animate(time
);
1619 last_animate_time
= time
;
1621 VERIFY_AND_RESET_MOCKS();
1623 // GestureScrollUpdates in the same direction and at sufficient speed should
1624 // be swallowed by the fling.
1626 gesture_
.timeStampSeconds
= InSecondsF(time
);
1627 gesture_
.type
= WebInputEvent::GestureScrollUpdate
;
1628 gesture_
.data
.scrollUpdate
.deltaX
= fling_delta
.x
;
1629 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1631 VERIFY_AND_RESET_MOCKS();
1633 // Animate calls within the deferred cancellation window should continue.
1635 expected_delta
= (time
- last_animate_time
).InSecondsF() * -fling_delta
.x
;
1636 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
1637 EXPECT_CALL(mock_input_handler_
,
1638 ScrollBy(testing::_
,
1639 testing::Property(&gfx::Vector2dF::x
,
1640 testing::Eq(expected_delta
))))
1641 .WillOnce(testing::Return(true));
1642 input_handler_
->Animate(time
);
1643 last_animate_time
= time
;
1645 VERIFY_AND_RESET_MOCKS();
1647 // GestureFlingStart in the same direction and at sufficient speed should
1648 // boost the active fling.
1650 gesture_
= CreateFling(time
,
1651 blink::WebGestureDeviceTouchscreen
,
1656 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1657 VERIFY_AND_RESET_MOCKS();
1660 // Note we get *2x* as much delta because 2 flings have combined.
1661 expected_delta
= 2 * (time
- last_animate_time
).InSecondsF() * -fling_delta
.x
;
1662 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
1663 EXPECT_CALL(mock_input_handler_
,
1664 ScrollBy(testing::_
,
1665 testing::Property(&gfx::Vector2dF::x
,
1666 testing::Eq(expected_delta
))))
1667 .WillOnce(testing::Return(true));
1668 input_handler_
->Animate(time
);
1669 last_animate_time
= time
;
1671 VERIFY_AND_RESET_MOCKS();
1673 // Repeated GestureFlingStarts should accumulate.
1676 gesture_
= CreateFling(time
,
1677 blink::WebGestureDeviceTouchscreen
,
1682 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1683 VERIFY_AND_RESET_MOCKS();
1686 // Note we get *3x* as much delta because 3 flings have combined.
1687 expected_delta
= 3 * (time
- last_animate_time
).InSecondsF() * -fling_delta
.x
;
1688 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
1689 EXPECT_CALL(mock_input_handler_
,
1690 ScrollBy(testing::_
,
1691 testing::Property(&gfx::Vector2dF::x
,
1692 testing::Eq(expected_delta
))))
1693 .WillOnce(testing::Return(true));
1694 input_handler_
->Animate(time
);
1695 last_animate_time
= time
;
1697 VERIFY_AND_RESET_MOCKS();
1699 // GestureFlingCancel should terminate the fling if no boosting gestures are
1700 // received within the timeout window.
1703 gesture_
.timeStampSeconds
= InSecondsF(time
);
1704 gesture_
.type
= WebInputEvent::GestureFlingCancel
;
1705 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1707 VERIFY_AND_RESET_MOCKS();
1709 time
+= base::TimeDelta::FromMilliseconds(100);
1710 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1711 input_handler_
->Animate(time
);
1713 VERIFY_AND_RESET_MOCKS();
1716 TEST_F(InputHandlerProxyTest
, NoFlingBoostIfScrollTargetsDifferentLayer
) {
1717 base::TimeDelta dt
= base::TimeDelta::FromMilliseconds(10);
1718 base::TimeTicks time
= base::TimeTicks() + dt
;
1719 WebFloatPoint fling_delta
= WebFloatPoint(1000, 0);
1720 WebPoint fling_point
= WebPoint(7, 13);
1722 time
, blink::WebGestureDeviceTouchscreen
, fling_delta
, fling_point
);
1724 // Cancel the fling. The fling cancellation should be deferred to allow
1725 // fling boosting events to arrive.
1729 // If the GestureScrollBegin targets a different layer, the fling should be
1730 // cancelled and the scroll should be handled as usual.
1731 EXPECT_CALL(mock_input_handler_
,
1732 IsCurrentlyScrollingLayerAt(testing::_
, testing::_
))
1733 .WillOnce(testing::Return(false));
1734 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1735 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1736 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
1739 gesture_
.timeStampSeconds
= InSecondsF(time
);
1740 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1741 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1743 VERIFY_AND_RESET_MOCKS();
1746 TEST_F(InputHandlerProxyTest
, NoFlingBoostIfScrollDelayed
) {
1747 base::TimeDelta dt
= base::TimeDelta::FromMilliseconds(10);
1748 base::TimeTicks time
= base::TimeTicks() + dt
;
1749 WebFloatPoint fling_delta
= WebFloatPoint(1000, 0);
1750 WebPoint fling_point
= WebPoint(7, 13);
1752 time
, blink::WebGestureDeviceTouchscreen
, fling_delta
, fling_point
);
1754 // Cancel the fling. The fling cancellation should be deferred to allow
1755 // fling boosting events to arrive.
1759 // The GestureScrollBegin should be swallowed by the fling if it hits the same
1761 EXPECT_CALL(mock_input_handler_
,
1762 IsCurrentlyScrollingLayerAt(testing::_
, testing::_
))
1763 .WillOnce(testing::Return(true));
1766 gesture_
.timeStampSeconds
= InSecondsF(time
);
1767 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1768 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1770 VERIFY_AND_RESET_MOCKS();
1772 // If no GestureScrollUpdate or GestureFlingStart is received within the
1773 // timeout window, the fling should be cancelled and scrolling should resume.
1774 time
+= base::TimeDelta::FromMilliseconds(100);
1775 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1776 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1777 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
1778 input_handler_
->Animate(time
);
1780 VERIFY_AND_RESET_MOCKS();
1783 TEST_F(InputHandlerProxyTest
, NoFlingBoostIfScrollInDifferentDirection
) {
1784 base::TimeDelta dt
= base::TimeDelta::FromMilliseconds(10);
1785 base::TimeTicks time
= base::TimeTicks() + dt
;
1786 WebFloatPoint fling_delta
= WebFloatPoint(1000, 0);
1787 WebPoint fling_point
= WebPoint(7, 13);
1789 time
, blink::WebGestureDeviceTouchscreen
, fling_delta
, fling_point
);
1791 // Cancel the fling. The fling cancellation should be deferred to allow
1792 // fling boosting events to arrive.
1796 // The GestureScrollBegin should be swallowed by the fling if it hits the same
1798 EXPECT_CALL(mock_input_handler_
,
1799 IsCurrentlyScrollingLayerAt(testing::_
, testing::_
))
1800 .WillOnce(testing::Return(true));
1803 gesture_
.timeStampSeconds
= InSecondsF(time
);
1804 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1805 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1807 VERIFY_AND_RESET_MOCKS();
1809 // If the GestureScrollUpdate is in a different direction than the fling,
1810 // the fling should be cancelled and scrolling should resume.
1812 gesture_
.timeStampSeconds
= InSecondsF(time
);
1813 gesture_
.type
= WebInputEvent::GestureScrollUpdate
;
1814 gesture_
.data
.scrollUpdate
.deltaX
= -fling_delta
.x
;
1815 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1816 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1817 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
1818 EXPECT_CALL(mock_input_handler_
,
1819 ScrollBy(testing::_
,
1820 testing::Property(&gfx::Vector2dF::x
,
1821 testing::Eq(fling_delta
.x
))))
1822 .WillOnce(testing::Return(true));
1823 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1825 VERIFY_AND_RESET_MOCKS();
1828 TEST_F(InputHandlerProxyTest
, NoFlingBoostIfFlingTooSlow
) {
1829 base::TimeDelta dt
= base::TimeDelta::FromMilliseconds(10);
1830 base::TimeTicks time
= base::TimeTicks() + dt
;
1831 WebFloatPoint fling_delta
= WebFloatPoint(1000, 0);
1832 WebPoint fling_point
= WebPoint(7, 13);
1834 time
, blink::WebGestureDeviceTouchscreen
, fling_delta
, fling_point
);
1836 // Cancel the fling. The fling cancellation should be deferred to allow
1837 // fling boosting events to arrive.
1841 // If the new fling is too slow, no boosting should take place, with the new
1842 // fling replacing the old.
1843 WebFloatPoint small_fling_delta
= WebFloatPoint(100, 0);
1844 gesture_
= CreateFling(time
,
1845 blink::WebGestureDeviceTouchscreen
,
1850 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1852 VERIFY_AND_RESET_MOCKS();
1854 // Note that the new fling delta uses the *slow*, unboosted fling velocity.
1856 float expected_delta
= dt
.InSecondsF() * -small_fling_delta
.x
;
1857 EXPECT_CALL(mock_input_handler_
, SetNeedsAnimate());
1858 EXPECT_CALL(mock_input_handler_
,
1859 ScrollBy(testing::_
,
1860 testing::Property(&gfx::Vector2dF::x
,
1861 testing::Eq(expected_delta
))))
1862 .WillOnce(testing::Return(true));
1863 input_handler_
->Animate(time
);
1865 VERIFY_AND_RESET_MOCKS();
1868 TEST_F(InputHandlerProxyTest
, FlingBoostTerminatedDuringScrollSequence
) {
1869 base::TimeDelta dt
= base::TimeDelta::FromMilliseconds(10);
1870 base::TimeTicks time
= base::TimeTicks() + dt
;
1871 base::TimeTicks last_animate_time
= time
;
1872 WebFloatPoint fling_delta
= WebFloatPoint(1000, 0);
1873 WebPoint fling_point
= WebPoint(7, 13);
1875 time
, blink::WebGestureDeviceTouchscreen
, fling_delta
, fling_point
);
1877 // Now cancel the fling. The fling cancellation should be deferred to allow
1878 // fling boosting events to arrive.
1882 // The GestureScrollBegin should be swallowed by the fling.
1884 gesture_
.timeStampSeconds
= InSecondsF(time
);
1885 gesture_
.type
= WebInputEvent::GestureScrollBegin
;
1886 EXPECT_CALL(mock_input_handler_
,
1887 IsCurrentlyScrollingLayerAt(testing::_
, testing::_
))
1888 .WillOnce(testing::Return(true));
1889 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1891 VERIFY_AND_RESET_MOCKS();
1893 // Now animate the fling to completion (in this case, the fling should
1894 // terminate because the input handler reports a failed scroll). As the fling
1895 // was cancelled during an active scroll sequence, a synthetic
1896 // GestureScrollBegin should be processed, resuming the scroll.
1898 float expected_delta
=
1899 (time
- last_animate_time
).InSecondsF() * -fling_delta
.x
;
1900 EXPECT_CALL(mock_input_handler_
,
1901 ScrollBy(testing::_
,
1902 testing::Property(&gfx::Vector2dF::x
,
1903 testing::Eq(expected_delta
))))
1904 .WillOnce(testing::Return(false));
1905 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1906 EXPECT_CALL(mock_input_handler_
, ScrollBegin(testing::_
, testing::_
))
1907 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted
));
1908 input_handler_
->Animate(time
);
1910 VERIFY_AND_RESET_MOCKS();
1912 // Subsequent GestureScrollUpdates after the cancelled, boosted fling should
1913 // cause scrolling as usual.
1915 expected_delta
= 7.3f
;
1916 gesture_
.timeStampSeconds
= InSecondsF(time
);
1917 gesture_
.type
= WebInputEvent::GestureScrollUpdate
;
1918 gesture_
.data
.scrollUpdate
.deltaX
= -expected_delta
;
1919 EXPECT_CALL(mock_input_handler_
,
1920 ScrollBy(testing::_
,
1921 testing::Property(&gfx::Vector2dF::x
,
1922 testing::Eq(expected_delta
))))
1923 .WillOnce(testing::Return(true));
1924 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1926 VERIFY_AND_RESET_MOCKS();
1928 // GestureScrollEnd should terminate the resumed scroll properly.
1930 gesture_
.timeStampSeconds
= InSecondsF(time
);
1931 gesture_
.type
= WebInputEvent::GestureScrollEnd
;
1932 EXPECT_CALL(mock_input_handler_
, ScrollEnd());
1933 EXPECT_EQ(expected_disposition_
, input_handler_
->HandleInputEvent(gesture_
));
1935 VERIFY_AND_RESET_MOCKS();
1939 } // namespace content