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/renderer/input/input_handler_proxy_client.h"
     11 #include "testing/gmock/include/gmock/gmock.h"
     12 #include "testing/gtest/include/gtest/gtest.h"
     13 #include "third_party/WebKit/public/platform/WebFloatPoint.h"
     14 #include "third_party/WebKit/public/platform/WebFloatSize.h"
     15 #include "third_party/WebKit/public/platform/WebGestureCurve.h"
     16 #include "third_party/WebKit/public/platform/WebPoint.h"
     17 #include "third_party/WebKit/public/web/WebInputEvent.h"
     18 #include "ui/events/latency_info.h"
     19 
     20 using blink::WebActiveWheelFlingParameters;
     21 using blink::WebFloatPoint;
     22 using blink::WebFloatSize;
     23 using blink::WebGestureEvent;
     24 using blink::WebInputEvent;
     25 using blink::WebMouseWheelEvent;
     26 using blink::WebPoint;
     27 using blink::WebSize;
     28 using blink::WebTouchEvent;
     29 using blink::WebTouchPoint;
     30 
     31 namespace content {
     32 namespace {
     33 
     34 class MockInputHandler : public cc::InputHandler {
     35  public:
     36   MockInputHandler() {}
     37   virtual ~MockInputHandler() {}
     38 
     39   MOCK_METHOD0(PinchGestureBegin, void());
     40   MOCK_METHOD2(PinchGestureUpdate,
     41                void(float magnify_delta, gfx::Point anchor));
     42   MOCK_METHOD0(PinchGestureEnd, void());
     43 
     44   MOCK_METHOD0(ScheduleAnimation, void());
     45 
     46   MOCK_METHOD2(ScrollBegin,
     47                ScrollStatus(gfx::Point viewport_point,
     48                             cc::InputHandler::ScrollInputType type));
     49   MOCK_METHOD2(ScrollBy,
     50                bool(gfx::Point viewport_point, gfx::Vector2dF scroll_delta));
     51   MOCK_METHOD2(ScrollVerticallyByPage,
     52                bool(gfx::Point viewport_point,
     53                     cc::ScrollDirection direction));
     54   MOCK_METHOD0(ScrollEnd, void());
     55   MOCK_METHOD0(FlingScrollBegin, cc::InputHandler::ScrollStatus());
     56 
     57   virtual scoped_ptr<cc::SwapPromiseMonitor>
     58     CreateLatencyInfoSwapPromiseMonitor(ui::LatencyInfo* latency) OVERRIDE {
     59       return scoped_ptr<cc::SwapPromiseMonitor>();
     60   }
     61 
     62   virtual void BindToClient(cc::InputHandlerClient* client) OVERRIDE {}
     63 
     64   virtual void StartPageScaleAnimation(gfx::Vector2d target_offset,
     65                                        bool anchor_point,
     66                                        float page_scale,
     67                                        base::TimeDelta duration) OVERRIDE {}
     68 
     69   virtual void NotifyCurrentFlingVelocity(gfx::Vector2dF velocity) OVERRIDE {}
     70   virtual void MouseMoveAt(gfx::Point mouse_position) OVERRIDE {}
     71 
     72   MOCK_METHOD1(HaveTouchEventHandlersAt,
     73                bool(gfx::Point point));
     74 
     75   virtual void SetRootLayerScrollOffsetDelegate(
     76       cc::LayerScrollOffsetDelegate* root_layer_scroll_offset_delegate)
     77       OVERRIDE {}
     78 
     79   virtual void OnRootLayerDelegatedScrollOffsetChanged() OVERRIDE {}
     80 
     81   DISALLOW_COPY_AND_ASSIGN(MockInputHandler);
     82 };
     83 
     84 // A simple WebGestureCurve implementation that flings at a constant velocity
     85 // indefinitely.
     86 class FakeWebGestureCurve : public blink::WebGestureCurve {
     87  public:
     88   FakeWebGestureCurve(const blink::WebFloatPoint& velocity,
     89                       const blink::WebSize& cumulative_scroll)
     90       : velocity_(velocity), cumulative_scroll_(cumulative_scroll) {}
     91 
     92   virtual ~FakeWebGestureCurve() {}
     93 
     94   // Returns false if curve has finished and can no longer be applied.
     95   virtual bool apply(double time, blink::WebGestureCurveTarget* target) {
     96     blink::WebSize displacement(velocity_.x * time, velocity_.y * time);
     97     blink::WebFloatSize increment(
     98         displacement.width - cumulative_scroll_.width,
     99         displacement.height - cumulative_scroll_.height);
    100     cumulative_scroll_ = displacement;
    101     // scrollBy() could delete this curve if the animation is over, so don't
    102     // touch any member variables after making that call.
    103     target->scrollBy(increment);
    104     return true;
    105   }
    106 
    107  private:
    108   blink::WebFloatPoint velocity_;
    109   blink::WebSize cumulative_scroll_;
    110 
    111   DISALLOW_COPY_AND_ASSIGN(FakeWebGestureCurve);
    112 };
    113 
    114 class MockInputHandlerProxyClient
    115     : public content::InputHandlerProxyClient {
    116  public:
    117   MockInputHandlerProxyClient() {}
    118   virtual ~MockInputHandlerProxyClient() {}
    119 
    120   virtual void WillShutdown() OVERRIDE {}
    121 
    122   MOCK_METHOD1(TransferActiveWheelFlingAnimation,
    123                void(const WebActiveWheelFlingParameters&));
    124 
    125   virtual blink::WebGestureCurve* CreateFlingAnimationCurve(
    126       int deviceSource,
    127       const WebFloatPoint& velocity,
    128       const WebSize& cumulative_scroll) OVERRIDE {
    129     return new FakeWebGestureCurve(velocity, cumulative_scroll);
    130   }
    131 
    132   virtual void DidOverscroll(const cc::DidOverscrollParams& params) {}
    133 
    134  private:
    135   DISALLOW_COPY_AND_ASSIGN(MockInputHandlerProxyClient);
    136 };
    137 
    138 class InputHandlerProxyTest : public testing::Test {
    139  public:
    140   InputHandlerProxyTest()
    141       : expected_disposition_(InputHandlerProxy::DID_HANDLE) {
    142     input_handler_.reset(
    143         new content::InputHandlerProxy(&mock_input_handler_));
    144     input_handler_->SetClient(&mock_client_);
    145   }
    146 
    147   ~InputHandlerProxyTest() {
    148     input_handler_.reset();
    149   }
    150 
    151 // This is defined as a macro because when an expectation is not satisfied the
    152 // only output you get
    153 // out of gmock is the line number that set the expectation.
    154 #define VERIFY_AND_RESET_MOCKS()                                              \
    155   do {                                                                        \
    156     testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);          \
    157     testing::Mock::VerifyAndClearExpectations(&mock_client_);                 \
    158   } while (false)
    159 
    160  protected:
    161   testing::StrictMock<MockInputHandler> mock_input_handler_;
    162   scoped_ptr<content::InputHandlerProxy> input_handler_;
    163   testing::StrictMock<MockInputHandlerProxyClient> mock_client_;
    164   WebGestureEvent gesture_;
    165 
    166   InputHandlerProxy::EventDisposition expected_disposition_;
    167 };
    168 
    169 TEST_F(InputHandlerProxyTest, MouseWheelByPageMainThread) {
    170   expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
    171   WebMouseWheelEvent wheel;
    172   wheel.type = WebInputEvent::MouseWheel;
    173   wheel.scrollByPage = true;
    174 
    175   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(wheel));
    176   testing::Mock::VerifyAndClearExpectations(&mock_client_);
    177 }
    178 
    179 TEST_F(InputHandlerProxyTest, GestureScrollStarted) {
    180   // We shouldn't send any events to the widget for this gesture.
    181   expected_disposition_ = InputHandlerProxy::DID_HANDLE;
    182   VERIFY_AND_RESET_MOCKS();
    183 
    184   EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
    185       .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
    186 
    187   gesture_.type = WebInputEvent::GestureScrollBegin;
    188   EXPECT_EQ(expected_disposition_,input_handler_->HandleInputEvent(gesture_));
    189 
    190   // The event should not be marked as handled if scrolling is not possible.
    191   expected_disposition_ = InputHandlerProxy::DROP_EVENT;
    192   VERIFY_AND_RESET_MOCKS();
    193 
    194   gesture_.type = WebInputEvent::GestureScrollUpdate;
    195   gesture_.data.scrollUpdate.deltaY =
    196       -40;  // -Y means scroll down - i.e. in the +Y direction.
    197   EXPECT_CALL(mock_input_handler_,
    198               ScrollBy(testing::_,
    199                        testing::Property(&gfx::Vector2dF::y, testing::Gt(0))))
    200       .WillOnce(testing::Return(false));
    201   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    202 
    203   // Mark the event as handled if scroll happens.
    204   expected_disposition_ = InputHandlerProxy::DID_HANDLE;
    205   VERIFY_AND_RESET_MOCKS();
    206 
    207   gesture_.type = WebInputEvent::GestureScrollUpdate;
    208   gesture_.data.scrollUpdate.deltaY =
    209       -40;  // -Y means scroll down - i.e. in the +Y direction.
    210   EXPECT_CALL(mock_input_handler_,
    211               ScrollBy(testing::_,
    212                        testing::Property(&gfx::Vector2dF::y, testing::Gt(0))))
    213       .WillOnce(testing::Return(true));
    214   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    215 
    216   VERIFY_AND_RESET_MOCKS();
    217 
    218   gesture_.type = WebInputEvent::GestureScrollEnd;
    219   gesture_.data.scrollUpdate.deltaY = 0;
    220   EXPECT_CALL(mock_input_handler_, ScrollEnd());
    221   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    222 }
    223 
    224 TEST_F(InputHandlerProxyTest, GestureScrollOnMainThread) {
    225   // We should send all events to the widget for this gesture.
    226   expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
    227   VERIFY_AND_RESET_MOCKS();
    228 
    229   EXPECT_CALL(mock_input_handler_, ScrollBegin(::testing::_, ::testing::_))
    230       .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread));
    231 
    232   gesture_.type = WebInputEvent::GestureScrollBegin;
    233   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    234 
    235   VERIFY_AND_RESET_MOCKS();
    236 
    237   gesture_.type = WebInputEvent::GestureScrollUpdate;
    238   gesture_.data.scrollUpdate.deltaY = 40;
    239   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    240 
    241   VERIFY_AND_RESET_MOCKS();
    242 
    243   gesture_.type = WebInputEvent::GestureScrollEnd;
    244   gesture_.data.scrollUpdate.deltaY = 0;
    245   EXPECT_CALL(mock_input_handler_, ScrollEnd()).WillOnce(testing::Return());
    246   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    247 }
    248 
    249 TEST_F(InputHandlerProxyTest, GestureScrollIgnored) {
    250   // We shouldn't handle the GestureScrollBegin.
    251   // Instead, we should get a DROP_EVENT result, indicating
    252   // that we could determine that there's nothing that could scroll or otherwise
    253   // react to this gesture sequence and thus we should drop the whole gesture
    254   // sequence on the floor, except for the ScrollEnd.
    255   expected_disposition_ = InputHandlerProxy::DROP_EVENT;
    256   VERIFY_AND_RESET_MOCKS();
    257 
    258   EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
    259       .WillOnce(testing::Return(cc::InputHandler::ScrollIgnored));
    260 
    261   gesture_.type = WebInputEvent::GestureScrollBegin;
    262   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    263 
    264   expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
    265   gesture_.type = WebInputEvent::GestureScrollEnd;
    266   EXPECT_CALL(mock_input_handler_, ScrollEnd()).WillOnce(testing::Return());
    267   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    268 }
    269 
    270 TEST_F(InputHandlerProxyTest, GesturePinch) {
    271   // We shouldn't send any events to the widget for this gesture.
    272   expected_disposition_ = InputHandlerProxy::DID_HANDLE;
    273   VERIFY_AND_RESET_MOCKS();
    274 
    275   gesture_.type = WebInputEvent::GesturePinchBegin;
    276   EXPECT_CALL(mock_input_handler_, PinchGestureBegin());
    277   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    278 
    279   VERIFY_AND_RESET_MOCKS();
    280 
    281   gesture_.type = WebInputEvent::GesturePinchUpdate;
    282   gesture_.data.pinchUpdate.scale = 1.5;
    283   gesture_.x = 7;
    284   gesture_.y = 13;
    285   EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(1.5, gfx::Point(7, 13)));
    286   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    287 
    288   VERIFY_AND_RESET_MOCKS();
    289 
    290   gesture_.type = WebInputEvent::GesturePinchUpdate;
    291   gesture_.data.pinchUpdate.scale = 0.5;
    292   gesture_.x = 9;
    293   gesture_.y = 6;
    294   EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(.5, gfx::Point(9, 6)));
    295   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    296 
    297   VERIFY_AND_RESET_MOCKS();
    298 
    299   gesture_.type = WebInputEvent::GesturePinchEnd;
    300   EXPECT_CALL(mock_input_handler_, PinchGestureEnd());
    301   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    302 }
    303 
    304 TEST_F(InputHandlerProxyTest, GesturePinchAfterScrollOnMainThread) {
    305   // Scrolls will start by being sent to the main thread.
    306   expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
    307   VERIFY_AND_RESET_MOCKS();
    308 
    309   EXPECT_CALL(mock_input_handler_, ScrollBegin(::testing::_, ::testing::_))
    310       .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread));
    311 
    312   gesture_.type = WebInputEvent::GestureScrollBegin;
    313   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    314 
    315   VERIFY_AND_RESET_MOCKS();
    316 
    317   gesture_.type = WebInputEvent::GestureScrollUpdate;
    318   gesture_.data.scrollUpdate.deltaY = 40;
    319   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    320 
    321   // However, after the pinch gesture starts, they should go to the impl
    322   // thread.
    323   expected_disposition_ = InputHandlerProxy::DID_HANDLE;
    324   VERIFY_AND_RESET_MOCKS();
    325 
    326   gesture_.type = WebInputEvent::GesturePinchBegin;
    327   EXPECT_CALL(mock_input_handler_, PinchGestureBegin());
    328   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    329 
    330   VERIFY_AND_RESET_MOCKS();
    331 
    332   gesture_.type = WebInputEvent::GesturePinchUpdate;
    333   gesture_.data.pinchUpdate.scale = 1.5;
    334   gesture_.x = 7;
    335   gesture_.y = 13;
    336   EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(1.5, gfx::Point(7, 13)));
    337   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    338 
    339   VERIFY_AND_RESET_MOCKS();
    340 
    341   gesture_.type = WebInputEvent::GestureScrollUpdate;
    342   gesture_.data.scrollUpdate.deltaY =
    343       -40;  // -Y means scroll down - i.e. in the +Y direction.
    344   EXPECT_CALL(mock_input_handler_,
    345               ScrollBy(testing::_,
    346                        testing::Property(&gfx::Vector2dF::y, testing::Gt(0))))
    347       .WillOnce(testing::Return(true));
    348   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    349 
    350   VERIFY_AND_RESET_MOCKS();
    351 
    352   gesture_.type = WebInputEvent::GesturePinchUpdate;
    353   gesture_.data.pinchUpdate.scale = 0.5;
    354   gesture_.x = 9;
    355   gesture_.y = 6;
    356   EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(.5, gfx::Point(9, 6)));
    357   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    358 
    359   VERIFY_AND_RESET_MOCKS();
    360 
    361   gesture_.type = WebInputEvent::GesturePinchEnd;
    362   EXPECT_CALL(mock_input_handler_, PinchGestureEnd());
    363   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    364 
    365   // After the pinch gesture ends, they should go to back to the main
    366   // thread.
    367   expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
    368   VERIFY_AND_RESET_MOCKS();
    369 
    370   gesture_.type = WebInputEvent::GestureScrollEnd;
    371   gesture_.data.scrollUpdate.deltaY = 0;
    372   EXPECT_CALL(mock_input_handler_, ScrollEnd())
    373       .WillOnce(testing::Return());
    374   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    375 }
    376 
    377 TEST_F(InputHandlerProxyTest, GestureFlingStartedTouchpad) {
    378   // We shouldn't send any events to the widget for this gesture.
    379   expected_disposition_ = InputHandlerProxy::DID_HANDLE;
    380   VERIFY_AND_RESET_MOCKS();
    381 
    382   EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
    383       .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
    384   EXPECT_CALL(mock_input_handler_, ScrollEnd());
    385   EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
    386 
    387   gesture_.type = WebInputEvent::GestureFlingStart;
    388   gesture_.data.flingStart.velocityX = 10;
    389   gesture_.sourceDevice = WebGestureEvent::Touchpad;
    390   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    391 
    392   VERIFY_AND_RESET_MOCKS();
    393 
    394   // Verify that a GestureFlingCancel during an animation cancels it.
    395   gesture_.type = WebInputEvent::GestureFlingCancel;
    396   gesture_.sourceDevice = WebGestureEvent::Touchpad;
    397   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    398 }
    399 
    400 TEST_F(InputHandlerProxyTest, GestureFlingOnMainThreadTouchpad) {
    401   // We should send all events to the widget for this gesture.
    402   expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
    403   VERIFY_AND_RESET_MOCKS();
    404 
    405   EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
    406       .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread));
    407 
    408   gesture_.type = WebInputEvent::GestureFlingStart;
    409   gesture_.sourceDevice = WebGestureEvent::Touchpad;
    410   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    411 
    412   // Since we returned ScrollStatusOnMainThread from scrollBegin, ensure the
    413   // input handler knows it's scrolling off the impl thread
    414   ASSERT_FALSE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
    415 
    416   VERIFY_AND_RESET_MOCKS();
    417 
    418   // Even if we didn't start a fling ourselves, we still need to send the cancel
    419   // event to the widget.
    420   gesture_.type = WebInputEvent::GestureFlingCancel;
    421   gesture_.sourceDevice = WebGestureEvent::Touchpad;
    422   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    423 }
    424 
    425 TEST_F(InputHandlerProxyTest, GestureFlingIgnoredTouchpad) {
    426   expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
    427   VERIFY_AND_RESET_MOCKS();
    428 
    429   EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
    430       .WillOnce(testing::Return(cc::InputHandler::ScrollIgnored));
    431 
    432   gesture_.type = WebInputEvent::GestureFlingStart;
    433   gesture_.sourceDevice = WebGestureEvent::Touchpad;
    434   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    435 
    436   expected_disposition_ = InputHandlerProxy::DROP_EVENT;
    437   VERIFY_AND_RESET_MOCKS();
    438 
    439   // Since the previous fling was ignored, we should also be dropping the next
    440   // fling_cancel.
    441   gesture_.type = WebInputEvent::GestureFlingCancel;
    442   gesture_.sourceDevice = WebGestureEvent::Touchpad;
    443   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    444 }
    445 
    446 TEST_F(InputHandlerProxyTest, GestureFlingAnimatesTouchpad) {
    447   // We shouldn't send any events to the widget for this gesture.
    448   expected_disposition_ = InputHandlerProxy::DID_HANDLE;
    449   VERIFY_AND_RESET_MOCKS();
    450 
    451   // On the fling start, we should schedule an animation but not actually start
    452   // scrolling.
    453   gesture_.type = WebInputEvent::GestureFlingStart;
    454   WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
    455   WebPoint fling_point = WebPoint(7, 13);
    456   WebPoint fling_global_point = WebPoint(17, 23);
    457   int modifiers = 7;
    458   gesture_.data.flingStart.velocityX = fling_delta.x;
    459   gesture_.data.flingStart.velocityY = fling_delta.y;
    460   gesture_.sourceDevice = WebGestureEvent::Touchpad;
    461   gesture_.x = fling_point.x;
    462   gesture_.y = fling_point.y;
    463   gesture_.globalX = fling_global_point.x;
    464   gesture_.globalY = fling_global_point.y;
    465   gesture_.modifiers = modifiers;
    466   EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
    467   EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
    468       .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
    469   EXPECT_CALL(mock_input_handler_, ScrollEnd());
    470   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    471 
    472   testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
    473   // The first animate call should let us pick up an animation start time, but
    474   // we shouldn't actually move anywhere just yet. The first frame after the
    475   // fling start will typically include the last scroll from the gesture that
    476   // lead to the scroll (either wheel or gesture scroll), so there should be no
    477   // visible hitch.
    478   EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
    479   EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
    480       .Times(0);
    481   base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
    482   input_handler_->Animate(time);
    483 
    484   testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
    485 
    486   // The second call should start scrolling in the -X direction.
    487   EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
    488   EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
    489       .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
    490   EXPECT_CALL(mock_input_handler_,
    491               ScrollBy(testing::_,
    492                        testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))
    493       .WillOnce(testing::Return(true));
    494   EXPECT_CALL(mock_input_handler_, ScrollEnd());
    495   time += base::TimeDelta::FromMilliseconds(100);
    496   input_handler_->Animate(time);
    497 
    498   testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
    499 
    500   // Let's say on the third call we hit a non-scrollable region. We should abort
    501   // the fling and not scroll.
    502   // We also should pass the current fling parameters out to the client so the
    503   // rest of the fling can be
    504   // transferred to the main thread.
    505   EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
    506   EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
    507       .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread));
    508   EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_, testing::_)).Times(0);
    509   EXPECT_CALL(mock_input_handler_, ScrollEnd()).Times(0);
    510   // Expected wheel fling animation parameters:
    511   // *) fling_delta and fling_point should match the original GestureFlingStart
    512   // event
    513   // *) startTime should be 10 to match the time parameter of the first
    514   // Animate() call after the GestureFlingStart
    515   // *) cumulativeScroll depends on the curve, but since we've animated in the
    516   // -X direction the X value should be < 0
    517   EXPECT_CALL(
    518       mock_client_,
    519       TransferActiveWheelFlingAnimation(testing::AllOf(
    520           testing::Field(&WebActiveWheelFlingParameters::delta,
    521                          testing::Eq(fling_delta)),
    522           testing::Field(&WebActiveWheelFlingParameters::point,
    523                          testing::Eq(fling_point)),
    524           testing::Field(&WebActiveWheelFlingParameters::globalPoint,
    525                          testing::Eq(fling_global_point)),
    526           testing::Field(&WebActiveWheelFlingParameters::modifiers,
    527                          testing::Eq(modifiers)),
    528           testing::Field(&WebActiveWheelFlingParameters::startTime,
    529                          testing::Eq(10)),
    530           testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll,
    531                          testing::Field(&WebSize::width, testing::Gt(0))))));
    532   time += base::TimeDelta::FromMilliseconds(100);
    533   input_handler_->Animate(time);
    534 
    535   testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
    536   testing::Mock::VerifyAndClearExpectations(&mock_client_);
    537 
    538   // Since we've aborted the fling, the next animation should be a no-op and
    539   // should not result in another
    540   // frame being requested.
    541   EXPECT_CALL(mock_input_handler_, ScheduleAnimation()).Times(0);
    542   EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
    543       .Times(0);
    544   time += base::TimeDelta::FromMilliseconds(100);
    545   input_handler_->Animate(time);
    546 
    547   // Since we've transferred the fling to the main thread, we need to pass the
    548   // next GestureFlingCancel to the main
    549   // thread as well.
    550   expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
    551   gesture_.type = WebInputEvent::GestureFlingCancel;
    552   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    553 }
    554 
    555 TEST_F(InputHandlerProxyTest, GestureFlingTransferResetsTouchpad) {
    556   // We shouldn't send any events to the widget for this gesture.
    557   expected_disposition_ = InputHandlerProxy::DID_HANDLE;
    558   VERIFY_AND_RESET_MOCKS();
    559 
    560   // Start a gesture fling in the -X direction with zero Y movement.
    561   gesture_.type = WebInputEvent::GestureFlingStart;
    562   WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
    563   WebPoint fling_point = WebPoint(7, 13);
    564   WebPoint fling_global_point = WebPoint(17, 23);
    565   int modifiers = 1;
    566   gesture_.data.flingStart.velocityX = fling_delta.x;
    567   gesture_.data.flingStart.velocityY = fling_delta.y;
    568   gesture_.sourceDevice = WebGestureEvent::Touchpad;
    569   gesture_.x = fling_point.x;
    570   gesture_.y = fling_point.y;
    571   gesture_.globalX = fling_global_point.x;
    572   gesture_.globalY = fling_global_point.y;
    573   gesture_.modifiers = modifiers;
    574   EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
    575   EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
    576       .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
    577   EXPECT_CALL(mock_input_handler_, ScrollEnd());
    578   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    579 
    580   testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
    581 
    582   // Start the fling animation at time 10. This shouldn't actually scroll, just
    583   // establish a start time.
    584   EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
    585   EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
    586       .Times(0);
    587   base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
    588   input_handler_->Animate(time);
    589 
    590   testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
    591 
    592   // The second call should start scrolling in the -X direction.
    593   EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
    594   EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
    595       .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
    596   EXPECT_CALL(mock_input_handler_,
    597               ScrollBy(testing::_,
    598                        testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))
    599       .WillOnce(testing::Return(true));
    600   EXPECT_CALL(mock_input_handler_, ScrollEnd());
    601   time += base::TimeDelta::FromMilliseconds(100);
    602   input_handler_->Animate(time);
    603 
    604   testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
    605 
    606   // Let's say on the third call we hit a non-scrollable region. We should abort
    607   // the fling and not scroll.
    608   // We also should pass the current fling parameters out to the client so the
    609   // rest of the fling can be
    610   // transferred to the main thread.
    611   EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
    612   EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
    613       .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread));
    614   EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_, testing::_)).Times(0);
    615   EXPECT_CALL(mock_input_handler_, ScrollEnd()).Times(0);
    616 
    617   // Expected wheel fling animation parameters:
    618   // *) fling_delta and fling_point should match the original GestureFlingStart
    619   // event
    620   // *) startTime should be 10 to match the time parameter of the first
    621   // Animate() call after the GestureFlingStart
    622   // *) cumulativeScroll depends on the curve, but since we've animated in the
    623   // -X direction the X value should be < 0
    624   EXPECT_CALL(
    625       mock_client_,
    626       TransferActiveWheelFlingAnimation(testing::AllOf(
    627           testing::Field(&WebActiveWheelFlingParameters::delta,
    628                          testing::Eq(fling_delta)),
    629           testing::Field(&WebActiveWheelFlingParameters::point,
    630                          testing::Eq(fling_point)),
    631           testing::Field(&WebActiveWheelFlingParameters::globalPoint,
    632                          testing::Eq(fling_global_point)),
    633           testing::Field(&WebActiveWheelFlingParameters::modifiers,
    634                          testing::Eq(modifiers)),
    635           testing::Field(&WebActiveWheelFlingParameters::startTime,
    636                          testing::Eq(10)),
    637           testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll,
    638                          testing::Field(&WebSize::width, testing::Gt(0))))));
    639   time += base::TimeDelta::FromMilliseconds(100);
    640   input_handler_->Animate(time);
    641 
    642   testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
    643   testing::Mock::VerifyAndClearExpectations(&mock_client_);
    644 
    645   // Since we've aborted the fling, the next animation should be a no-op and
    646   // should not result in another
    647   // frame being requested.
    648   EXPECT_CALL(mock_input_handler_, ScheduleAnimation()).Times(0);
    649   EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
    650       .Times(0);
    651   time += base::TimeDelta::FromMilliseconds(100);
    652   input_handler_->Animate(time);
    653 
    654   testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
    655 
    656   // Since we've transferred the fling to the main thread, we need to pass the
    657   // next GestureFlingCancel to the main
    658   // thread as well.
    659   expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
    660   gesture_.type = WebInputEvent::GestureFlingCancel;
    661   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    662 
    663   VERIFY_AND_RESET_MOCKS();
    664   input_handler_->MainThreadHasStoppedFlinging();
    665 
    666   // Start a second gesture fling, this time in the +Y direction with no X.
    667   gesture_.type = WebInputEvent::GestureFlingStart;
    668   fling_delta = WebFloatPoint(0, -1000);
    669   fling_point = WebPoint(95, 87);
    670   fling_global_point = WebPoint(32, 71);
    671   modifiers = 2;
    672   gesture_.data.flingStart.velocityX = fling_delta.x;
    673   gesture_.data.flingStart.velocityY = fling_delta.y;
    674   gesture_.sourceDevice = WebGestureEvent::Touchpad;
    675   gesture_.x = fling_point.x;
    676   gesture_.y = fling_point.y;
    677   gesture_.globalX = fling_global_point.x;
    678   gesture_.globalY = fling_global_point.y;
    679   gesture_.modifiers = modifiers;
    680   EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
    681   EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
    682       .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
    683   EXPECT_CALL(mock_input_handler_, ScrollEnd());
    684   expected_disposition_ = InputHandlerProxy::DID_HANDLE;
    685   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    686 
    687   testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
    688 
    689   // Start the second fling animation at time 30.
    690   EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
    691   EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
    692       .Times(0);
    693   time = base::TimeTicks() + base::TimeDelta::FromSeconds(30);
    694   input_handler_->Animate(time);
    695 
    696   testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
    697 
    698   // Tick the second fling once normally.
    699   EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
    700   EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
    701       .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
    702   EXPECT_CALL(mock_input_handler_,
    703               ScrollBy(testing::_,
    704                        testing::Property(&gfx::Vector2dF::y, testing::Gt(0))))
    705       .WillOnce(testing::Return(true));
    706   EXPECT_CALL(mock_input_handler_, ScrollEnd());
    707   time += base::TimeDelta::FromMilliseconds(100);
    708   input_handler_->Animate(time);
    709 
    710   testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
    711 
    712   // Then abort the second fling.
    713   EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
    714   EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
    715       .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread));
    716   EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_, testing::_)).Times(0);
    717   EXPECT_CALL(mock_input_handler_, ScrollEnd()).Times(0);
    718 
    719   // We should get parameters from the second fling, nothing from the first
    720   // fling should "leak".
    721   EXPECT_CALL(
    722       mock_client_,
    723       TransferActiveWheelFlingAnimation(testing::AllOf(
    724           testing::Field(&WebActiveWheelFlingParameters::delta,
    725                          testing::Eq(fling_delta)),
    726           testing::Field(&WebActiveWheelFlingParameters::point,
    727                          testing::Eq(fling_point)),
    728           testing::Field(&WebActiveWheelFlingParameters::globalPoint,
    729                          testing::Eq(fling_global_point)),
    730           testing::Field(&WebActiveWheelFlingParameters::modifiers,
    731                          testing::Eq(modifiers)),
    732           testing::Field(&WebActiveWheelFlingParameters::startTime,
    733                          testing::Eq(30)),
    734           testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll,
    735                          testing::Field(&WebSize::height, testing::Lt(0))))));
    736   time += base::TimeDelta::FromMilliseconds(100);
    737   input_handler_->Animate(time);
    738 }
    739 
    740 TEST_F(InputHandlerProxyTest, GestureFlingStartedTouchscreen) {
    741   // We shouldn't send any events to the widget for this gesture.
    742   expected_disposition_ = InputHandlerProxy::DID_HANDLE;
    743   VERIFY_AND_RESET_MOCKS();
    744 
    745   EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
    746       .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
    747   gesture_.type = WebInputEvent::GestureScrollBegin;
    748   gesture_.sourceDevice = WebGestureEvent::Touchscreen;
    749   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    750 
    751   VERIFY_AND_RESET_MOCKS();
    752 
    753   EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
    754       .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
    755   EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
    756 
    757   gesture_.type = WebInputEvent::GestureFlingStart;
    758   gesture_.data.flingStart.velocityX = 10;
    759   gesture_.sourceDevice = WebGestureEvent::Touchscreen;
    760   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    761 
    762   VERIFY_AND_RESET_MOCKS();
    763 
    764   EXPECT_CALL(mock_input_handler_, ScrollEnd());
    765 
    766   // Verify that a GestureFlingCancel during an animation cancels it.
    767   gesture_.type = WebInputEvent::GestureFlingCancel;
    768   gesture_.sourceDevice = WebGestureEvent::Touchscreen;
    769   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    770 }
    771 
    772 TEST_F(InputHandlerProxyTest, GestureFlingOnMainThreadTouchscreen) {
    773   // We should send all events to the widget for this gesture.
    774   expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
    775   VERIFY_AND_RESET_MOCKS();
    776 
    777   EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
    778       .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread));
    779 
    780   gesture_.type = WebInputEvent::GestureScrollBegin;
    781   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    782 
    783   VERIFY_AND_RESET_MOCKS();
    784 
    785   EXPECT_CALL(mock_input_handler_, FlingScrollBegin()).Times(0);
    786 
    787   gesture_.type = WebInputEvent::GestureFlingStart;
    788   gesture_.sourceDevice = WebGestureEvent::Touchscreen;
    789   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    790 
    791   VERIFY_AND_RESET_MOCKS();
    792 
    793   // Even if we didn't start a fling ourselves, we still need to send the cancel
    794   // event to the widget.
    795   gesture_.type = WebInputEvent::GestureFlingCancel;
    796   gesture_.sourceDevice = WebGestureEvent::Touchscreen;
    797   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    798 }
    799 
    800 TEST_F(InputHandlerProxyTest, GestureFlingIgnoredTouchscreen) {
    801   expected_disposition_ = InputHandlerProxy::DID_HANDLE;
    802   VERIFY_AND_RESET_MOCKS();
    803 
    804   EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
    805       .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
    806 
    807   gesture_.type = WebInputEvent::GestureScrollBegin;
    808   gesture_.sourceDevice = WebGestureEvent::Touchscreen;
    809   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    810 
    811   expected_disposition_ = InputHandlerProxy::DROP_EVENT;
    812   VERIFY_AND_RESET_MOCKS();
    813 
    814   EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
    815       .WillOnce(testing::Return(cc::InputHandler::ScrollIgnored));
    816 
    817   gesture_.type = WebInputEvent::GestureFlingStart;
    818   gesture_.sourceDevice = WebGestureEvent::Touchscreen;
    819   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    820 
    821   VERIFY_AND_RESET_MOCKS();
    822 
    823   // Even if we didn't start a fling ourselves, we still need to send the cancel
    824   // event to the widget.
    825   gesture_.type = WebInputEvent::GestureFlingCancel;
    826   gesture_.sourceDevice = WebGestureEvent::Touchscreen;
    827   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    828 }
    829 
    830 TEST_F(InputHandlerProxyTest, GestureFlingAnimatesTouchscreen) {
    831   // We shouldn't send any events to the widget for this gesture.
    832   expected_disposition_ = InputHandlerProxy::DID_HANDLE;
    833   VERIFY_AND_RESET_MOCKS();
    834 
    835   EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
    836       .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
    837 
    838   gesture_.type = WebInputEvent::GestureScrollBegin;
    839   gesture_.sourceDevice = WebGestureEvent::Touchscreen;
    840   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    841 
    842   VERIFY_AND_RESET_MOCKS();
    843 
    844   // On the fling start, we should schedule an animation but not actually start
    845   // scrolling.
    846   gesture_.type = WebInputEvent::GestureFlingStart;
    847   WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
    848   WebPoint fling_point = WebPoint(7, 13);
    849   WebPoint fling_global_point = WebPoint(17, 23);
    850   int modifiers = 7;
    851   gesture_.data.flingStart.velocityX = fling_delta.x;
    852   gesture_.data.flingStart.velocityY = fling_delta.y;
    853   gesture_.sourceDevice = WebGestureEvent::Touchscreen;
    854   gesture_.x = fling_point.x;
    855   gesture_.y = fling_point.y;
    856   gesture_.globalX = fling_global_point.x;
    857   gesture_.globalY = fling_global_point.y;
    858   gesture_.modifiers = modifiers;
    859   EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
    860   EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
    861       .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
    862   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    863 
    864   testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
    865   // The first animate call should let us pick up an animation start time, but
    866   // we shouldn't actually move anywhere just yet. The first frame after the
    867   // fling start will typically include the last scroll from the gesture that
    868   // lead to the scroll (either wheel or gesture scroll), so there should be no
    869   // visible hitch.
    870   EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
    871   base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
    872   input_handler_->Animate(time);
    873 
    874   testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
    875 
    876   // The second call should start scrolling in the -X direction.
    877   EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
    878   EXPECT_CALL(mock_input_handler_,
    879               ScrollBy(testing::_,
    880                        testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))
    881       .WillOnce(testing::Return(true));
    882   time += base::TimeDelta::FromMilliseconds(100);
    883   input_handler_->Animate(time);
    884 
    885   testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
    886 
    887   EXPECT_CALL(mock_input_handler_, ScrollEnd());
    888   gesture_.type = WebInputEvent::GestureFlingCancel;
    889   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    890 }
    891 
    892 TEST_F(InputHandlerProxyTest, GestureFlingWithValidTimestamp) {
    893   // We shouldn't send any events to the widget for this gesture.
    894   expected_disposition_ = InputHandlerProxy::DID_HANDLE;
    895   VERIFY_AND_RESET_MOCKS();
    896 
    897   EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
    898       .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
    899 
    900   gesture_.type = WebInputEvent::GestureScrollBegin;
    901   gesture_.sourceDevice = WebGestureEvent::Touchscreen;
    902   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    903 
    904   VERIFY_AND_RESET_MOCKS();
    905 
    906   // On the fling start, we should schedule an animation but not actually start
    907   // scrolling.
    908   base::TimeDelta startTimeOffset = base::TimeDelta::FromMilliseconds(10);
    909   gesture_.type = WebInputEvent::GestureFlingStart;
    910   WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
    911   WebPoint fling_point = WebPoint(7, 13);
    912   WebPoint fling_global_point = WebPoint(17, 23);
    913   int modifiers = 7;
    914   gesture_.timeStampSeconds = startTimeOffset.InSecondsF();
    915   gesture_.data.flingStart.velocityX = fling_delta.x;
    916   gesture_.data.flingStart.velocityY = fling_delta.y;
    917   gesture_.sourceDevice = WebGestureEvent::Touchscreen;
    918   gesture_.x = fling_point.x;
    919   gesture_.y = fling_point.y;
    920   gesture_.globalX = fling_global_point.x;
    921   gesture_.globalY = fling_global_point.y;
    922   gesture_.modifiers = modifiers;
    923   EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
    924   EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
    925       .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
    926   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    927 
    928   testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
    929   // With a valid time stamp, the first animate call should skip start time
    930   // initialization and immediately begin scroll update production. This reduces
    931   // the likelihood of a hitch between the scroll preceding the fling and
    932   // the first scroll generated by the fling.
    933   // Scrolling should start in the -X direction.
    934   EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
    935   EXPECT_CALL(mock_input_handler_,
    936               ScrollBy(testing::_,
    937                        testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))
    938       .WillOnce(testing::Return(true));
    939   base::TimeTicks time = base::TimeTicks() + 2 * startTimeOffset;
    940   input_handler_->Animate(time);
    941 
    942   testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
    943 
    944   EXPECT_CALL(mock_input_handler_, ScrollEnd());
    945   gesture_.type = WebInputEvent::GestureFlingCancel;
    946   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    947 }
    948 
    949 TEST_F(InputHandlerProxyTest,
    950        GestureScrollOnImplThreadFlagClearedAfterFling) {
    951   // We shouldn't send any events to the widget for this gesture.
    952   expected_disposition_ = InputHandlerProxy::DID_HANDLE;
    953   VERIFY_AND_RESET_MOCKS();
    954 
    955   EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
    956       .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
    957 
    958   gesture_.type = WebInputEvent::GestureScrollBegin;
    959   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    960 
    961   // After sending a GestureScrollBegin, the member variable
    962   // |gesture_scroll_on_impl_thread_| should be true.
    963   EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
    964 
    965   expected_disposition_ = InputHandlerProxy::DID_HANDLE;
    966   VERIFY_AND_RESET_MOCKS();
    967 
    968   // On the fling start, we should schedule an animation but not actually start
    969   // scrolling.
    970   gesture_.type = WebInputEvent::GestureFlingStart;
    971   WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
    972   WebPoint fling_point = WebPoint(7, 13);
    973   WebPoint fling_global_point = WebPoint(17, 23);
    974   int modifiers = 7;
    975   gesture_.data.flingStart.velocityX = fling_delta.x;
    976   gesture_.data.flingStart.velocityY = fling_delta.y;
    977   gesture_.sourceDevice = WebGestureEvent::Touchscreen;
    978   gesture_.x = fling_point.x;
    979   gesture_.y = fling_point.y;
    980   gesture_.globalX = fling_global_point.x;
    981   gesture_.globalY = fling_global_point.y;
    982   gesture_.modifiers = modifiers;
    983   EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
    984   EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
    985       .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
    986   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
    987 
    988   // |gesture_scroll_on_impl_thread_| should still be true after
    989   // a GestureFlingStart is sent.
    990   EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
    991 
    992   testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
    993   // The first animate call should let us pick up an animation start time, but
    994   // we shouldn't actually move anywhere just yet. The first frame after the
    995   // fling start will typically include the last scroll from the gesture that
    996   // lead to the scroll (either wheel or gesture scroll), so there should be no
    997   // visible hitch.
    998   EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
    999   base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
   1000   input_handler_->Animate(time);
   1001 
   1002   testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
   1003 
   1004   // The second call should start scrolling in the -X direction.
   1005   EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
   1006   EXPECT_CALL(mock_input_handler_,
   1007               ScrollBy(testing::_,
   1008                        testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))
   1009       .WillOnce(testing::Return(true));
   1010   time += base::TimeDelta::FromMilliseconds(100);
   1011   input_handler_->Animate(time);
   1012 
   1013   testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
   1014 
   1015   EXPECT_CALL(mock_input_handler_, ScrollEnd());
   1016   gesture_.type = WebInputEvent::GestureFlingCancel;
   1017   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
   1018 
   1019   // |gesture_scroll_on_impl_thread_| should be false once
   1020   // the fling has finished (note no GestureScrollEnd has been sent).
   1021   EXPECT_TRUE(!input_handler_->gesture_scroll_on_impl_thread_for_testing());
   1022 }
   1023 
   1024 TEST_F(InputHandlerProxyTest, GestureFlingStopsAtContentEdge) {
   1025   // We shouldn't send any events to the widget for this gesture.
   1026   expected_disposition_ = InputHandlerProxy::DID_HANDLE;
   1027   VERIFY_AND_RESET_MOCKS();
   1028 
   1029   // On the fling start, we should schedule an animation but not actually start
   1030   // scrolling.
   1031   gesture_.type = WebInputEvent::GestureFlingStart;
   1032   WebFloatPoint fling_delta = WebFloatPoint(1000, 1000);
   1033   gesture_.data.flingStart.velocityX = fling_delta.x;
   1034   gesture_.data.flingStart.velocityY = fling_delta.y;
   1035   EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
   1036   EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
   1037       .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
   1038   EXPECT_CALL(mock_input_handler_, ScrollEnd());
   1039   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
   1040   testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
   1041 
   1042   // The first animate doesn't cause any scrolling.
   1043   EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
   1044   base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
   1045   input_handler_->Animate(time);
   1046   testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
   1047 
   1048   // The second animate starts scrolling in the positive X and Y directions.
   1049   EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
   1050   EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
   1051       .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
   1052   EXPECT_CALL(mock_input_handler_,
   1053               ScrollBy(testing::_,
   1054                        testing::Property(&gfx::Vector2dF::y, testing::Lt(0))))
   1055       .WillOnce(testing::Return(true));
   1056   EXPECT_CALL(mock_input_handler_, ScrollEnd());
   1057   time += base::TimeDelta::FromMilliseconds(100);
   1058   input_handler_->Animate(time);
   1059   testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
   1060 
   1061   // Simulate hitting the bottom content edge.
   1062   cc::DidOverscrollParams overscroll_params;
   1063   overscroll_params.accumulated_overscroll = gfx::Vector2dF(0, 100);
   1064   overscroll_params.current_fling_velocity = gfx::Vector2dF(0, 10);
   1065   input_handler_->DidOverscroll(overscroll_params);
   1066 
   1067   // The next call to animate will no longer scroll vertically.
   1068   EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
   1069   EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
   1070       .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
   1071   EXPECT_CALL(mock_input_handler_,
   1072               ScrollBy(testing::_,
   1073                        testing::Property(&gfx::Vector2dF::y, testing::Eq(0))))
   1074       .WillOnce(testing::Return(true));
   1075   EXPECT_CALL(mock_input_handler_, ScrollEnd());
   1076   time += base::TimeDelta::FromMilliseconds(100);
   1077   input_handler_->Animate(time);
   1078   testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
   1079 }
   1080 
   1081 TEST_F(InputHandlerProxyTest, MultiTouchPointHitTestNegative) {
   1082   // None of the three touch points fall in the touch region. So the event
   1083   // should be dropped.
   1084   expected_disposition_ = InputHandlerProxy::DROP_EVENT;
   1085   VERIFY_AND_RESET_MOCKS();
   1086 
   1087   EXPECT_CALL(mock_input_handler_,
   1088               HaveTouchEventHandlersAt(
   1089                   testing::Property(&gfx::Point::x, testing::Gt(0))))
   1090       .WillOnce(testing::Return(false));
   1091   EXPECT_CALL(mock_input_handler_,
   1092               HaveTouchEventHandlersAt(
   1093                   testing::Property(&gfx::Point::x, testing::Lt(0))))
   1094       .WillOnce(testing::Return(false));
   1095 
   1096   WebTouchEvent touch;
   1097   touch.type = WebInputEvent::TouchStart;
   1098 
   1099   touch.touchesLength = 3;
   1100   touch.touches[0].state = WebTouchPoint::StateStationary;
   1101   touch.touches[0].screenPosition = WebPoint();
   1102   touch.touches[0].position = WebPoint();
   1103 
   1104   touch.touches[1].state = WebTouchPoint::StatePressed;
   1105   touch.touches[1].screenPosition = WebPoint(10, 10);
   1106   touch.touches[1].position = WebPoint(10, 10);
   1107 
   1108   touch.touches[2].state = WebTouchPoint::StatePressed;
   1109   touch.touches[2].screenPosition = WebPoint(-10, 10);
   1110   touch.touches[2].position = WebPoint(-10, 10);
   1111 
   1112   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(touch));
   1113 }
   1114 
   1115 TEST_F(InputHandlerProxyTest, MultiTouchPointHitTestPositive) {
   1116   // One of the touch points is on a touch-region. So the event should be sent
   1117   // to the main thread.
   1118   expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE;
   1119   VERIFY_AND_RESET_MOCKS();
   1120 
   1121   EXPECT_CALL(mock_input_handler_,
   1122               HaveTouchEventHandlersAt(
   1123                   testing::Property(&gfx::Point::x, testing::Eq(0))))
   1124       .WillOnce(testing::Return(false));
   1125   EXPECT_CALL(mock_input_handler_,
   1126               HaveTouchEventHandlersAt(
   1127                   testing::Property(&gfx::Point::x, testing::Gt(0))))
   1128       .WillOnce(testing::Return(true));
   1129   // Since the second touch point hits a touch-region, there should be no
   1130   // hit-testing for the third touch point.
   1131 
   1132   WebTouchEvent touch;
   1133   touch.type = WebInputEvent::TouchStart;
   1134 
   1135   touch.touchesLength = 3;
   1136   touch.touches[0].state = WebTouchPoint::StatePressed;
   1137   touch.touches[0].screenPosition = WebPoint();
   1138   touch.touches[0].position = WebPoint();
   1139 
   1140   touch.touches[1].state = WebTouchPoint::StatePressed;
   1141   touch.touches[1].screenPosition = WebPoint(10, 10);
   1142   touch.touches[1].position = WebPoint(10, 10);
   1143 
   1144   touch.touches[2].state = WebTouchPoint::StatePressed;
   1145   touch.touches[2].screenPosition = WebPoint(-10, 10);
   1146   touch.touches[2].position = WebPoint(-10, 10);
   1147 
   1148   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(touch));
   1149 }
   1150 
   1151 } // namespace
   1152 } // namespace content
   1153