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