Home | History | Annotate | Download | only in input
      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 
     21 using blink::WebActiveWheelFlingParameters;
     22 using blink::WebFloatPoint;
     23 using blink::WebFloatSize;
     24 using blink::WebGestureDevice;
     25 using blink::WebGestureEvent;
     26 using blink::WebInputEvent;
     27 using blink::WebKeyboardEvent;
     28 using blink::WebMouseWheelEvent;
     29 using blink::WebPoint;
     30 using blink::WebSize;
     31 using blink::WebTouchEvent;
     32 using blink::WebTouchPoint;
     33 
     34 namespace content {
     35 namespace {
     36 
     37 double InSecondsF(const base::TimeTicks& time) {
     38   return (time - base::TimeTicks()).InSecondsF();
     39 }
     40 
     41 WebGestureEvent CreateFling(base::TimeTicks timestamp,
     42                             WebGestureDevice source_device,
     43                             WebFloatPoint velocity,
     44                             WebPoint point,
     45                             WebPoint global_point,
     46                             int modifiers) {
     47   WebGestureEvent fling;
     48   fling.type = WebInputEvent::GestureFlingStart;
     49   fling.sourceDevice = source_device;
     50   fling.timeStampSeconds = (timestamp - base::TimeTicks()).InSecondsF();
     51   fling.data.flingStart.velocityX = velocity.x;
     52   fling.data.flingStart.velocityY = velocity.y;
     53   fling.x = point.x;
     54   fling.y = point.y;
     55   fling.globalX = global_point.x;
     56   fling.globalY = global_point.y;
     57   fling.modifiers = modifiers;
     58   return fling;
     59 }
     60 
     61 WebGestureEvent CreateFling(WebGestureDevice source_device,
     62                             WebFloatPoint velocity,
     63                             WebPoint point,
     64                             WebPoint global_point,
     65                             int modifiers) {
     66   return CreateFling(base::TimeTicks(),
     67                      source_device,
     68                      velocity,
     69                      point,
     70                      global_point,
     71                      modifiers);
     72 }
     73 
     74 class 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.
    127 class 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 
    155 class 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 
    183 class 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 
    195 WebTouchPoint 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 
    204 class 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 
    271 TEST_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 
    281 TEST_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 
    291 TEST_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 
    336 TEST_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 
    361 TEST_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 
    382 TEST_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 
    416 TEST_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 
    489 TEST_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 
    512 TEST_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 
    537 TEST_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 
    558 TEST_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 
    665 TEST_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 
    842 TEST_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 
    874 TEST_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 
    902 TEST_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 
    932 TEST_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 
    991 TEST_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 
   1045 TEST_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 
   1108 TEST_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 
   1179 TEST_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 
   1248 TEST_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 
   1325 TEST_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 
   1421 TEST_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 
   1446 TEST_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 
   1473 TEST_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 
   1525 TEST_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 
   1589 TEST_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 
   1724 TEST_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 
   1754 TEST_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 
   1791 TEST_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 
   1833 TEST_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 
   1878 TEST_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 
   1918 TEST_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 
   1988 TEST_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