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.
4
5#include "content/renderer/input/input_handler_proxy.h"
6
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"
20
21using blink::WebActiveWheelFlingParameters;
22using blink::WebFloatPoint;
23using blink::WebFloatSize;
24using blink::WebGestureDevice;
25using blink::WebGestureEvent;
26using blink::WebInputEvent;
27using blink::WebKeyboardEvent;
28using blink::WebMouseWheelEvent;
29using blink::WebPoint;
30using blink::WebSize;
31using blink::WebTouchEvent;
32using blink::WebTouchPoint;
33
34namespace content {
35namespace {
36
37double InSecondsF(const base::TimeTicks& time) {
38  return (time - base::TimeTicks()).InSecondsF();
39}
40
41WebGestureEvent 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;
59}
60
61WebGestureEvent 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);
72}
73
74class MockInputHandler : public cc::InputHandler {
75 public:
76  MockInputHandler() {}
77  virtual ~MockInputHandler() {}
78
79  MOCK_METHOD0(PinchGestureBegin, void());
80  MOCK_METHOD2(PinchGestureUpdate,
81               void(float magnify_delta, const gfx::Point& anchor));
82  MOCK_METHOD0(PinchGestureEnd, void());
83
84  MOCK_METHOD0(SetNeedsAnimate, void());
85
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());
100
101  virtual scoped_ptr<cc::SwapPromiseMonitor>
102    CreateLatencyInfoSwapPromiseMonitor(ui::LatencyInfo* latency) OVERRIDE {
103      return scoped_ptr<cc::SwapPromiseMonitor>();
104  }
105
106  virtual void BindToClient(cc::InputHandlerClient* client) OVERRIDE {}
107
108  virtual void MouseMoveAt(const gfx::Point& mouse_position) OVERRIDE {}
109
110  MOCK_METHOD2(IsCurrentlyScrollingLayerAt,
111               bool(const gfx::Point& point,
112                    cc::InputHandler::ScrollInputType type));
113
114  MOCK_METHOD1(HaveTouchEventHandlersAt, bool(const gfx::Point& point));
115
116  virtual void SetRootLayerScrollOffsetDelegate(
117      cc::LayerScrollOffsetDelegate* root_layer_scroll_offset_delegate)
118      OVERRIDE {}
119
120  virtual void OnRootLayerDelegatedScrollOffsetChanged() OVERRIDE {}
121
122  DISALLOW_COPY_AND_ASSIGN(MockInputHandler);
123};
124
125// A simple WebGestureCurve implementation that flings at a constant velocity
126// indefinitely.
127class FakeWebGestureCurve : public blink::WebGestureCurve {
128 public:
129  FakeWebGestureCurve(const blink::WebFloatSize& velocity,
130                      const blink::WebFloatSize& cumulative_scroll)
131      : velocity_(velocity), cumulative_scroll_(cumulative_scroll) {}
132
133  virtual ~FakeWebGestureCurve() {}
134
135  // Returns false if curve has finished and can no longer be applied.
136  virtual bool apply(double time, blink::WebGestureCurveTarget* target) {
137    blink::WebFloatSize displacement(velocity_.width * time,
138                                     velocity_.height * time);
139    blink::WebFloatSize increment(
140        displacement.width - cumulative_scroll_.width,
141        displacement.height - cumulative_scroll_.height);
142    cumulative_scroll_ = displacement;
143    // scrollBy() could delete this curve if the animation is over, so don't
144    // touch any member variables after making that call.
145    return target->scrollBy(increment, velocity_);
146  }
147
148 private:
149  blink::WebFloatSize velocity_;
150  blink::WebFloatSize cumulative_scroll_;
151
152  DISALLOW_COPY_AND_ASSIGN(FakeWebGestureCurve);
153};
154
155class MockInputHandlerProxyClient
156    : public content::InputHandlerProxyClient {
157 public:
158  MockInputHandlerProxyClient() {}
159  virtual ~MockInputHandlerProxyClient() {}
160
161  virtual void WillShutdown() OVERRIDE {}
162
163  MOCK_METHOD1(TransferActiveWheelFlingAnimation,
164               void(const WebActiveWheelFlingParameters&));
165
166  virtual blink::WebGestureCurve* CreateFlingAnimationCurve(
167      WebGestureDevice deviceSource,
168      const WebFloatPoint& velocity,
169      const WebSize& cumulative_scroll) OVERRIDE {
170    return new FakeWebGestureCurve(
171        blink::WebFloatSize(velocity.x, velocity.y),
172        blink::WebFloatSize(cumulative_scroll.width, cumulative_scroll.height));
173  }
174
175  MOCK_METHOD1(DidOverscroll, void(const DidOverscrollParams&));
176  virtual void DidStopFlinging() OVERRIDE {}
177  virtual void DidReceiveInputEvent() OVERRIDE {}
178
179 private:
180  DISALLOW_COPY_AND_ASSIGN(MockInputHandlerProxyClient);
181};
182
183class MockInputHandlerProxyClientWithDidReceiveInputEvent
184    : public MockInputHandlerProxyClient {
185 public:
186  MockInputHandlerProxyClientWithDidReceiveInputEvent() {}
187  virtual ~MockInputHandlerProxyClientWithDidReceiveInputEvent() {}
188
189  MOCK_METHOD0(DidReceiveInputEvent, void());
190
191 private:
192  DISALLOW_COPY_AND_ASSIGN(MockInputHandlerProxyClientWithDidReceiveInputEvent);
193};
194
195WebTouchPoint CreateWebTouchPoint(WebTouchPoint::State state, float x,
196                                  float y) {
197  WebTouchPoint point;
198  point.state = state;
199  point.screenPosition = WebFloatPoint(x, y);
200  point.position = WebFloatPoint(x, y);
201  return point;
202}
203
204class InputHandlerProxyTest : public testing::Test {
205 public:
206  InputHandlerProxyTest()
207      : expected_disposition_(InputHandlerProxy::DID_HANDLE) {
208    input_handler_.reset(
209        new content::InputHandlerProxy(&mock_input_handler_, &mock_client_));
210  }
211
212  ~InputHandlerProxyTest() {
213    input_handler_.reset();
214  }
215
216// This is defined as a macro because when an expectation is not satisfied the
217// only output you get
218// out of gmock is the line number that set the expectation.
219#define VERIFY_AND_RESET_MOCKS()                                              \
220  do {                                                                        \
221    testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);          \
222    testing::Mock::VerifyAndClearExpectations(&mock_client_);                 \
223  } while (false)
224
225  void StartFling(base::TimeTicks timestamp,
226                  WebGestureDevice source_device,
227                  WebFloatPoint velocity,
228                  WebPoint position) {
229    expected_disposition_ = InputHandlerProxy::DID_HANDLE;
230    VERIFY_AND_RESET_MOCKS();
231
232    EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
233        .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
234    gesture_.type = WebInputEvent::GestureScrollBegin;
235    gesture_.sourceDevice = source_device;
236    EXPECT_EQ(expected_disposition_,
237              input_handler_->HandleInputEvent(gesture_));
238
239    VERIFY_AND_RESET_MOCKS();
240
241    EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
242        .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
243    EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
244
245    gesture_ =
246        CreateFling(timestamp, source_device, velocity, position, position, 0);
247    EXPECT_EQ(expected_disposition_,
248              input_handler_->HandleInputEvent(gesture_));
249
250    VERIFY_AND_RESET_MOCKS();
251  }
252
253  void CancelFling(base::TimeTicks timestamp) {
254    gesture_.timeStampSeconds = InSecondsF(timestamp);
255    gesture_.type = WebInputEvent::GestureFlingCancel;
256    EXPECT_EQ(expected_disposition_,
257              input_handler_->HandleInputEvent(gesture_));
258
259    VERIFY_AND_RESET_MOCKS();
260  }
261
262 protected:
263  testing::StrictMock<MockInputHandler> mock_input_handler_;
264  scoped_ptr<content::InputHandlerProxy> input_handler_;
265  testing::StrictMock<MockInputHandlerProxyClient> mock_client_;
266  WebGestureEvent gesture_;
267
268  InputHandlerProxy::EventDisposition expected_disposition_;
269};
270
271TEST_F(InputHandlerProxyTest, MouseWheelByPageMainThread) {
272  expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
273  WebMouseWheelEvent wheel;
274  wheel.type = WebInputEvent::MouseWheel;
275  wheel.scrollByPage = true;
276
277  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(wheel));
278  testing::Mock::VerifyAndClearExpectations(&mock_client_);
279}
280
281TEST_F(InputHandlerProxyTest, MouseWheelWithCtrl) {
282  expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
283  WebMouseWheelEvent wheel;
284  wheel.type = WebInputEvent::MouseWheel;
285  wheel.modifiers = WebInputEvent::ControlKey;
286
287  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(wheel));
288  testing::Mock::VerifyAndClearExpectations(&mock_client_);
289}
290
291TEST_F(InputHandlerProxyTest, GestureScrollStarted) {
292  // We shouldn't send any events to the widget for this gesture.
293  expected_disposition_ = InputHandlerProxy::DID_HANDLE;
294  VERIFY_AND_RESET_MOCKS();
295
296  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
297      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
298
299  gesture_.type = WebInputEvent::GestureScrollBegin;
300  EXPECT_EQ(expected_disposition_,input_handler_->HandleInputEvent(gesture_));
301
302  // The event should not be marked as handled if scrolling is not possible.
303  expected_disposition_ = InputHandlerProxy::DROP_EVENT;
304  VERIFY_AND_RESET_MOCKS();
305
306  gesture_.type = WebInputEvent::GestureScrollUpdate;
307  gesture_.data.scrollUpdate.deltaY =
308      -40;  // -Y means scroll down - i.e. in the +Y direction.
309  EXPECT_CALL(mock_input_handler_,
310              ScrollBy(testing::_,
311                       testing::Property(&gfx::Vector2dF::y, testing::Gt(0))))
312      .WillOnce(testing::Return(false));
313  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
314
315  // Mark the event as handled if scroll happens.
316  expected_disposition_ = InputHandlerProxy::DID_HANDLE;
317  VERIFY_AND_RESET_MOCKS();
318
319  gesture_.type = WebInputEvent::GestureScrollUpdate;
320  gesture_.data.scrollUpdate.deltaY =
321      -40;  // -Y means scroll down - i.e. in the +Y direction.
322  EXPECT_CALL(mock_input_handler_,
323              ScrollBy(testing::_,
324                       testing::Property(&gfx::Vector2dF::y, testing::Gt(0))))
325      .WillOnce(testing::Return(true));
326  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
327
328  VERIFY_AND_RESET_MOCKS();
329
330  gesture_.type = WebInputEvent::GestureScrollEnd;
331  gesture_.data.scrollUpdate.deltaY = 0;
332  EXPECT_CALL(mock_input_handler_, ScrollEnd());
333  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
334}
335
336TEST_F(InputHandlerProxyTest, GestureScrollOnMainThread) {
337  // We should send all events to the widget for this gesture.
338  expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
339  VERIFY_AND_RESET_MOCKS();
340
341  EXPECT_CALL(mock_input_handler_, ScrollBegin(::testing::_, ::testing::_))
342      .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread));
343
344  gesture_.type = WebInputEvent::GestureScrollBegin;
345  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
346
347  VERIFY_AND_RESET_MOCKS();
348
349  gesture_.type = WebInputEvent::GestureScrollUpdate;
350  gesture_.data.scrollUpdate.deltaY = 40;
351  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
352
353  VERIFY_AND_RESET_MOCKS();
354
355  gesture_.type = WebInputEvent::GestureScrollEnd;
356  gesture_.data.scrollUpdate.deltaY = 0;
357  EXPECT_CALL(mock_input_handler_, ScrollEnd()).WillOnce(testing::Return());
358  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
359}
360
361TEST_F(InputHandlerProxyTest, GestureScrollIgnored) {
362  // We shouldn't handle the GestureScrollBegin.
363  // Instead, we should get a DROP_EVENT result, indicating
364  // that we could determine that there's nothing that could scroll or otherwise
365  // react to this gesture sequence and thus we should drop the whole gesture
366  // sequence on the floor, except for the ScrollEnd.
367  expected_disposition_ = InputHandlerProxy::DROP_EVENT;
368  VERIFY_AND_RESET_MOCKS();
369
370  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
371      .WillOnce(testing::Return(cc::InputHandler::ScrollIgnored));
372
373  gesture_.type = WebInputEvent::GestureScrollBegin;
374  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
375
376  expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
377  gesture_.type = WebInputEvent::GestureScrollEnd;
378  EXPECT_CALL(mock_input_handler_, ScrollEnd()).WillOnce(testing::Return());
379  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
380}
381
382TEST_F(InputHandlerProxyTest, GesturePinch) {
383  // We shouldn't send any events to the widget for this gesture.
384  expected_disposition_ = InputHandlerProxy::DID_HANDLE;
385  VERIFY_AND_RESET_MOCKS();
386
387  gesture_.type = WebInputEvent::GesturePinchBegin;
388  EXPECT_CALL(mock_input_handler_, PinchGestureBegin());
389  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
390
391  VERIFY_AND_RESET_MOCKS();
392
393  gesture_.type = WebInputEvent::GesturePinchUpdate;
394  gesture_.data.pinchUpdate.scale = 1.5;
395  gesture_.x = 7;
396  gesture_.y = 13;
397  EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(1.5, gfx::Point(7, 13)));
398  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
399
400  VERIFY_AND_RESET_MOCKS();
401
402  gesture_.type = WebInputEvent::GesturePinchUpdate;
403  gesture_.data.pinchUpdate.scale = 0.5;
404  gesture_.x = 9;
405  gesture_.y = 6;
406  EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(.5, gfx::Point(9, 6)));
407  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
408
409  VERIFY_AND_RESET_MOCKS();
410
411  gesture_.type = WebInputEvent::GesturePinchEnd;
412  EXPECT_CALL(mock_input_handler_, PinchGestureEnd());
413  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
414}
415
416TEST_F(InputHandlerProxyTest, GesturePinchAfterScrollOnMainThread) {
417  // Scrolls will start by being sent to the main thread.
418  expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
419  VERIFY_AND_RESET_MOCKS();
420
421  EXPECT_CALL(mock_input_handler_, ScrollBegin(::testing::_, ::testing::_))
422      .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread));
423
424  gesture_.type = WebInputEvent::GestureScrollBegin;
425  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
426
427  VERIFY_AND_RESET_MOCKS();
428
429  gesture_.type = WebInputEvent::GestureScrollUpdate;
430  gesture_.data.scrollUpdate.deltaY = 40;
431  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
432
433  // However, after the pinch gesture starts, they should go to the impl
434  // thread.
435  expected_disposition_ = InputHandlerProxy::DID_HANDLE;
436  VERIFY_AND_RESET_MOCKS();
437
438  gesture_.type = WebInputEvent::GesturePinchBegin;
439  EXPECT_CALL(mock_input_handler_, PinchGestureBegin());
440  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
441
442  VERIFY_AND_RESET_MOCKS();
443
444  gesture_.type = WebInputEvent::GesturePinchUpdate;
445  gesture_.data.pinchUpdate.scale = 1.5;
446  gesture_.x = 7;
447  gesture_.y = 13;
448  EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(1.5, gfx::Point(7, 13)));
449  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
450
451  VERIFY_AND_RESET_MOCKS();
452
453  gesture_.type = WebInputEvent::GestureScrollUpdate;
454  gesture_.data.scrollUpdate.deltaY =
455      -40;  // -Y means scroll down - i.e. in the +Y direction.
456  EXPECT_CALL(mock_input_handler_,
457              ScrollBy(testing::_,
458                       testing::Property(&gfx::Vector2dF::y, testing::Gt(0))))
459      .WillOnce(testing::Return(true));
460  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
461
462  VERIFY_AND_RESET_MOCKS();
463
464  gesture_.type = WebInputEvent::GesturePinchUpdate;
465  gesture_.data.pinchUpdate.scale = 0.5;
466  gesture_.x = 9;
467  gesture_.y = 6;
468  EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(.5, gfx::Point(9, 6)));
469  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
470
471  VERIFY_AND_RESET_MOCKS();
472
473  gesture_.type = WebInputEvent::GesturePinchEnd;
474  EXPECT_CALL(mock_input_handler_, PinchGestureEnd());
475  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
476
477  // After the pinch gesture ends, they should go to back to the main
478  // thread.
479  expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
480  VERIFY_AND_RESET_MOCKS();
481
482  gesture_.type = WebInputEvent::GestureScrollEnd;
483  gesture_.data.scrollUpdate.deltaY = 0;
484  EXPECT_CALL(mock_input_handler_, ScrollEnd())
485      .WillOnce(testing::Return());
486  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
487}
488
489TEST_F(InputHandlerProxyTest, GestureFlingStartedTouchpad) {
490  // We shouldn't send any events to the widget for this gesture.
491  expected_disposition_ = InputHandlerProxy::DID_HANDLE;
492  VERIFY_AND_RESET_MOCKS();
493
494  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
495      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
496  EXPECT_CALL(mock_input_handler_, ScrollEnd());
497  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
498
499  gesture_.type = WebInputEvent::GestureFlingStart;
500  gesture_.data.flingStart.velocityX = 10;
501  gesture_.sourceDevice = blink::WebGestureDeviceTouchpad;
502  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
503
504  VERIFY_AND_RESET_MOCKS();
505
506  // Verify that a GestureFlingCancel during an animation cancels it.
507  gesture_.type = WebInputEvent::GestureFlingCancel;
508  gesture_.sourceDevice = blink::WebGestureDeviceTouchpad;
509  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
510}
511
512TEST_F(InputHandlerProxyTest, GestureFlingOnMainThreadTouchpad) {
513  // We should send all events to the widget for this gesture.
514  expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
515  VERIFY_AND_RESET_MOCKS();
516
517  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
518      .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread));
519
520  gesture_.type = WebInputEvent::GestureFlingStart;
521  gesture_.sourceDevice = blink::WebGestureDeviceTouchpad;
522  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
523
524  // Since we returned ScrollStatusOnMainThread from scrollBegin, ensure the
525  // input handler knows it's scrolling off the impl thread
526  ASSERT_FALSE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
527
528  VERIFY_AND_RESET_MOCKS();
529
530  // Even if we didn't start a fling ourselves, we still need to send the cancel
531  // event to the widget.
532  gesture_.type = WebInputEvent::GestureFlingCancel;
533  gesture_.sourceDevice = blink::WebGestureDeviceTouchpad;
534  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
535}
536
537TEST_F(InputHandlerProxyTest, GestureFlingIgnoredTouchpad) {
538  expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
539  VERIFY_AND_RESET_MOCKS();
540
541  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
542      .WillOnce(testing::Return(cc::InputHandler::ScrollIgnored));
543
544  gesture_.type = WebInputEvent::GestureFlingStart;
545  gesture_.sourceDevice = blink::WebGestureDeviceTouchpad;
546  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
547
548  expected_disposition_ = InputHandlerProxy::DROP_EVENT;
549  VERIFY_AND_RESET_MOCKS();
550
551  // Since the previous fling was ignored, we should also be dropping the next
552  // fling_cancel.
553  gesture_.type = WebInputEvent::GestureFlingCancel;
554  gesture_.sourceDevice = blink::WebGestureDeviceTouchpad;
555  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
556}
557
558TEST_F(InputHandlerProxyTest, GestureFlingAnimatesTouchpad) {
559  // We shouldn't send any events to the widget for this gesture.
560  expected_disposition_ = InputHandlerProxy::DID_HANDLE;
561  VERIFY_AND_RESET_MOCKS();
562
563  // On the fling start, we should schedule an animation but not actually start
564  // scrolling.
565  gesture_.type = WebInputEvent::GestureFlingStart;
566  WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
567  WebPoint fling_point = WebPoint(7, 13);
568  WebPoint fling_global_point = WebPoint(17, 23);
569  // Note that for trackpad, wheel events with the Control modifier are
570  // special (reserved for zoom), so don't set that here.
571  int modifiers = WebInputEvent::ShiftKey | WebInputEvent::AltKey;
572  gesture_ = CreateFling(blink::WebGestureDeviceTouchpad,
573                         fling_delta,
574                         fling_point,
575                         fling_global_point,
576                         modifiers);
577  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
578  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
579      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
580  EXPECT_CALL(mock_input_handler_, ScrollEnd());
581  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
582
583  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
584  // The first animate call should let us pick up an animation start time, but
585  // we shouldn't actually move anywhere just yet. The first frame after the
586  // fling start will typically include the last scroll from the gesture that
587  // lead to the scroll (either wheel or gesture scroll), so there should be no
588  // visible hitch.
589  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
590  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
591      .Times(0);
592  base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
593  input_handler_->Animate(time);
594
595  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
596
597  // The second call should start scrolling in the -X direction.
598  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
599  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
600      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
601  EXPECT_CALL(mock_input_handler_,
602              ScrollBy(testing::_,
603                       testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))
604      .WillOnce(testing::Return(true));
605  EXPECT_CALL(mock_input_handler_, ScrollEnd());
606  time += base::TimeDelta::FromMilliseconds(100);
607  input_handler_->Animate(time);
608
609  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
610
611  // Let's say on the third call we hit a non-scrollable region. We should abort
612  // the fling and not scroll.
613  // We also should pass the current fling parameters out to the client so the
614  // rest of the fling can be
615  // transferred to the main thread.
616  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
617      .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread));
618  EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_, testing::_)).Times(0);
619  EXPECT_CALL(mock_input_handler_, ScrollEnd()).Times(0);
620  // Expected wheel fling animation parameters:
621  // *) fling_delta and fling_point should match the original GestureFlingStart
622  // event
623  // *) startTime should be 10 to match the time parameter of the first
624  // Animate() call after the GestureFlingStart
625  // *) cumulativeScroll depends on the curve, but since we've animated in the
626  // -X direction the X value should be < 0
627  EXPECT_CALL(
628      mock_client_,
629      TransferActiveWheelFlingAnimation(testing::AllOf(
630          testing::Field(&WebActiveWheelFlingParameters::delta,
631                         testing::Eq(fling_delta)),
632          testing::Field(&WebActiveWheelFlingParameters::point,
633                         testing::Eq(fling_point)),
634          testing::Field(&WebActiveWheelFlingParameters::globalPoint,
635                         testing::Eq(fling_global_point)),
636          testing::Field(&WebActiveWheelFlingParameters::modifiers,
637                         testing::Eq(modifiers)),
638          testing::Field(&WebActiveWheelFlingParameters::startTime,
639                         testing::Eq(10)),
640          testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll,
641                         testing::Field(&WebSize::width, testing::Gt(0))))));
642  time += base::TimeDelta::FromMilliseconds(100);
643  input_handler_->Animate(time);
644
645  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
646  testing::Mock::VerifyAndClearExpectations(&mock_client_);
647
648  // Since we've aborted the fling, the next animation should be a no-op and
649  // should not result in another
650  // frame being requested.
651  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()).Times(0);
652  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
653      .Times(0);
654  time += base::TimeDelta::FromMilliseconds(100);
655  input_handler_->Animate(time);
656
657  // Since we've transferred the fling to the main thread, we need to pass the
658  // next GestureFlingCancel to the main
659  // thread as well.
660  expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
661  gesture_.type = WebInputEvent::GestureFlingCancel;
662  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
663}
664
665TEST_F(InputHandlerProxyTest, GestureFlingTransferResetsTouchpad) {
666  // We shouldn't send any events to the widget for this gesture.
667  expected_disposition_ = InputHandlerProxy::DID_HANDLE;
668  VERIFY_AND_RESET_MOCKS();
669
670  // Start a gesture fling in the -X direction with zero Y movement.
671  WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
672  WebPoint fling_point = WebPoint(7, 13);
673  WebPoint fling_global_point = WebPoint(17, 23);
674  // Note that for trackpad, wheel events with the Control modifier are
675  // special (reserved for zoom), so don't set that here.
676  int modifiers = WebInputEvent::ShiftKey | WebInputEvent::AltKey;
677  gesture_ = CreateFling(blink::WebGestureDeviceTouchpad,
678                         fling_delta,
679                         fling_point,
680                         fling_global_point,
681                         modifiers);
682  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
683  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
684      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
685  EXPECT_CALL(mock_input_handler_, ScrollEnd());
686  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
687
688  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
689
690  // Start the fling animation at time 10. This shouldn't actually scroll, just
691  // establish a start time.
692  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
693  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
694      .Times(0);
695  base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
696  input_handler_->Animate(time);
697
698  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
699
700  // The second call should start scrolling in the -X direction.
701  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
702  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
703      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
704  EXPECT_CALL(mock_input_handler_,
705              ScrollBy(testing::_,
706                       testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))
707      .WillOnce(testing::Return(true));
708  EXPECT_CALL(mock_input_handler_, ScrollEnd());
709  time += base::TimeDelta::FromMilliseconds(100);
710  input_handler_->Animate(time);
711
712  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
713
714  // Let's say on the third call we hit a non-scrollable region. We should abort
715  // the fling and not scroll.
716  // We also should pass the current fling parameters out to the client so the
717  // rest of the fling can be
718  // transferred to the main thread.
719  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
720      .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread));
721  EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_, testing::_)).Times(0);
722  EXPECT_CALL(mock_input_handler_, ScrollEnd()).Times(0);
723
724  // Expected wheel fling animation parameters:
725  // *) fling_delta and fling_point should match the original GestureFlingStart
726  // event
727  // *) startTime should be 10 to match the time parameter of the first
728  // Animate() call after the GestureFlingStart
729  // *) cumulativeScroll depends on the curve, but since we've animated in the
730  // -X direction the X value should be < 0
731  EXPECT_CALL(
732      mock_client_,
733      TransferActiveWheelFlingAnimation(testing::AllOf(
734          testing::Field(&WebActiveWheelFlingParameters::delta,
735                         testing::Eq(fling_delta)),
736          testing::Field(&WebActiveWheelFlingParameters::point,
737                         testing::Eq(fling_point)),
738          testing::Field(&WebActiveWheelFlingParameters::globalPoint,
739                         testing::Eq(fling_global_point)),
740          testing::Field(&WebActiveWheelFlingParameters::modifiers,
741                         testing::Eq(modifiers)),
742          testing::Field(&WebActiveWheelFlingParameters::startTime,
743                         testing::Eq(10)),
744          testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll,
745                         testing::Field(&WebSize::width, testing::Gt(0))))));
746  time += base::TimeDelta::FromMilliseconds(100);
747  input_handler_->Animate(time);
748
749  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
750  testing::Mock::VerifyAndClearExpectations(&mock_client_);
751
752  // Since we've aborted the fling, the next animation should be a no-op and
753  // should not result in another
754  // frame being requested.
755  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()).Times(0);
756  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
757      .Times(0);
758  time += base::TimeDelta::FromMilliseconds(100);
759  input_handler_->Animate(time);
760
761  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
762
763  // Since we've transferred the fling to the main thread, we need to pass the
764  // next GestureFlingCancel to the main
765  // thread as well.
766  expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
767  gesture_.type = WebInputEvent::GestureFlingCancel;
768  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
769
770  VERIFY_AND_RESET_MOCKS();
771  input_handler_->MainThreadHasStoppedFlinging();
772
773  // Start a second gesture fling, this time in the +Y direction with no X.
774  fling_delta = WebFloatPoint(0, -1000);
775  fling_point = WebPoint(95, 87);
776  fling_global_point = WebPoint(32, 71);
777  modifiers = WebInputEvent::AltKey;
778  gesture_ = CreateFling(blink::WebGestureDeviceTouchpad,
779                         fling_delta,
780                         fling_point,
781                         fling_global_point,
782                         modifiers);
783  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
784  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
785      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
786  EXPECT_CALL(mock_input_handler_, ScrollEnd());
787  expected_disposition_ = InputHandlerProxy::DID_HANDLE;
788  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
789
790  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
791
792  // Start the second fling animation at time 30.
793  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
794  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
795      .Times(0);
796  time = base::TimeTicks() + base::TimeDelta::FromSeconds(30);
797  input_handler_->Animate(time);
798
799  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
800
801  // Tick the second fling once normally.
802  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
803  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
804      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
805  EXPECT_CALL(mock_input_handler_,
806              ScrollBy(testing::_,
807                       testing::Property(&gfx::Vector2dF::y, testing::Gt(0))))
808      .WillOnce(testing::Return(true));
809  EXPECT_CALL(mock_input_handler_, ScrollEnd());
810  time += base::TimeDelta::FromMilliseconds(100);
811  input_handler_->Animate(time);
812
813  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
814
815  // Then abort the second fling.
816  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
817      .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread));
818  EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_, testing::_)).Times(0);
819  EXPECT_CALL(mock_input_handler_, ScrollEnd()).Times(0);
820
821  // We should get parameters from the second fling, nothing from the first
822  // fling should "leak".
823  EXPECT_CALL(
824      mock_client_,
825      TransferActiveWheelFlingAnimation(testing::AllOf(
826          testing::Field(&WebActiveWheelFlingParameters::delta,
827                         testing::Eq(fling_delta)),
828          testing::Field(&WebActiveWheelFlingParameters::point,
829                         testing::Eq(fling_point)),
830          testing::Field(&WebActiveWheelFlingParameters::globalPoint,
831                         testing::Eq(fling_global_point)),
832          testing::Field(&WebActiveWheelFlingParameters::modifiers,
833                         testing::Eq(modifiers)),
834          testing::Field(&WebActiveWheelFlingParameters::startTime,
835                         testing::Eq(30)),
836          testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll,
837                         testing::Field(&WebSize::height, testing::Lt(0))))));
838  time += base::TimeDelta::FromMilliseconds(100);
839  input_handler_->Animate(time);
840}
841
842TEST_F(InputHandlerProxyTest, GestureFlingStartedTouchscreen) {
843  // We shouldn't send any events to the widget for this gesture.
844  expected_disposition_ = InputHandlerProxy::DID_HANDLE;
845  VERIFY_AND_RESET_MOCKS();
846
847  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
848      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
849  gesture_.type = WebInputEvent::GestureScrollBegin;
850  gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen;
851  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
852
853  VERIFY_AND_RESET_MOCKS();
854
855  EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
856      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
857  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
858
859  gesture_.type = WebInputEvent::GestureFlingStart;
860  gesture_.data.flingStart.velocityX = 10;
861  gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen;
862  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
863
864  VERIFY_AND_RESET_MOCKS();
865
866  EXPECT_CALL(mock_input_handler_, ScrollEnd());
867
868  // Verify that a GestureFlingCancel during an animation cancels it.
869  gesture_.type = WebInputEvent::GestureFlingCancel;
870  gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen;
871  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
872}
873
874TEST_F(InputHandlerProxyTest, GestureFlingOnMainThreadTouchscreen) {
875  // We should send all events to the widget for this gesture.
876  expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
877  VERIFY_AND_RESET_MOCKS();
878
879  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
880      .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread));
881
882  gesture_.type = WebInputEvent::GestureScrollBegin;
883  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
884
885  VERIFY_AND_RESET_MOCKS();
886
887  EXPECT_CALL(mock_input_handler_, FlingScrollBegin()).Times(0);
888
889  gesture_.type = WebInputEvent::GestureFlingStart;
890  gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen;
891  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
892
893  VERIFY_AND_RESET_MOCKS();
894
895  // Even if we didn't start a fling ourselves, we still need to send the cancel
896  // event to the widget.
897  gesture_.type = WebInputEvent::GestureFlingCancel;
898  gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen;
899  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
900}
901
902TEST_F(InputHandlerProxyTest, GestureFlingIgnoredTouchscreen) {
903  expected_disposition_ = InputHandlerProxy::DID_HANDLE;
904  VERIFY_AND_RESET_MOCKS();
905
906  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
907      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
908
909  gesture_.type = WebInputEvent::GestureScrollBegin;
910  gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen;
911  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
912
913  expected_disposition_ = InputHandlerProxy::DROP_EVENT;
914  VERIFY_AND_RESET_MOCKS();
915
916  EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
917      .WillOnce(testing::Return(cc::InputHandler::ScrollIgnored));
918
919  gesture_.type = WebInputEvent::GestureFlingStart;
920  gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen;
921  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
922
923  VERIFY_AND_RESET_MOCKS();
924
925  // Even if we didn't start a fling ourselves, we still need to send the cancel
926  // event to the widget.
927  gesture_.type = WebInputEvent::GestureFlingCancel;
928  gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen;
929  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
930}
931
932TEST_F(InputHandlerProxyTest, GestureFlingAnimatesTouchscreen) {
933  // We shouldn't send any events to the widget for this gesture.
934  expected_disposition_ = InputHandlerProxy::DID_HANDLE;
935  VERIFY_AND_RESET_MOCKS();
936
937  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
938      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
939
940  gesture_.type = WebInputEvent::GestureScrollBegin;
941  gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen;
942  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
943
944  VERIFY_AND_RESET_MOCKS();
945
946  // On the fling start, we should schedule an animation but not actually start
947  // scrolling.
948  WebFloatPoint fling_delta = WebFloatPoint(100, 0);
949  WebPoint fling_point = WebPoint(7, 13);
950  WebPoint fling_global_point = WebPoint(17, 23);
951  // Note that for touchscreen the control modifier is not special.
952  int modifiers = WebInputEvent::ControlKey;
953  gesture_ = CreateFling(blink::WebGestureDeviceTouchscreen,
954                         fling_delta,
955                         fling_point,
956                         fling_global_point,
957                         modifiers);
958  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
959  EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
960      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
961  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
962
963  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
964  // The first animate call should let us pick up an animation start time, but
965  // we shouldn't actually move anywhere just yet. The first frame after the
966  // fling start will typically include the last scroll from the gesture that
967  // lead to the scroll (either wheel or gesture scroll), so there should be no
968  // visible hitch.
969  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
970  base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
971  input_handler_->Animate(time);
972
973  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
974
975  // The second call should start scrolling in the -X direction.
976  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
977  EXPECT_CALL(mock_input_handler_,
978              ScrollBy(testing::_,
979                       testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))
980      .WillOnce(testing::Return(true));
981  time += base::TimeDelta::FromMilliseconds(100);
982  input_handler_->Animate(time);
983
984  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
985
986  EXPECT_CALL(mock_input_handler_, ScrollEnd());
987  gesture_.type = WebInputEvent::GestureFlingCancel;
988  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
989}
990
991TEST_F(InputHandlerProxyTest, GestureFlingWithValidTimestamp) {
992  // We shouldn't send any events to the widget for this gesture.
993  expected_disposition_ = InputHandlerProxy::DID_HANDLE;
994  VERIFY_AND_RESET_MOCKS();
995
996  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
997      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
998
999  gesture_.type = WebInputEvent::GestureScrollBegin;
1000  gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen;
1001  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1002
1003  VERIFY_AND_RESET_MOCKS();
1004
1005  // On the fling start, we should schedule an animation but not actually start
1006  // scrolling.
1007  base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10);
1008  base::TimeTicks time = base::TimeTicks() + dt;
1009  WebFloatPoint fling_delta = WebFloatPoint(100, 0);
1010  WebPoint fling_point = WebPoint(7, 13);
1011  WebPoint fling_global_point = WebPoint(17, 23);
1012  int modifiers = WebInputEvent::ControlKey;
1013  gesture_ = CreateFling(time,
1014                         blink::WebGestureDeviceTouchscreen,
1015                         fling_delta,
1016                         fling_point,
1017                         fling_global_point,
1018                         modifiers);
1019  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1020  EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
1021      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
1022  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1023
1024  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1025  // With a valid time stamp, the first animate call should skip start time
1026  // initialization and immediately begin scroll update production. This reduces
1027  // the likelihood of a hitch between the scroll preceding the fling and
1028  // the first scroll generated by the fling.
1029  // Scrolling should start in the -X direction.
1030  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1031  EXPECT_CALL(mock_input_handler_,
1032              ScrollBy(testing::_,
1033                       testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))
1034      .WillOnce(testing::Return(true));
1035  time += dt;
1036  input_handler_->Animate(time);
1037
1038  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1039
1040  EXPECT_CALL(mock_input_handler_, ScrollEnd());
1041  gesture_.type = WebInputEvent::GestureFlingCancel;
1042  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1043}
1044
1045TEST_F(InputHandlerProxyTest, GestureFlingWithInvalidTimestamp) {
1046  // We shouldn't send any events to the widget for this gesture.
1047  expected_disposition_ = InputHandlerProxy::DID_HANDLE;
1048  VERIFY_AND_RESET_MOCKS();
1049
1050  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
1051      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
1052
1053  gesture_.type = WebInputEvent::GestureScrollBegin;
1054  gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen;
1055  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1056
1057  VERIFY_AND_RESET_MOCKS();
1058
1059  // On the fling start, we should schedule an animation but not actually start
1060  // scrolling.
1061  base::TimeDelta start_time_offset = base::TimeDelta::FromMilliseconds(10);
1062  gesture_.type = WebInputEvent::GestureFlingStart;
1063  WebFloatPoint fling_delta = WebFloatPoint(100, 0);
1064  WebPoint fling_point = WebPoint(7, 13);
1065  WebPoint fling_global_point = WebPoint(17, 23);
1066  int modifiers = WebInputEvent::ControlKey;
1067  gesture_.timeStampSeconds = start_time_offset.InSecondsF();
1068  gesture_.data.flingStart.velocityX = fling_delta.x;
1069  gesture_.data.flingStart.velocityY = fling_delta.y;
1070  gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen;
1071  gesture_.x = fling_point.x;
1072  gesture_.y = fling_point.y;
1073  gesture_.globalX = fling_global_point.x;
1074  gesture_.globalY = fling_global_point.y;
1075  gesture_.modifiers = modifiers;
1076  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1077  EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
1078      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
1079  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1080
1081  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1082  // Event though a time stamp was provided for the fling event, it will be
1083  // ignored as its too far in the past relative to the first animate call's
1084  // timestamp.
1085  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1086  base::TimeTicks time =
1087      base::TimeTicks() + start_time_offset + base::TimeDelta::FromSeconds(1);
1088  input_handler_->Animate(time);
1089
1090  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1091
1092  // Further animation ticks should update the fling as usual.
1093  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1094  EXPECT_CALL(mock_input_handler_,
1095              ScrollBy(testing::_,
1096                       testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))
1097      .WillOnce(testing::Return(true));
1098  time += base::TimeDelta::FromMilliseconds(10);
1099  input_handler_->Animate(time);
1100
1101  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1102
1103  EXPECT_CALL(mock_input_handler_, ScrollEnd());
1104  gesture_.type = WebInputEvent::GestureFlingCancel;
1105  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1106}
1107
1108TEST_F(InputHandlerProxyTest,
1109       GestureScrollOnImplThreadFlagClearedAfterFling) {
1110  // We shouldn't send any events to the widget for this gesture.
1111  expected_disposition_ = InputHandlerProxy::DID_HANDLE;
1112  VERIFY_AND_RESET_MOCKS();
1113
1114  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
1115      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
1116
1117  gesture_.type = WebInputEvent::GestureScrollBegin;
1118  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1119
1120  // After sending a GestureScrollBegin, the member variable
1121  // |gesture_scroll_on_impl_thread_| should be true.
1122  EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
1123
1124  expected_disposition_ = InputHandlerProxy::DID_HANDLE;
1125  VERIFY_AND_RESET_MOCKS();
1126
1127  // On the fling start, we should schedule an animation but not actually start
1128  // scrolling.
1129  WebFloatPoint fling_delta = WebFloatPoint(100, 0);
1130  WebPoint fling_point = WebPoint(7, 13);
1131  WebPoint fling_global_point = WebPoint(17, 23);
1132  int modifiers = WebInputEvent::ControlKey | WebInputEvent::AltKey;
1133  gesture_ = CreateFling(blink::WebGestureDeviceTouchscreen,
1134                         fling_delta,
1135                         fling_point,
1136                         fling_global_point,
1137                         modifiers);
1138  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1139  EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
1140      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
1141  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1142
1143  // |gesture_scroll_on_impl_thread_| should still be true after
1144  // a GestureFlingStart is sent.
1145  EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
1146
1147  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1148  // The first animate call should let us pick up an animation start time, but
1149  // we shouldn't actually move anywhere just yet. The first frame after the
1150  // fling start will typically include the last scroll from the gesture that
1151  // lead to the scroll (either wheel or gesture scroll), so there should be no
1152  // visible hitch.
1153  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1154  base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
1155  input_handler_->Animate(time);
1156
1157  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1158
1159  // The second call should start scrolling in the -X direction.
1160  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1161  EXPECT_CALL(mock_input_handler_,
1162              ScrollBy(testing::_,
1163                       testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))
1164      .WillOnce(testing::Return(true));
1165  time += base::TimeDelta::FromMilliseconds(100);
1166  input_handler_->Animate(time);
1167
1168  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1169
1170  EXPECT_CALL(mock_input_handler_, ScrollEnd());
1171  gesture_.type = WebInputEvent::GestureFlingCancel;
1172  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1173
1174  // |gesture_scroll_on_impl_thread_| should be false once
1175  // the fling has finished (note no GestureScrollEnd has been sent).
1176  EXPECT_TRUE(!input_handler_->gesture_scroll_on_impl_thread_for_testing());
1177}
1178
1179TEST_F(InputHandlerProxyTest, GestureFlingStopsAtContentEdge) {
1180  // We shouldn't send any events to the widget for this gesture.
1181  expected_disposition_ = InputHandlerProxy::DID_HANDLE;
1182  VERIFY_AND_RESET_MOCKS();
1183
1184  // On the fling start, we should schedule an animation but not actually start
1185  // scrolling.
1186  gesture_.type = WebInputEvent::GestureFlingStart;
1187  WebFloatPoint fling_delta = WebFloatPoint(100, 100);
1188  gesture_.data.flingStart.velocityX = fling_delta.x;
1189  gesture_.data.flingStart.velocityY = fling_delta.y;
1190  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1191  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
1192      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
1193  EXPECT_CALL(mock_input_handler_, ScrollEnd());
1194  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1195  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1196
1197  // The first animate doesn't cause any scrolling.
1198  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1199  base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
1200  input_handler_->Animate(time);
1201  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1202
1203  // The second animate starts scrolling in the positive X and Y directions.
1204  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1205  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
1206      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
1207  EXPECT_CALL(mock_input_handler_,
1208              ScrollBy(testing::_,
1209                       testing::Property(&gfx::Vector2dF::y, testing::Lt(0))))
1210      .WillOnce(testing::Return(true));
1211  EXPECT_CALL(mock_input_handler_, ScrollEnd());
1212  time += base::TimeDelta::FromMilliseconds(100);
1213  input_handler_->Animate(time);
1214  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1215
1216  // Simulate hitting the bottom content edge.
1217  gfx::Vector2dF accumulated_overscroll(0, 100);
1218  gfx::Vector2dF latest_overscroll_delta(0, 10);
1219  gfx::PointF scroll_point(10, 0);
1220  EXPECT_CALL(
1221      mock_client_,
1222      DidOverscroll(testing::AllOf(
1223          testing::Field(&DidOverscrollParams::accumulated_overscroll,
1224                         testing::Eq(accumulated_overscroll)),
1225          testing::Field(&DidOverscrollParams::latest_overscroll_delta,
1226                         testing::Eq(latest_overscroll_delta)),
1227          testing::Field(&DidOverscrollParams::current_fling_velocity,
1228                         testing::Property(&gfx::Vector2dF::y, testing::Lt(0))),
1229          testing::Field(&DidOverscrollParams::causal_event_viewport_point,
1230                         testing::Eq(scroll_point)))));
1231  input_handler_->DidOverscroll(
1232      scroll_point, accumulated_overscroll, latest_overscroll_delta);
1233
1234  // The next call to animate will no longer scroll vertically.
1235  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1236  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
1237      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
1238  EXPECT_CALL(mock_input_handler_,
1239              ScrollBy(testing::_,
1240                       testing::Property(&gfx::Vector2dF::y, testing::Eq(0))))
1241      .WillOnce(testing::Return(true));
1242  EXPECT_CALL(mock_input_handler_, ScrollEnd());
1243  time += base::TimeDelta::FromMilliseconds(100);
1244  input_handler_->Animate(time);
1245  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1246}
1247
1248TEST_F(InputHandlerProxyTest, GestureFlingNotCancelledBySmallTimeDelta) {
1249  // We shouldn't send any events to the widget for this gesture.
1250  expected_disposition_ = InputHandlerProxy::DID_HANDLE;
1251  VERIFY_AND_RESET_MOCKS();
1252
1253  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
1254      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
1255
1256  gesture_.type = WebInputEvent::GestureScrollBegin;
1257  gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen;
1258  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1259
1260  VERIFY_AND_RESET_MOCKS();
1261
1262  // On the fling start, we should schedule an animation but not actually start
1263  // scrolling.
1264  base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10);
1265  base::TimeTicks time = base::TimeTicks() + dt;
1266  WebFloatPoint fling_delta = WebFloatPoint(100, 0);
1267  WebPoint fling_point = WebPoint(7, 13);
1268  WebPoint fling_global_point = WebPoint(17, 23);
1269  int modifiers = WebInputEvent::ControlKey;
1270  gesture_ = CreateFling(time,
1271                         blink::WebGestureDeviceTouchscreen,
1272                         fling_delta,
1273                         fling_point,
1274                         fling_global_point,
1275                         modifiers);
1276  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1277  EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
1278      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
1279  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1280
1281  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1282  // With an animation timestamp equivalent to the starting timestamp, the
1283  // animation will simply be rescheduled.
1284  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1285  input_handler_->Animate(time);
1286
1287  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1288  EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
1289
1290  // A small time delta should not stop the fling, even if the client
1291  // reports no scrolling.
1292  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1293  EXPECT_CALL(mock_input_handler_,
1294              ScrollBy(testing::_,
1295                       testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))
1296      .WillOnce(testing::Return(false));
1297  time += base::TimeDelta::FromMicroseconds(5);
1298  input_handler_->Animate(time);
1299
1300  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1301  EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
1302
1303  // A time delta of zero should not stop the fling, and neither should it
1304  // trigger scrolling on the client.
1305  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1306  input_handler_->Animate(time);
1307
1308  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1309  EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
1310
1311  // Lack of movement on the client, with a non-trivial scroll delta, should
1312  // terminate the fling.
1313  EXPECT_CALL(mock_input_handler_, ScrollEnd());
1314  EXPECT_CALL(mock_input_handler_,
1315              ScrollBy(testing::_,
1316                       testing::Property(&gfx::Vector2dF::x, testing::Lt(1))))
1317      .WillOnce(testing::Return(false));
1318  time += base::TimeDelta::FromMilliseconds(100);
1319  input_handler_->Animate(time);
1320
1321  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1322  EXPECT_FALSE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
1323}
1324
1325TEST_F(InputHandlerProxyTest, GestureFlingCancelledAfterBothAxesStopScrolling) {
1326  // We shouldn't send any events to the widget for this gesture.
1327  expected_disposition_ = InputHandlerProxy::DID_HANDLE;
1328  VERIFY_AND_RESET_MOCKS();
1329
1330  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
1331      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
1332  gesture_.type = WebInputEvent::GestureScrollBegin;
1333  gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen;
1334  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1335  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1336
1337  // On the fling start, we should schedule an animation but not actually start
1338  // scrolling.
1339  gesture_.type = WebInputEvent::GestureFlingStart;
1340  WebFloatPoint fling_delta = WebFloatPoint(100, 100);
1341  gesture_.data.flingStart.velocityX = fling_delta.x;
1342  gesture_.data.flingStart.velocityY = fling_delta.y;
1343  EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
1344      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
1345  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1346  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1347  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1348
1349  // The first animate doesn't cause any scrolling.
1350  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1351  base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
1352  input_handler_->Animate(time);
1353  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1354
1355  // The second animate starts scrolling in the positive X and Y directions.
1356  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1357  EXPECT_CALL(mock_input_handler_,
1358              ScrollBy(testing::_,
1359                       testing::Property(&gfx::Vector2dF::y, testing::Lt(0))))
1360      .WillOnce(testing::Return(true));
1361  time += base::TimeDelta::FromMilliseconds(10);
1362  input_handler_->Animate(time);
1363  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1364
1365  // Simulate hitting the bottom content edge.
1366  gfx::Vector2dF accumulated_overscroll(0, 100);
1367  gfx::Vector2dF latest_overscroll_delta(0, 100);
1368  gfx::PointF scroll_point(10, -50);
1369  EXPECT_CALL(
1370      mock_client_,
1371      DidOverscroll(testing::AllOf(
1372          testing::Field(&DidOverscrollParams::accumulated_overscroll,
1373                         testing::Eq(accumulated_overscroll)),
1374          testing::Field(&DidOverscrollParams::latest_overscroll_delta,
1375                         testing::Eq(latest_overscroll_delta)),
1376          testing::Field(&DidOverscrollParams::current_fling_velocity,
1377                         testing::Property(&gfx::Vector2dF::y, testing::Lt(0))),
1378          testing::Field(&DidOverscrollParams::causal_event_viewport_point,
1379                         testing::Eq(scroll_point)))));
1380  input_handler_->DidOverscroll(
1381      scroll_point, accumulated_overscroll, latest_overscroll_delta);
1382
1383  // The next call to animate will no longer scroll vertically.
1384  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1385  EXPECT_CALL(mock_input_handler_,
1386              ScrollBy(testing::_,
1387                       testing::Property(&gfx::Vector2dF::y, testing::Eq(0))))
1388      .WillOnce(testing::Return(true));
1389  time += base::TimeDelta::FromMilliseconds(10);
1390  input_handler_->Animate(time);
1391  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1392
1393  // Simulate hitting the right content edge.
1394  accumulated_overscroll = gfx::Vector2dF(100, 100);
1395  latest_overscroll_delta = gfx::Vector2dF(100, 0);
1396  scroll_point = gfx::PointF(50, 0);
1397  EXPECT_CALL(
1398      mock_client_,
1399      DidOverscroll(testing::AllOf(
1400          testing::Field(&DidOverscrollParams::accumulated_overscroll,
1401                         testing::Eq(accumulated_overscroll)),
1402          testing::Field(&DidOverscrollParams::latest_overscroll_delta,
1403                         testing::Eq(latest_overscroll_delta)),
1404          testing::Field(&DidOverscrollParams::current_fling_velocity,
1405                         testing::Property(&gfx::Vector2dF::x, testing::Lt(0))),
1406          testing::Field(&DidOverscrollParams::causal_event_viewport_point,
1407                         testing::Eq(scroll_point)))));
1408  input_handler_->DidOverscroll(
1409      scroll_point, accumulated_overscroll, latest_overscroll_delta);
1410  // The next call to animate will no longer scroll horizontally or vertically,
1411  // and the fling should be cancelled.
1412  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()).Times(0);
1413  EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_, testing::_)).Times(0);
1414  EXPECT_CALL(mock_input_handler_, ScrollEnd());
1415  time += base::TimeDelta::FromMilliseconds(10);
1416  input_handler_->Animate(time);
1417  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1418  EXPECT_FALSE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
1419}
1420
1421TEST_F(InputHandlerProxyTest, MultiTouchPointHitTestNegative) {
1422  // None of the three touch points fall in the touch region. So the event
1423  // should be dropped.
1424  expected_disposition_ = InputHandlerProxy::DROP_EVENT;
1425  VERIFY_AND_RESET_MOCKS();
1426
1427  EXPECT_CALL(mock_input_handler_,
1428              HaveTouchEventHandlersAt(
1429                  testing::Property(&gfx::Point::x, testing::Gt(0))))
1430      .WillOnce(testing::Return(false));
1431  EXPECT_CALL(mock_input_handler_,
1432              HaveTouchEventHandlersAt(
1433                  testing::Property(&gfx::Point::x, testing::Lt(0))))
1434      .WillOnce(testing::Return(false));
1435
1436  WebTouchEvent touch;
1437  touch.type = WebInputEvent::TouchStart;
1438
1439  touch.touchesLength = 3;
1440  touch.touches[0] = CreateWebTouchPoint(WebTouchPoint::StateStationary, 0, 0);
1441  touch.touches[1] = CreateWebTouchPoint(WebTouchPoint::StatePressed, 10, 10);
1442  touch.touches[2] = CreateWebTouchPoint(WebTouchPoint::StatePressed, -10, 10);
1443  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(touch));
1444}
1445
1446TEST_F(InputHandlerProxyTest, MultiTouchPointHitTestPositive) {
1447  // One of the touch points is on a touch-region. So the event should be sent
1448  // to the main thread.
1449  expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
1450  VERIFY_AND_RESET_MOCKS();
1451
1452  EXPECT_CALL(mock_input_handler_,
1453              HaveTouchEventHandlersAt(
1454                  testing::Property(&gfx::Point::x, testing::Eq(0))))
1455      .WillOnce(testing::Return(false));
1456  EXPECT_CALL(mock_input_handler_,
1457              HaveTouchEventHandlersAt(
1458                  testing::Property(&gfx::Point::x, testing::Gt(0))))
1459      .WillOnce(testing::Return(true));
1460  // Since the second touch point hits a touch-region, there should be no
1461  // hit-testing for the third touch point.
1462
1463  WebTouchEvent touch;
1464  touch.type = WebInputEvent::TouchStart;
1465
1466  touch.touchesLength = 3;
1467  touch.touches[0] = CreateWebTouchPoint(WebTouchPoint::StatePressed, 0, 0);
1468  touch.touches[1] = CreateWebTouchPoint(WebTouchPoint::StatePressed, 10, 10);
1469  touch.touches[2] = CreateWebTouchPoint(WebTouchPoint::StatePressed, -10, 10);
1470  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(touch));
1471}
1472
1473TEST_F(InputHandlerProxyTest, GestureFlingCancelledByKeyboardEvent) {
1474  // We shouldn't send any events to the widget for this gesture.
1475  expected_disposition_ = InputHandlerProxy::DID_HANDLE;
1476  VERIFY_AND_RESET_MOCKS();
1477
1478  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
1479      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
1480  gesture_.type = WebInputEvent::GestureScrollBegin;
1481  gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen;
1482  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1483  EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
1484  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1485
1486  // Keyboard events received during a scroll should have no effect.
1487  WebKeyboardEvent key_event;
1488  key_event.type = WebInputEvent::KeyDown;
1489  EXPECT_EQ(InputHandlerProxy::DID_NOT_HANDLE,
1490            input_handler_->HandleInputEvent(key_event));
1491  EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
1492  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1493
1494  // On the fling start, animation should be scheduled, but no scrolling occurs.
1495  gesture_.type = WebInputEvent::GestureFlingStart;
1496  WebFloatPoint fling_delta = WebFloatPoint(100, 100);
1497  gesture_.data.flingStart.velocityX = fling_delta.x;
1498  gesture_.data.flingStart.velocityY = fling_delta.y;
1499  EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
1500      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
1501  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1502  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1503  EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
1504  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1505
1506  // Keyboard events received during a fling should cancel the active fling.
1507  EXPECT_CALL(mock_input_handler_, ScrollEnd());
1508  EXPECT_EQ(InputHandlerProxy::DID_NOT_HANDLE,
1509            input_handler_->HandleInputEvent(key_event));
1510  EXPECT_FALSE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
1511  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1512
1513  // The call to animate should have no effect, as the fling was cancelled.
1514  base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
1515  input_handler_->Animate(time);
1516  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1517
1518  // A fling cancel should be dropped, as there is nothing to cancel.
1519  gesture_.type = WebInputEvent::GestureFlingCancel;
1520  EXPECT_EQ(InputHandlerProxy::DROP_EVENT,
1521            input_handler_->HandleInputEvent(gesture_));
1522  EXPECT_FALSE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
1523}
1524
1525TEST_F(InputHandlerProxyTest, GestureFlingWithNegativeTimeDelta) {
1526  // We shouldn't send any events to the widget for this gesture.
1527  expected_disposition_ = InputHandlerProxy::DID_HANDLE;
1528  VERIFY_AND_RESET_MOCKS();
1529
1530  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
1531      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
1532
1533  gesture_.type = WebInputEvent::GestureScrollBegin;
1534  gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen;
1535  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1536
1537  VERIFY_AND_RESET_MOCKS();
1538
1539  // On the fling start, we should schedule an animation but not actually start
1540  // scrolling.
1541  base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10);
1542  base::TimeTicks time = base::TimeTicks() + dt;
1543  WebFloatPoint fling_delta = WebFloatPoint(100, 0);
1544  WebPoint fling_point = WebPoint(7, 13);
1545  WebPoint fling_global_point = WebPoint(17, 23);
1546  int modifiers = WebInputEvent::ControlKey;
1547  gesture_ = CreateFling(time,
1548                         blink::WebGestureDeviceTouchscreen,
1549                         fling_delta,
1550                         fling_point,
1551                         fling_global_point,
1552                         modifiers);
1553  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1554  EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
1555      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
1556  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1557
1558  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1559
1560  // If we get a negative time delta, that is, the Animation tick time happens
1561  // before the fling's start time then we should *not* try scrolling and
1562  // instead reset the fling start time.
1563  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1564  EXPECT_CALL(mock_input_handler_,
1565              ScrollBy(testing::_,
1566                       testing::_)).Times(0);
1567  time -= base::TimeDelta::FromMilliseconds(5);
1568  input_handler_->Animate(time);
1569
1570  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1571
1572  // The first call should have reset the start time so subsequent calls should
1573  // generate scroll events.
1574  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1575  EXPECT_CALL(mock_input_handler_,
1576              ScrollBy(testing::_,
1577                       testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))
1578      .WillOnce(testing::Return(true));
1579
1580  input_handler_->Animate(time + base::TimeDelta::FromMilliseconds(1));
1581
1582  testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
1583
1584  EXPECT_CALL(mock_input_handler_, ScrollEnd());
1585  gesture_.type = WebInputEvent::GestureFlingCancel;
1586  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1587}
1588
1589TEST_F(InputHandlerProxyTest, FlingBoost) {
1590  base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10);
1591  base::TimeTicks time = base::TimeTicks() + dt;
1592  base::TimeTicks last_animate_time = time;
1593  WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
1594  WebPoint fling_point = WebPoint(7, 13);
1595  StartFling(
1596      time, blink::WebGestureDeviceTouchscreen, fling_delta, fling_point);
1597
1598  // Now cancel the fling.  The fling cancellation should be deferred to allow
1599  // fling boosting events to arrive.
1600  time += dt;
1601  CancelFling(time);
1602
1603  // The GestureScrollBegin should be swallowed by the fling if it hits the same
1604  // scrolling layer.
1605  EXPECT_CALL(mock_input_handler_,
1606              IsCurrentlyScrollingLayerAt(testing::_, testing::_))
1607      .WillOnce(testing::Return(true));
1608
1609  time += dt;
1610  gesture_.timeStampSeconds = InSecondsF(time);
1611  gesture_.type = WebInputEvent::GestureScrollBegin;
1612  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1613
1614  VERIFY_AND_RESET_MOCKS();
1615
1616  // Animate calls within the deferred cancellation window should continue.
1617  time += dt;
1618  float expected_delta =
1619      (time - last_animate_time).InSecondsF() * -fling_delta.x;
1620  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1621  EXPECT_CALL(mock_input_handler_,
1622              ScrollBy(testing::_,
1623                       testing::Property(&gfx::Vector2dF::x,
1624                                         testing::Eq(expected_delta))))
1625      .WillOnce(testing::Return(true));
1626  input_handler_->Animate(time);
1627  last_animate_time = time;
1628
1629  VERIFY_AND_RESET_MOCKS();
1630
1631  // GestureScrollUpdates in the same direction and at sufficient speed should
1632  // be swallowed by the fling.
1633  time += dt;
1634  gesture_.timeStampSeconds = InSecondsF(time);
1635  gesture_.type = WebInputEvent::GestureScrollUpdate;
1636  gesture_.data.scrollUpdate.deltaX = fling_delta.x;
1637  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1638
1639  VERIFY_AND_RESET_MOCKS();
1640
1641  // Animate calls within the deferred cancellation window should continue.
1642  time += dt;
1643  expected_delta = (time - last_animate_time).InSecondsF() * -fling_delta.x;
1644  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1645  EXPECT_CALL(mock_input_handler_,
1646              ScrollBy(testing::_,
1647                       testing::Property(&gfx::Vector2dF::x,
1648                                         testing::Eq(expected_delta))))
1649      .WillOnce(testing::Return(true));
1650  input_handler_->Animate(time);
1651  last_animate_time = time;
1652
1653  VERIFY_AND_RESET_MOCKS();
1654
1655  // GestureFlingStart in the same direction and at sufficient speed should
1656  // boost the active fling.
1657
1658  gesture_ = CreateFling(time,
1659                         blink::WebGestureDeviceTouchscreen,
1660                         fling_delta,
1661                         fling_point,
1662                         fling_point,
1663                         0);
1664  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1665  VERIFY_AND_RESET_MOCKS();
1666
1667  time += dt;
1668  // Note we get *2x* as much delta because 2 flings have combined.
1669  expected_delta = 2 * (time - last_animate_time).InSecondsF() * -fling_delta.x;
1670  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1671  EXPECT_CALL(mock_input_handler_,
1672              ScrollBy(testing::_,
1673                       testing::Property(&gfx::Vector2dF::x,
1674                                         testing::Eq(expected_delta))))
1675      .WillOnce(testing::Return(true));
1676  input_handler_->Animate(time);
1677  last_animate_time = time;
1678
1679  VERIFY_AND_RESET_MOCKS();
1680
1681  // Repeated GestureFlingStarts should accumulate.
1682
1683  CancelFling(time);
1684  gesture_ = CreateFling(time,
1685                         blink::WebGestureDeviceTouchscreen,
1686                         fling_delta,
1687                         fling_point,
1688                         fling_point,
1689                         0);
1690  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1691  VERIFY_AND_RESET_MOCKS();
1692
1693  time += dt;
1694  // Note we get *3x* as much delta because 3 flings have combined.
1695  expected_delta = 3 * (time - last_animate_time).InSecondsF() * -fling_delta.x;
1696  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1697  EXPECT_CALL(mock_input_handler_,
1698              ScrollBy(testing::_,
1699                       testing::Property(&gfx::Vector2dF::x,
1700                                         testing::Eq(expected_delta))))
1701      .WillOnce(testing::Return(true));
1702  input_handler_->Animate(time);
1703  last_animate_time = time;
1704
1705  VERIFY_AND_RESET_MOCKS();
1706
1707  // GestureFlingCancel should terminate the fling if no boosting gestures are
1708  // received within the timeout window.
1709
1710  time += dt;
1711  gesture_.timeStampSeconds = InSecondsF(time);
1712  gesture_.type = WebInputEvent::GestureFlingCancel;
1713  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1714
1715  VERIFY_AND_RESET_MOCKS();
1716
1717  time += base::TimeDelta::FromMilliseconds(100);
1718  EXPECT_CALL(mock_input_handler_, ScrollEnd());
1719  input_handler_->Animate(time);
1720
1721  VERIFY_AND_RESET_MOCKS();
1722}
1723
1724TEST_F(InputHandlerProxyTest, NoFlingBoostIfScrollTargetsDifferentLayer) {
1725  base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10);
1726  base::TimeTicks time = base::TimeTicks() + dt;
1727  WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
1728  WebPoint fling_point = WebPoint(7, 13);
1729  StartFling(
1730      time, blink::WebGestureDeviceTouchscreen, fling_delta, fling_point);
1731
1732  // Cancel the fling.  The fling cancellation should be deferred to allow
1733  // fling boosting events to arrive.
1734  time += dt;
1735  CancelFling(time);
1736
1737  // If the GestureScrollBegin targets a different layer, the fling should be
1738  // cancelled and the scroll should be handled as usual.
1739  EXPECT_CALL(mock_input_handler_,
1740              IsCurrentlyScrollingLayerAt(testing::_, testing::_))
1741      .WillOnce(testing::Return(false));
1742  EXPECT_CALL(mock_input_handler_, ScrollEnd());
1743  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
1744      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
1745
1746  time += dt;
1747  gesture_.timeStampSeconds = InSecondsF(time);
1748  gesture_.type = WebInputEvent::GestureScrollBegin;
1749  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1750
1751  VERIFY_AND_RESET_MOCKS();
1752}
1753
1754TEST_F(InputHandlerProxyTest, NoFlingBoostIfScrollDelayed) {
1755  base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10);
1756  base::TimeTicks time = base::TimeTicks() + dt;
1757  WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
1758  WebPoint fling_point = WebPoint(7, 13);
1759  StartFling(
1760      time, blink::WebGestureDeviceTouchscreen, fling_delta, fling_point);
1761
1762  // Cancel the fling.  The fling cancellation should be deferred to allow
1763  // fling boosting events to arrive.
1764  time += dt;
1765  CancelFling(time);
1766
1767  // The GestureScrollBegin should be swallowed by the fling if it hits the same
1768  // scrolling layer.
1769  EXPECT_CALL(mock_input_handler_,
1770              IsCurrentlyScrollingLayerAt(testing::_, testing::_))
1771      .WillOnce(testing::Return(true));
1772
1773  time += dt;
1774  gesture_.timeStampSeconds = InSecondsF(time);
1775  gesture_.type = WebInputEvent::GestureScrollBegin;
1776  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1777
1778  VERIFY_AND_RESET_MOCKS();
1779
1780  // If no GestureScrollUpdate or GestureFlingStart is received within the
1781  // timeout window, the fling should be cancelled and scrolling should resume.
1782  time += base::TimeDelta::FromMilliseconds(100);
1783  EXPECT_CALL(mock_input_handler_, ScrollEnd());
1784  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
1785      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
1786  input_handler_->Animate(time);
1787
1788  VERIFY_AND_RESET_MOCKS();
1789}
1790
1791TEST_F(InputHandlerProxyTest, NoFlingBoostIfFlingInDifferentDirection) {
1792  base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10);
1793  base::TimeTicks time = base::TimeTicks() + dt;
1794  WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
1795  WebPoint fling_point = WebPoint(7, 13);
1796  StartFling(
1797      time, blink::WebGestureDeviceTouchscreen, fling_delta, fling_point);
1798
1799  // Cancel the fling.  The fling cancellation should be deferred to allow
1800  // fling boosting events to arrive.
1801  time += dt;
1802  CancelFling(time);
1803
1804  // If the new fling is orthogonal to the existing fling, no boosting should
1805  // take place, with the new fling replacing the old.
1806  WebFloatPoint orthogonal_fling_delta =
1807      WebFloatPoint(fling_delta.y, -fling_delta.x);
1808  gesture_ = CreateFling(time,
1809                         blink::WebGestureDeviceTouchscreen,
1810                         orthogonal_fling_delta,
1811                         fling_point,
1812                         fling_point,
1813                         0);
1814  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1815
1816  VERIFY_AND_RESET_MOCKS();
1817
1818  // Note that the new fling delta uses the orthogonal, unboosted fling
1819  // velocity.
1820  time += dt;
1821  float expected_delta = dt.InSecondsF() * -orthogonal_fling_delta.y;
1822  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1823  EXPECT_CALL(mock_input_handler_,
1824              ScrollBy(testing::_,
1825                       testing::Property(&gfx::Vector2dF::y,
1826                                         testing::Eq(expected_delta))))
1827      .WillOnce(testing::Return(true));
1828  input_handler_->Animate(time);
1829
1830  VERIFY_AND_RESET_MOCKS();
1831}
1832
1833TEST_F(InputHandlerProxyTest, NoFlingBoostIfScrollInDifferentDirection) {
1834  base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10);
1835  base::TimeTicks time = base::TimeTicks() + dt;
1836  WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
1837  WebPoint fling_point = WebPoint(7, 13);
1838  StartFling(
1839      time, blink::WebGestureDeviceTouchscreen, fling_delta, fling_point);
1840
1841  // Cancel the fling.  The fling cancellation should be deferred to allow
1842  // fling boosting events to arrive.
1843  time += dt;
1844  CancelFling(time);
1845
1846  // The GestureScrollBegin should be swallowed by the fling if it hits the same
1847  // scrolling layer.
1848  EXPECT_CALL(mock_input_handler_,
1849              IsCurrentlyScrollingLayerAt(testing::_, testing::_))
1850      .WillOnce(testing::Return(true));
1851
1852  time += dt;
1853  gesture_.timeStampSeconds = InSecondsF(time);
1854  gesture_.type = WebInputEvent::GestureScrollBegin;
1855  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1856
1857  VERIFY_AND_RESET_MOCKS();
1858
1859  // If the GestureScrollUpdate is in a different direction than the fling,
1860  // the fling should be cancelled and scrolling should resume.
1861  time += dt;
1862  gesture_.timeStampSeconds = InSecondsF(time);
1863  gesture_.type = WebInputEvent::GestureScrollUpdate;
1864  gesture_.data.scrollUpdate.deltaX = -fling_delta.x;
1865  EXPECT_CALL(mock_input_handler_, ScrollEnd());
1866  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
1867      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
1868  EXPECT_CALL(mock_input_handler_,
1869              ScrollBy(testing::_,
1870                       testing::Property(&gfx::Vector2dF::x,
1871                                         testing::Eq(fling_delta.x))))
1872      .WillOnce(testing::Return(true));
1873  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1874
1875  VERIFY_AND_RESET_MOCKS();
1876}
1877
1878TEST_F(InputHandlerProxyTest, NoFlingBoostIfFlingTooSlow) {
1879  base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10);
1880  base::TimeTicks time = base::TimeTicks() + dt;
1881  WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
1882  WebPoint fling_point = WebPoint(7, 13);
1883  StartFling(
1884      time, blink::WebGestureDeviceTouchscreen, fling_delta, fling_point);
1885
1886  // Cancel the fling.  The fling cancellation should be deferred to allow
1887  // fling boosting events to arrive.
1888  time += dt;
1889  CancelFling(time);
1890
1891  // If the new fling is too slow, no boosting should take place, with the new
1892  // fling replacing the old.
1893  WebFloatPoint small_fling_delta = WebFloatPoint(100, 0);
1894  gesture_ = CreateFling(time,
1895                         blink::WebGestureDeviceTouchscreen,
1896                         small_fling_delta,
1897                         fling_point,
1898                         fling_point,
1899                         0);
1900  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1901
1902  VERIFY_AND_RESET_MOCKS();
1903
1904  // Note that the new fling delta uses the *slow*, unboosted fling velocity.
1905  time += dt;
1906  float expected_delta = dt.InSecondsF() * -small_fling_delta.x;
1907  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
1908  EXPECT_CALL(mock_input_handler_,
1909              ScrollBy(testing::_,
1910                       testing::Property(&gfx::Vector2dF::x,
1911                                         testing::Eq(expected_delta))))
1912      .WillOnce(testing::Return(true));
1913  input_handler_->Animate(time);
1914
1915  VERIFY_AND_RESET_MOCKS();
1916}
1917
1918TEST_F(InputHandlerProxyTest, FlingBoostTerminatedDuringScrollSequence) {
1919  base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10);
1920  base::TimeTicks time = base::TimeTicks() + dt;
1921  base::TimeTicks last_animate_time = time;
1922  WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
1923  WebPoint fling_point = WebPoint(7, 13);
1924  StartFling(
1925      time, blink::WebGestureDeviceTouchscreen, fling_delta, fling_point);
1926
1927  // Now cancel the fling.  The fling cancellation should be deferred to allow
1928  // fling boosting events to arrive.
1929  time += dt;
1930  CancelFling(time);
1931
1932  // The GestureScrollBegin should be swallowed by the fling.
1933  time += dt;
1934  gesture_.timeStampSeconds = InSecondsF(time);
1935  gesture_.type = WebInputEvent::GestureScrollBegin;
1936  EXPECT_CALL(mock_input_handler_,
1937              IsCurrentlyScrollingLayerAt(testing::_, testing::_))
1938      .WillOnce(testing::Return(true));
1939  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1940
1941  VERIFY_AND_RESET_MOCKS();
1942
1943  // Now animate the fling to completion (in this case, the fling should
1944  // terminate because the input handler reports a failed scroll). As the fling
1945  // was cancelled during an active scroll sequence, a synthetic
1946  // GestureScrollBegin should be processed, resuming the scroll.
1947  time += dt;
1948  float expected_delta =
1949      (time - last_animate_time).InSecondsF() * -fling_delta.x;
1950  EXPECT_CALL(mock_input_handler_,
1951              ScrollBy(testing::_,
1952                       testing::Property(&gfx::Vector2dF::x,
1953                                         testing::Eq(expected_delta))))
1954      .WillOnce(testing::Return(false));
1955  EXPECT_CALL(mock_input_handler_, ScrollEnd());
1956  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
1957      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
1958  input_handler_->Animate(time);
1959
1960  VERIFY_AND_RESET_MOCKS();
1961
1962  // Subsequent GestureScrollUpdates after the cancelled, boosted fling should
1963  // cause scrolling as usual.
1964  time += dt;
1965  expected_delta = 7.3f;
1966  gesture_.timeStampSeconds = InSecondsF(time);
1967  gesture_.type = WebInputEvent::GestureScrollUpdate;
1968  gesture_.data.scrollUpdate.deltaX = -expected_delta;
1969  EXPECT_CALL(mock_input_handler_,
1970              ScrollBy(testing::_,
1971                       testing::Property(&gfx::Vector2dF::x,
1972                                         testing::Eq(expected_delta))))
1973      .WillOnce(testing::Return(true));
1974  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1975
1976  VERIFY_AND_RESET_MOCKS();
1977
1978  // GestureScrollEnd should terminate the resumed scroll properly.
1979  time += dt;
1980  gesture_.timeStampSeconds = InSecondsF(time);
1981  gesture_.type = WebInputEvent::GestureScrollEnd;
1982  EXPECT_CALL(mock_input_handler_, ScrollEnd());
1983  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
1984
1985  VERIFY_AND_RESET_MOCKS();
1986}
1987
1988TEST_F(InputHandlerProxyTest, DidReceiveInputEvent) {
1989  testing::StrictMock<
1990      MockInputHandlerProxyClientWithDidReceiveInputEvent> mock_client;
1991  input_handler_.reset(
1992        new content::InputHandlerProxy(&mock_input_handler_, &mock_client));
1993
1994  // Note the type of input event isn't important.
1995  WebMouseWheelEvent wheel;
1996  wheel.type = WebInputEvent::MouseWheel;
1997  wheel.scrollByPage = true;
1998
1999  EXPECT_CALL(mock_client, DidReceiveInputEvent());
2000
2001  input_handler_->HandleInputEvent(wheel);
2002  testing::Mock::VerifyAndClearExpectations(&mock_client);
2003}
2004
2005} // namespace
2006} // namespace content
2007