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