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