Remove LayerScrollOffsetDelegate, make all input paths go thru proxy.
[chromium-blink-merge.git] / content / renderer / input / input_handler_proxy_unittest.cc
blob3cc7f43a9bd1a80e4ffcb01df91839403aa54f2f
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;
32 using blink::WebSize;
33 using blink::WebTouchEvent;
34 using blink::WebTouchPoint;
35 using testing::Field;
37 namespace content {
38 namespace {
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,
57 WebPoint point,
58 WebPoint global_point,
59 int modifiers) {
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;
66 fling.x = point.x;
67 fling.y = point.y;
68 fling.globalX = global_point.x;
69 fling.globalY = global_point.y;
70 fling.modifiers = modifiers;
71 return fling;
74 WebGestureEvent CreateFling(WebGestureDevice source_device,
75 WebFloatPoint velocity,
76 WebPoint point,
77 WebPoint global_point,
78 int modifiers) {
79 return CreateFling(base::TimeTicks(),
80 source_device,
81 velocity,
82 point,
83 global_point,
84 modifiers);
87 class MockInputHandler : public cc::InputHandler {
88 public:
89 MockInputHandler() {}
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 {
123 return NULL;
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; }
144 private:
145 bool is_scrolling_root_ = true;
146 DISALLOW_COPY_AND_ASSIGN(MockInputHandler);
149 class MockSynchronousInputHandler : public content::SynchronousInputHandler {
150 public:
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
162 // indefinitely.
163 class FakeWebGestureCurve : public blink::WebGestureCurve {
164 public:
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_);
184 private:
185 blink::WebFloatSize velocity_;
186 blink::WebFloatSize cumulative_scroll_;
188 DISALLOW_COPY_AND_ASSIGN(FakeWebGestureCurve);
191 class MockInputHandlerProxyClient
192 : public content::InputHandlerProxyClient {
193 public:
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 {}
215 private:
216 DISALLOW_COPY_AND_ASSIGN(MockInputHandlerProxyClient);
219 class MockInputHandlerProxyClientWithDidAnimateForInput
220 : public MockInputHandlerProxyClient {
221 public:
222 MockInputHandlerProxyClientWithDidAnimateForInput() {}
223 ~MockInputHandlerProxyClientWithDidAnimateForInput() override {}
225 MOCK_METHOD0(DidAnimateForInput, void());
227 private:
228 DISALLOW_COPY_AND_ASSIGN(MockInputHandlerProxyClientWithDidAnimateForInput);
231 WebTouchPoint CreateWebTouchPoint(WebTouchPoint::State state, float x,
232 float y) {
233 WebTouchPoint point;
234 point.state = state;
235 point.screenPosition = WebFloatPoint(x, y);
236 point.position = WebFloatPoint(x, y);
237 return point;
240 class InputHandlerProxyTest
241 : public testing::Test,
242 public testing::WithParamInterface<InputHandlerProxyTestType> {
243 public:
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())
258 .Times(1);
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) \
273 do { \
274 if (synchronous_root_scroll_) { \
275 EXPECT_CALL(mock_synchronous_input_handler_, \
276 SetNeedsSynchronousAnimateInput()) \
277 .Times(times); \
278 EXPECT_CALL(mock_input_handler_, SetNeedsAnimateInput()).Times(0); \
279 } else { \
280 EXPECT_CALL(mock_input_handler_, SetNeedsAnimateInput()).Times(times); \
281 EXPECT_CALL(mock_synchronous_input_handler_, \
282 SetNeedsSynchronousAnimateInput()) \
283 .Times(0); \
285 } while (false)
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() \
290 do { \
291 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); \
292 testing::Mock::VerifyAndClearExpectations( \
293 &mock_synchronous_input_handler_); \
294 testing::Mock::VerifyAndClearExpectations(&mock_client_); \
295 } while (false)
297 void Animate(base::TimeTicks time) {
298 if (synchronous_root_scroll_) {
299 input_handler_->SynchronouslyAnimate(time);
300 } else {
301 input_handler_->Animate(time);
305 void StartFling(base::TimeTicks timestamp,
306 WebGestureDevice source_device,
307 WebFloatPoint velocity,
308 WebPoint position) {
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);
325 gesture_ =
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();
342 protected:
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_,
395 ScrollBy(testing::_,
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_,
408 ScrollBy(testing::_,
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;
503 gesture_.x = 7;
504 gesture_.y = 13;
505 EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(1.5, gfx::Point(7, 13)));
506 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
508 VERIFY_AND_RESET_MOCKS();
510 gesture_.type = WebInputEvent::GesturePinchUpdate;
511 gesture_.data.pinchUpdate.scale = 0.5;
512 gesture_.data.pinchUpdate.zoomDisabled = true;
513 gesture_.x = 9;
514 gesture_.y = 6;
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;
523 gesture_.x = 9;
524 gesture_.y = 6;
525 EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(.5, gfx::Point(9, 6)));
526 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
528 VERIFY_AND_RESET_MOCKS();
530 gesture_.type = WebInputEvent::GesturePinchEnd;
531 EXPECT_CALL(mock_input_handler_, PinchGestureEnd());
532 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
534 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;
551 gesture_.x = 7;
552 gesture_.y = 13;
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;
559 gesture_.x = 9;
560 gesture_.y = 6;
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
587 // thread.
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;
601 gesture_.x = 7;
602 gesture_.y = 13;
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_,
612 ScrollBy(testing::_,
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;
621 gesture_.x = 9;
622 gesture_.y = 6;
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
633 // thread.
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
709 // fling_cancel.
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
721 // scrolling.
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,
730 fling_delta,
731 fling_point,
732 fling_global_point,
733 modifiers);
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
745 // visible hitch.
746 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
747 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
748 .Times(0);
749 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
750 Animate(time);
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_,
759 ScrollBy(testing::_,
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);
764 Animate(time);
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
779 // event
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
784 EXPECT_CALL(
785 mock_client_,
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,
796 testing::Eq(10)),
797 testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll,
798 testing::Field(&WebSize::width, testing::Gt(0))))));
799 time += base::TimeDelta::FromMilliseconds(100);
800 Animate(time);
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::_))
809 .Times(0);
810 time += base::TimeDelta::FromMilliseconds(100);
811 Animate(time);
813 // Since we've transferred the fling to the main thread, we need to pass the
814 // next GestureFlingCancel to the main
815 // thread as well.
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,
836 fling_delta,
837 fling_point,
838 fling_global_point,
839 modifiers);
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::_))
852 .Times(0);
853 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
854 Animate(time);
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_,
863 ScrollBy(testing::_,
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);
868 Animate(time);
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
884 // event
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
889 EXPECT_CALL(
890 mock_client_,
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,
901 testing::Eq(10)),
902 testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll,
903 testing::Field(&WebSize::width, testing::Gt(0))))));
904 time += base::TimeDelta::FromMilliseconds(100);
905 Animate(time);
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::_))
914 .Times(0);
915 time += base::TimeDelta::FromMilliseconds(100);
916 Animate(time);
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
922 // thread as well.
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,
936 fling_delta,
937 fling_point,
938 fling_global_point,
939 modifiers);
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::_))
952 .Times(0);
953 time = base::TimeTicks() + base::TimeDelta::FromSeconds(30);
954 Animate(time);
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_,
963 ScrollBy(testing::_,
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);
968 Animate(time);
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".
980 EXPECT_CALL(
981 mock_client_,
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,
992 testing::Eq(30)),
993 testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll,
994 testing::Field(&WebSize::height, testing::Lt(0))))));
995 time += base::TimeDelta::FromMilliseconds(100);
996 Animate(time);
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
1115 // scrolling.
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,
1122 fling_delta,
1123 fling_point,
1124 fling_global_point,
1125 modifiers);
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
1136 // visible hitch.
1137 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1138 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
1139 Animate(time);
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);
1150 Animate(time);
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
1176 // scrolling.
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,
1185 fling_delta,
1186 fling_point,
1187 fling_global_point,
1188 modifiers);
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_));
1205 time += dt;
1206 Animate(time);
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
1232 // scrolling.
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
1256 // timestamp.
1257 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1258 base::TimeTicks time =
1259 base::TimeTicks() + start_time_offset + base::TimeDelta::FromSeconds(1);
1260 Animate(time);
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);
1271 Animate(time);
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
1301 // scrolling.
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,
1307 fling_delta,
1308 fling_point,
1309 fling_global_point,
1310 modifiers);
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
1325 // visible hitch.
1326 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
1327 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
1328 Animate(time);
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);
1339 Animate(time);
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
1374 // scrolling.
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
1413 // scrolling.
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);
1428 Animate(time);
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);
1441 Animate(time);
1442 VERIFY_AND_RESET_MOCKS();
1444 // The third animate overscrolls in the positive Y direction but scrolls
1445 // somewhat.
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));
1457 EXPECT_CALL(
1458 mock_client_,
1459 DidOverscroll(testing::AllOf(
1460 testing::Field(
1461 &DidOverscrollParams::accumulated_overscroll,
1462 testing::Eq(overscroll.accumulated_root_overscroll)),
1463 testing::Field(
1464 &DidOverscrollParams::latest_overscroll_delta,
1465 testing::Eq(overscroll.unused_scroll_delta)),
1466 testing::Field(
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);
1472 Animate(time);
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);
1485 Animate(time);
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
1504 // scrolling.
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,
1513 fling_delta,
1514 fling_point,
1515 fling_global_point,
1516 modifiers);
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);
1526 Animate(time);
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);
1539 Animate(time);
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);
1547 Animate(time);
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);
1560 Animate(time);
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
1583 // scrolling.
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);
1597 Animate(time);
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);
1607 Animate(time);
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));
1617 EXPECT_CALL(
1618 mock_client_,
1619 DidOverscroll(testing::AllOf(
1620 testing::Field(
1621 &DidOverscrollParams::accumulated_overscroll,
1622 testing::Eq(overscroll.accumulated_root_overscroll)),
1623 testing::Field(
1624 &DidOverscrollParams::latest_overscroll_delta,
1625 testing::Eq(overscroll.unused_scroll_delta)),
1626 testing::Field(
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);
1631 Animate(time);
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);
1641 Animate(time);
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));
1651 EXPECT_CALL(
1652 mock_client_,
1653 DidOverscroll(testing::AllOf(
1654 testing::Field(
1655 &DidOverscrollParams::accumulated_overscroll,
1656 testing::Eq(overscroll.accumulated_root_overscroll)),
1657 testing::Field(
1658 &DidOverscrollParams::latest_overscroll_delta,
1659 testing::Eq(overscroll.unused_scroll_delta)),
1660 testing::Field(
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);
1665 Animate(time);
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);
1673 Animate(time);
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);
1776 Animate(time);
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
1801 // scrolling.
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,
1810 fling_delta,
1811 fling_point,
1812 fling_global_point,
1813 modifiers);
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);
1829 Animate(time);
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);
1858 StartFling(
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.
1863 time += dt;
1864 CancelFling(time);
1866 // The GestureScrollBegin should be swallowed by the fling if it hits the same
1867 // scrolling layer.
1868 EXPECT_CALL(mock_input_handler_,
1869 IsCurrentlyScrollingLayerAt(testing::_, testing::_))
1870 .WillOnce(testing::Return(true));
1872 time += dt;
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.
1880 time += dt;
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_));
1889 Animate(time);
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.
1896 time += dt;
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.
1905 time += dt;
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_));
1913 Animate(time);
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,
1923 fling_delta,
1924 fling_point,
1925 fling_point,
1927 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1928 VERIFY_AND_RESET_MOCKS();
1930 time += dt;
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_));
1939 Animate(time);
1940 last_animate_time = time;
1942 VERIFY_AND_RESET_MOCKS();
1944 // Repeated GestureFlingStarts should accumulate.
1946 CancelFling(time);
1947 gesture_ = CreateFling(time,
1948 blink::WebGestureDeviceTouchscreen,
1949 fling_delta,
1950 fling_point,
1951 fling_point,
1953 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1954 VERIFY_AND_RESET_MOCKS();
1956 time += dt;
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_));
1965 Animate(time);
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.
1973 time += dt;
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());
1982 Animate(time);
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);
1992 StartFling(
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.
1997 time += dt;
1998 CancelFling(time);
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));
2009 time += dt;
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);
2022 StartFling(
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.
2027 time += dt;
2028 CancelFling(time);
2030 // The GestureScrollBegin should be swallowed by the fling if it hits the same
2031 // scrolling layer.
2032 EXPECT_CALL(mock_input_handler_,
2033 IsCurrentlyScrollingLayerAt(testing::_, testing::_))
2034 .WillOnce(testing::Return(true));
2036 time += dt;
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));
2049 Animate(time);
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);
2059 StartFling(
2060 time, blink::WebGestureDeviceTouchscreen, fling_delta, fling_point);
2062 // Animate fling once.
2063 time += dt;
2064 EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_, testing::_))
2065 .WillOnce(testing::Return(scroll_result_did_scroll_));
2066 EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
2067 Animate(time);
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);
2072 CancelFling(time);
2074 // The GestureScrollBegin should be swallowed by the fling if it hits the same
2075 // scrolling layer.
2076 EXPECT_CALL(mock_input_handler_,
2077 IsCurrentlyScrollingLayerAt(testing::_, testing::_))
2078 .WillOnce(testing::Return(true));
2080 time += dt;
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);
2106 StartFling(
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.
2111 time += dt;
2112 CancelFling(time);
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,
2121 fling_point,
2122 fling_point,
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
2129 // velocity.
2130 time += dt;
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_));
2138 Animate(time);
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);
2148 StartFling(
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.
2153 time += dt;
2154 CancelFling(time);
2156 // The GestureScrollBegin should be swallowed by the fling if it hits the same
2157 // scrolling layer.
2158 EXPECT_CALL(mock_input_handler_,
2159 IsCurrentlyScrollingLayerAt(testing::_, testing::_))
2160 .WillOnce(testing::Return(true));
2162 time += dt;
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.
2171 time += dt;
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);
2193 StartFling(
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.
2198 time += dt;
2199 CancelFling(time);
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,
2206 small_fling_delta,
2207 fling_point,
2208 fling_point,
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.
2215 time += dt;
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_));
2223 Animate(time);
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);
2234 StartFling(
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;
2242 time += dt;
2243 CancelFling(time);
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);
2254 StartFling(
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.
2259 time += dt;
2260 CancelFling(time);
2262 // The GestureScrollBegin should be swallowed by the fling.
2263 time += dt;
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.
2277 time += dt;
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));
2288 Animate(time);
2290 VERIFY_AND_RESET_MOCKS();
2292 // Subsequent GestureScrollUpdates after the cancelled, boosted fling should
2293 // cause scrolling as usual.
2294 time += dt;
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.
2309 time += dt;
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>
2320 mock_client;
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())
2325 .Times(1);
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);
2346 Animate(time);
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())
2361 .Times(1);
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())
2369 .Times(0);
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.
2388 EXPECT_CALL(
2389 mock_synchronous_input_handler,
2390 UpdateRootLayerState(gfx::ScrollOffset(1, 2), gfx::ScrollOffset(3, 4),
2391 gfx::SizeF(5, 6), 7, 8, 9))
2392 .Times(1);
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));
2424 } // namespace
2425 } // namespace content