Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(465)

Side by Side Diff: content/renderer/gpu/input_handler_proxy_unittest.cc

Issue 13844021: Move compositor thread input handling logic into content (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix win component build Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 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/gpu/input_handler_proxy.h"
6
7 #include "base/basictypes.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "content/renderer/gpu/input_handler_proxy_client.h"
10 #include "testing/gmock/include/gmock/gmock.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 #include "third_party/WebKit/Source/Platform/chromium/public/WebFloatPoint.h"
13 #include "third_party/WebKit/Source/Platform/chromium/public/WebFloatSize.h"
14 #include "third_party/WebKit/Source/Platform/chromium/public/WebGestureCurve.h"
15 #include "third_party/WebKit/Source/Platform/chromium/public/WebPoint.h"
16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
17
18 using WebKit::WebActiveWheelFlingParameters;
19 using WebKit::WebFloatPoint;
20 using WebKit::WebFloatSize;
21 using WebKit::WebGestureEvent;
22 using WebKit::WebInputEvent;
23 using WebKit::WebPoint;
24 using WebKit::WebSize;
25
26 namespace {
27
28 class MockInputHandler : public cc::InputHandler {
29 public:
30 MockInputHandler() {}
31 virtual ~MockInputHandler() {}
32
33 MOCK_METHOD0(PinchGestureBegin, void());
34 MOCK_METHOD2(PinchGestureUpdate,
35 void(float magnify_delta, gfx::Point anchor));
36 MOCK_METHOD0(PinchGestureEnd, void());
37
38 MOCK_METHOD0(ScheduleAnimation, void());
39
40 MOCK_METHOD2(ScrollBegin,
41 ScrollStatus(gfx::Point viewport_point,
42 cc::InputHandler::ScrollInputType type));
43 MOCK_METHOD0(FlingScrollBegin, cc::InputHandler::ScrollStatus());
44 MOCK_METHOD2(ScrollBy,
45 bool(gfx::Point viewport_point, gfx::Vector2dF scroll_delta));
46 MOCK_METHOD2(ScrollVerticallyByPage,
47 bool(gfx::Point viewport_point,
48 WebKit::WebScrollbar::ScrollDirection direction));
49 MOCK_METHOD0(ScrollEnd, void());
50
51 MOCK_METHOD1(DidReceiveLastInputEventForVSync, void(base::TimeTicks time));
52
53 virtual void BindToClient(cc::InputHandlerClient* clent) OVERRIDE {}
danakj 2013/05/06 16:33:39 Can we MOCK to make sure we call this correctly?
54
55 virtual void StartPageScaleAnimation(gfx::Vector2d target_offset,
56 bool anchor_point,
57 float page_scale,
58 base::TimeTicks start_time,
59 base::TimeDelta duration) OVERRIDE {}
60
61 virtual void NotifyCurrentFlingVelocity(gfx::Vector2dF velocity) OVERRIDE {}
62
63 virtual bool HaveTouchEventHandlersAt(gfx::Point point) OVERRIDE {
64 return false;
65 }
66
67 virtual void SetRootLayerScrollOffsetDelegate(
68 cc::LayerScrollOffsetDelegate* root_layer_scroll_offset_delegate)
69 OVERRIDE {}
70
71 virtual void OnRootLayerDelegatedScrollOffsetChanged() OVERRIDE {}
72
73 DISALLOW_COPY_AND_ASSIGN(MockInputHandler);
74 };
75
76 // A simple WebGestureCurve implementation that flings at a constant velocity
77 // indefinitely.
78 class FakeWebGestureCurve : public WebKit::WebGestureCurve {
79 public:
80 FakeWebGestureCurve(const WebKit::WebFloatPoint& velocity,
81 const WebKit::WebSize& cumulative_scroll)
82 : velocity_(velocity), cumulative_scroll_(cumulative_scroll) {}
83
84 virtual ~FakeWebGestureCurve() {}
85
86 // Returns false if curve has finished and can no longer be applied.
87 virtual bool apply(double time, WebKit::WebGestureCurveTarget* target) {
88 WebKit::WebSize displacement(velocity_.x * time, velocity_.y * time);
89 WebKit::WebFloatSize increment(
90 displacement.width - cumulative_scroll_.width,
91 displacement.height - cumulative_scroll_.height);
92 cumulative_scroll_ = displacement;
93 // scrollBy() could delete this curve if the animation is over, so don't
94 // touch any member variables after making that call.
95 target->scrollBy(increment);
96 return true;
97 }
98
99 private:
100 WebKit::WebFloatPoint velocity_;
101 WebKit::WebSize cumulative_scroll_;
102
103 DISALLOW_COPY_AND_ASSIGN(FakeWebGestureCurve);
104 };
105
106 class MockInputHandlerProxyClient
107 : public content::InputHandlerProxyClient {
108 public:
109 MockInputHandlerProxyClient() {}
110 virtual ~MockInputHandlerProxyClient() {}
111
112 virtual void WillShutdown() OVERRIDE {}
danakj 2013/05/06 16:33:39 Can we MOCK this as well to verify it's called?
113
114 MOCK_METHOD0(DidHandleInputEvent, void());
115 MOCK_METHOD1(DidNotHandleInputEvent, void(bool send_to_widget));
116
117 MOCK_METHOD1(TransferActiveWheelFlingAnimation,
118 void(const WebActiveWheelFlingParameters&));
119
120 virtual WebKit::WebGestureCurve* CreateFlingAnimationCurve(
121 int deviceSource,
122 const WebFloatPoint& velocity,
123 const WebSize& cumulative_scroll) OVERRIDE {
124 return new FakeWebGestureCurve(velocity, cumulative_scroll);
125 }
126
127 private:
128 DISALLOW_COPY_AND_ASSIGN(MockInputHandlerProxyClient);
129 };
130
131 class InputHandlerProxyTest : public testing::Test {
132 public:
133 InputHandlerProxyTest() : expected_disposition_(DidHandle) {
134 input_handler_.reset(
135 new content::InputHandlerProxy(&mock_input_handler_));
136 input_handler_->SetClient(&mock_client_);
137 }
138
139 ~InputHandlerProxyTest() {
140 input_handler_->SetClient(NULL);
141 input_handler_.reset();
142 }
143
144 // This is defined as a macro because when an expectation is not satisfied the
145 // only output you get
146 // out of gmock is the line number that set the expectation.
147 #define VERIFY_AND_RESET_MOCKS() \
148 do { \
149 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); \
150 testing::Mock::VerifyAndClearExpectations(&mock_client_); \
151 switch (expected_disposition_) { \
152 case DidHandle: \
153 /* If we expect to handle events, we shouldn't get any */ \
154 /* DidNotHandleInputEvent() calls with any parameter. */ \
155 EXPECT_CALL(mock_client_, DidNotHandleInputEvent(::testing::_)) \
156 .Times(0); \
157 EXPECT_CALL(mock_client_, DidHandleInputEvent()); \
158 break; \
159 case DidNotHandle: \
160 /* If we aren't expecting to handle events, we shouldn't call */ \
161 /* DidHandleInputEvent(). */ \
162 EXPECT_CALL(mock_client_, DidHandleInputEvent()).Times(0); \
163 EXPECT_CALL(mock_client_, DidNotHandleInputEvent(false)).Times(0); \
164 EXPECT_CALL(mock_client_, DidNotHandleInputEvent(true)); \
165 break; \
166 case DropEvent: \
167 /* If we're expecting to drop, we shouldn't get any didHandle..() */ \
168 /* or DidNotHandleInputEvent(true) calls. */ \
169 EXPECT_CALL(mock_client_, DidHandleInputEvent()).Times(0); \
170 EXPECT_CALL(mock_client_, DidNotHandleInputEvent(true)).Times(0); \
171 EXPECT_CALL(mock_client_, DidNotHandleInputEvent(false)); \
172 break; \
173 } \
174 } while (false)
175
176 protected:
177 testing::StrictMock<MockInputHandler> mock_input_handler_;
178 scoped_ptr<content::InputHandlerProxy> input_handler_;
179 testing::StrictMock<MockInputHandlerProxyClient> mock_client_;
180 WebGestureEvent gesture_;
181
182 enum ExpectedDisposition {
183 DidHandle,
184 DidNotHandle,
185 DropEvent
186 };
187 ExpectedDisposition expected_disposition_;
188 };
189
190 TEST_F(InputHandlerProxyTest, GestureScrollStarted) {
191 // We shouldn't send any events to the widget for this gesture.
192 expected_disposition_ = DidHandle;
193 VERIFY_AND_RESET_MOCKS();
194
195 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
196 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
197
198 gesture_.type = WebInputEvent::GestureScrollBegin;
199 input_handler_->HandleInputEvent(gesture_);
200
201 // The event should not be marked as handled if scrolling is not possible.
202 expected_disposition_ = DropEvent;
203 VERIFY_AND_RESET_MOCKS();
204
205 gesture_.type = WebInputEvent::GestureScrollUpdate;
206 gesture_.data.scrollUpdate.deltaY =
207 -40; // -Y means scroll down - i.e. in the +Y direction.
208 EXPECT_CALL(mock_input_handler_,
209 ScrollBy(testing::_,
210 testing::Property(&gfx::Vector2dF::y, testing::Gt(0))))
211 .WillOnce(testing::Return(false));
212 input_handler_->HandleInputEvent(gesture_);
213
214 // Mark the event as handled if scroll happens.
215 expected_disposition_ = DidHandle;
216 VERIFY_AND_RESET_MOCKS();
217
218 gesture_.type = WebInputEvent::GestureScrollUpdate;
219 gesture_.data.scrollUpdate.deltaY =
220 -40; // -Y means scroll down - i.e. in the +Y direction.
221 EXPECT_CALL(mock_input_handler_,
222 ScrollBy(testing::_,
223 testing::Property(&gfx::Vector2dF::y, testing::Gt(0))))
224 .WillOnce(testing::Return(true));
225 input_handler_->HandleInputEvent(gesture_);
226
227 VERIFY_AND_RESET_MOCKS();
228
229 gesture_.type = WebInputEvent::GestureScrollEnd;
230 gesture_.data.scrollUpdate.deltaY = 0;
231 EXPECT_CALL(mock_input_handler_, ScrollEnd());
232 input_handler_->HandleInputEvent(gesture_);
233 }
234
235 TEST_F(InputHandlerProxyTest, GestureScrollOnMainThread) {
236 // We should send all events to the widget for this gesture.
237 expected_disposition_ = DidNotHandle;
238 VERIFY_AND_RESET_MOCKS();
239
240 EXPECT_CALL(mock_input_handler_, ScrollBegin(::testing::_, ::testing::_))
241 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread));
242
243 gesture_.type = WebInputEvent::GestureScrollBegin;
244 input_handler_->HandleInputEvent(gesture_);
245
246 VERIFY_AND_RESET_MOCKS();
247
248 gesture_.type = WebInputEvent::GestureScrollUpdate;
249 gesture_.data.scrollUpdate.deltaY = 40;
250 input_handler_->HandleInputEvent(gesture_);
251
252 VERIFY_AND_RESET_MOCKS();
253
254 gesture_.type = WebInputEvent::GestureScrollEnd;
255 gesture_.data.scrollUpdate.deltaY = 0;
256 input_handler_->HandleInputEvent(gesture_);
257 }
258
259 TEST_F(InputHandlerProxyTest, GestureScrollIgnored) {
260 // We shouldn't handle the GestureScrollBegin.
261 // Instead, we should get one DidNotHandleInputEvent(false) call per
262 // HandleInputEvent(), indicating that we could determine that there's nothing
263 // that could scroll or otherwise react to this gesture sequence and thus we
264 // should drop the whole gesture sequence on the floor.
265 expected_disposition_ = DropEvent;
266 VERIFY_AND_RESET_MOCKS();
267
268 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
269 .WillOnce(testing::Return(cc::InputHandler::ScrollIgnored));
270
271 gesture_.type = WebInputEvent::GestureScrollBegin;
272 input_handler_->HandleInputEvent(gesture_);
273 }
274
275 TEST_F(InputHandlerProxyTest, GesturePinch) {
276 // We shouldn't send any events to the widget for this gesture.
277 expected_disposition_ = DidHandle;
278 VERIFY_AND_RESET_MOCKS();
279
280 gesture_.type = WebInputEvent::GesturePinchBegin;
281 EXPECT_CALL(mock_input_handler_, PinchGestureBegin());
282 input_handler_->HandleInputEvent(gesture_);
283
284 VERIFY_AND_RESET_MOCKS();
285
286 gesture_.type = WebInputEvent::GesturePinchUpdate;
287 gesture_.data.pinchUpdate.scale = 1.5;
288 gesture_.x = 7;
289 gesture_.y = 13;
290 EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(1.5, gfx::Point(7, 13)));
291 input_handler_->HandleInputEvent(gesture_);
292
293 VERIFY_AND_RESET_MOCKS();
294
295 gesture_.type = WebInputEvent::GesturePinchUpdate;
296 gesture_.data.pinchUpdate.scale = 0.5;
297 gesture_.x = 9;
298 gesture_.y = 6;
299 EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(.5, gfx::Point(9, 6)));
300 input_handler_->HandleInputEvent(gesture_);
301
302 VERIFY_AND_RESET_MOCKS();
303
304 gesture_.type = WebInputEvent::GesturePinchEnd;
305 EXPECT_CALL(mock_input_handler_, PinchGestureEnd());
306 input_handler_->HandleInputEvent(gesture_);
307 }
308
309 TEST_F(InputHandlerProxyTest, GesturePinchAfterScrollOnMainThread) {
310 // Scrolls will start by being sent to the main thread.
311 expected_disposition_ = DidNotHandle;
312 VERIFY_AND_RESET_MOCKS();
313
314 EXPECT_CALL(mock_input_handler_, ScrollBegin(::testing::_, ::testing::_))
315 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread));
316
317 gesture_.type = WebInputEvent::GestureScrollBegin;
318 input_handler_->HandleInputEvent(gesture_);
319
320 VERIFY_AND_RESET_MOCKS();
321
322 gesture_.type = WebInputEvent::GestureScrollUpdate;
323 gesture_.data.scrollUpdate.deltaY = 40;
324 input_handler_->HandleInputEvent(gesture_);
325
326 // However, after the pinch gesture starts, they should go to the impl
327 // thread.
328 expected_disposition_ = DidHandle;
329 VERIFY_AND_RESET_MOCKS();
330
331 gesture_.type = WebInputEvent::GesturePinchBegin;
332 EXPECT_CALL(mock_input_handler_, PinchGestureBegin());
333 input_handler_->HandleInputEvent(gesture_);
334
335 VERIFY_AND_RESET_MOCKS();
336
337 gesture_.type = WebInputEvent::GesturePinchUpdate;
338 gesture_.data.pinchUpdate.scale = 1.5;
339 gesture_.x = 7;
340 gesture_.y = 13;
341 EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(1.5, gfx::Point(7, 13)));
342 input_handler_->HandleInputEvent(gesture_);
343
344 VERIFY_AND_RESET_MOCKS();
345
346 gesture_.type = WebInputEvent::GestureScrollUpdate;
347 gesture_.data.scrollUpdate.deltaY =
348 -40; // -Y means scroll down - i.e. in the +Y direction.
349 EXPECT_CALL(mock_input_handler_,
350 ScrollBy(testing::_,
351 testing::Property(&gfx::Vector2dF::y, testing::Gt(0))))
352 .WillOnce(testing::Return(true));
353 input_handler_->HandleInputEvent(gesture_);
354
355 VERIFY_AND_RESET_MOCKS();
356
357 gesture_.type = WebInputEvent::GesturePinchUpdate;
358 gesture_.data.pinchUpdate.scale = 0.5;
359 gesture_.x = 9;
360 gesture_.y = 6;
361 EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(.5, gfx::Point(9, 6)));
362 input_handler_->HandleInputEvent(gesture_);
363
364 VERIFY_AND_RESET_MOCKS();
365
366 gesture_.type = WebInputEvent::GesturePinchEnd;
367 EXPECT_CALL(mock_input_handler_, PinchGestureEnd());
368 input_handler_->HandleInputEvent(gesture_);
369
370 // After the pinch gesture ends, they should go to back to the main
371 // thread.
372 expected_disposition_ = DidNotHandle;
373 VERIFY_AND_RESET_MOCKS();
374
375 gesture_.type = WebInputEvent::GestureScrollEnd;
376 gesture_.data.scrollUpdate.deltaY = 0;
377 input_handler_->HandleInputEvent(gesture_);
378 }
379
380 TEST_F(InputHandlerProxyTest, GestureFlingStartedTouchpad) {
381 // We shouldn't send any events to the widget for this gesture.
382 expected_disposition_ = DidHandle;
383 VERIFY_AND_RESET_MOCKS();
384
385 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
386 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
387 EXPECT_CALL(mock_input_handler_, ScrollEnd());
388 EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
389
390 gesture_.type = WebInputEvent::GestureFlingStart;
391 gesture_.data.flingStart.velocityX = 10;
392 gesture_.sourceDevice = WebGestureEvent::Touchpad;
393 input_handler_->HandleInputEvent(gesture_);
394
395 VERIFY_AND_RESET_MOCKS();
396
397 // Verify that a GestureFlingCancel during an animation cancels it.
398 gesture_.type = WebInputEvent::GestureFlingCancel;
399 gesture_.sourceDevice = WebGestureEvent::Touchpad;
400 input_handler_->HandleInputEvent(gesture_);
401 }
402
403 TEST_F(InputHandlerProxyTest, GestureFlingOnMainThreadTouchpad) {
404 // We should send all events to the widget for this gesture.
405 expected_disposition_ = DidNotHandle;
406 VERIFY_AND_RESET_MOCKS();
407
408 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
409 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread));
410
411 gesture_.type = WebInputEvent::GestureFlingStart;
412 gesture_.sourceDevice = WebGestureEvent::Touchpad;
413 input_handler_->HandleInputEvent(gesture_);
414
415 VERIFY_AND_RESET_MOCKS();
416
417 // Even if we didn't start a fling ourselves, we still need to send the cancel
418 // event to the widget.
419 gesture_.type = WebInputEvent::GestureFlingCancel;
420 gesture_.sourceDevice = WebGestureEvent::Touchpad;
421 input_handler_->HandleInputEvent(gesture_);
422 }
423
424 TEST_F(InputHandlerProxyTest, GestureFlingIgnoredTouchpad) {
425 expected_disposition_ = DidNotHandle;
426 VERIFY_AND_RESET_MOCKS();
427
428 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
429 .WillOnce(testing::Return(cc::InputHandler::ScrollIgnored));
430
431 gesture_.type = WebInputEvent::GestureFlingStart;
432 gesture_.sourceDevice = WebGestureEvent::Touchpad;
433 input_handler_->HandleInputEvent(gesture_);
434
435 expected_disposition_ = DropEvent;
436 VERIFY_AND_RESET_MOCKS();
437
438 // Since the previous fling was ignored, we should also be dropping the next
439 // fling_cancel.
440 gesture_.type = WebInputEvent::GestureFlingCancel;
441 gesture_.sourceDevice = WebGestureEvent::Touchpad;
442 input_handler_->HandleInputEvent(gesture_);
443 }
444
445 TEST_F(InputHandlerProxyTest, GestureFlingAnimatesTouchpad) {
446 // We shouldn't send any events to the widget for this gesture.
447 expected_disposition_ = DidHandle;
448 VERIFY_AND_RESET_MOCKS();
449
450 // On the fling start, we should schedule an animation but not actually start
451 // scrolling.
452 gesture_.type = WebInputEvent::GestureFlingStart;
453 WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
454 WebPoint fling_point = WebPoint(7, 13);
455 WebPoint fling_global_point = WebPoint(17, 23);
456 int modifiers = 7;
457 gesture_.data.flingStart.velocityX = fling_delta.x;
458 gesture_.data.flingStart.velocityY = fling_delta.y;
459 gesture_.sourceDevice = WebGestureEvent::Touchpad;
460 gesture_.x = fling_point.x;
461 gesture_.y = fling_point.y;
462 gesture_.globalX = fling_global_point.x;
463 gesture_.globalY = fling_global_point.y;
464 gesture_.modifiers = modifiers;
465 EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
466 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
467 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
468 EXPECT_CALL(mock_input_handler_, ScrollEnd());
469 input_handler_->HandleInputEvent(gesture_);
470
471 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
472 // The first animate call should let us pick up an animation start time, but
473 // we shouldn't actually move anywhere just yet. The first frame after the
474 // fling start will typically include the last scroll from the gesture that
475 // lead to the scroll (either wheel or gesture scroll), so there should be no
476 // visible hitch.
477 EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
478 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
479 .Times(0);
480 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
481 input_handler_->Animate(time);
482
483 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
484
485 // The second call should start scrolling in the -X direction.
486 EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
487 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
488 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
489 EXPECT_CALL(mock_input_handler_,
490 ScrollBy(testing::_,
491 testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))
492 .WillOnce(testing::Return(true));
493 EXPECT_CALL(mock_input_handler_, ScrollEnd());
494 time += base::TimeDelta::FromMilliseconds(100);
495 input_handler_->Animate(time);
496
497 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
498
499 // Let's say on the third call we hit a non-scrollable region. We should abort
500 // the fling and not scroll.
501 // We also should pass the current fling parameters out to the client so the
502 // rest of the fling can be
503 // transferred to the main thread.
504 EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
505 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
506 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread));
507 EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_, testing::_)).Times(0);
508 EXPECT_CALL(mock_input_handler_, ScrollEnd()).Times(0);
509 // Expected wheel fling animation parameters:
510 // *) fling_delta and fling_point should match the original GestureFlingStart
511 // event
512 // *) startTime should be 10 to match the time parameter of the first
513 // Animate() call after the GestureFlingStart
514 // *) cumulativeScroll depends on the curve, but since we've animated in the
515 // -X direction the X value should be < 0
516 EXPECT_CALL(
517 mock_client_,
518 TransferActiveWheelFlingAnimation(testing::AllOf(
519 testing::Field(&WebActiveWheelFlingParameters::delta,
520 testing::Eq(fling_delta)),
521 testing::Field(&WebActiveWheelFlingParameters::point,
522 testing::Eq(fling_point)),
523 testing::Field(&WebActiveWheelFlingParameters::globalPoint,
524 testing::Eq(fling_global_point)),
525 testing::Field(&WebActiveWheelFlingParameters::modifiers,
526 testing::Eq(modifiers)),
527 testing::Field(&WebActiveWheelFlingParameters::startTime,
528 testing::Eq(10)),
529 testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll,
530 testing::Field(&WebSize::width, testing::Gt(0))))));
531 time += base::TimeDelta::FromMilliseconds(100);
532 input_handler_->Animate(time);
533
534 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
535 testing::Mock::VerifyAndClearExpectations(&mock_client_);
536
537 // Since we've aborted the fling, the next animation should be a no-op and
538 // should not result in another
539 // frame being requested.
540 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()).Times(0);
541 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
542 .Times(0);
543 time += base::TimeDelta::FromMilliseconds(100);
544 input_handler_->Animate(time);
545
546 // Since we've transferred the fling to the main thread, we need to pass the
547 // next GestureFlingCancel to the main
548 // thread as well.
549 EXPECT_CALL(mock_client_, DidNotHandleInputEvent(true));
550 gesture_.type = WebInputEvent::GestureFlingCancel;
551 input_handler_->HandleInputEvent(gesture_);
552 }
553
554 TEST_F(InputHandlerProxyTest, GestureFlingTransferResetsTouchpad) {
555 // We shouldn't send any events to the widget for this gesture.
556 expected_disposition_ = DidHandle;
557 VERIFY_AND_RESET_MOCKS();
558
559 // Start a gesture fling in the -X direction with zero Y movement.
560 gesture_.type = WebInputEvent::GestureFlingStart;
561 WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
562 WebPoint fling_point = WebPoint(7, 13);
563 WebPoint fling_global_point = WebPoint(17, 23);
564 int modifiers = 1;
565 gesture_.data.flingStart.velocityX = fling_delta.x;
566 gesture_.data.flingStart.velocityY = fling_delta.y;
567 gesture_.sourceDevice = WebGestureEvent::Touchpad;
568 gesture_.x = fling_point.x;
569 gesture_.y = fling_point.y;
570 gesture_.globalX = fling_global_point.x;
571 gesture_.globalY = fling_global_point.y;
572 gesture_.modifiers = modifiers;
573 EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
574 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
575 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
576 EXPECT_CALL(mock_input_handler_, ScrollEnd());
577 input_handler_->HandleInputEvent(gesture_);
578
579 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
580
581 // Start the fling animation at time 10. This shouldn't actually scroll, just
582 // establish a start time.
583 EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
584 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
585 .Times(0);
586 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
587 input_handler_->Animate(time);
588
589 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
590
591 // The second call should start scrolling in the -X direction.
592 EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
593 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
594 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
595 EXPECT_CALL(mock_input_handler_,
596 ScrollBy(testing::_,
597 testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))
598 .WillOnce(testing::Return(true));
599 EXPECT_CALL(mock_input_handler_, ScrollEnd());
600 time += base::TimeDelta::FromMilliseconds(100);
601 input_handler_->Animate(time);
602
603 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
604
605 // Let's say on the third call we hit a non-scrollable region. We should abort
606 // the fling and not scroll.
607 // We also should pass the current fling parameters out to the client so the
608 // rest of the fling can be
609 // transferred to the main thread.
610 EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
611 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
612 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread));
613 EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_, testing::_)).Times(0);
614 EXPECT_CALL(mock_input_handler_, ScrollEnd()).Times(0);
615
616 // Expected wheel fling animation parameters:
617 // *) fling_delta and fling_point should match the original GestureFlingStart
618 // event
619 // *) startTime should be 10 to match the time parameter of the first
620 // Animate() call after the GestureFlingStart
621 // *) cumulativeScroll depends on the curve, but since we've animated in the
622 // -X direction the X value should be < 0
623 EXPECT_CALL(
624 mock_client_,
625 TransferActiveWheelFlingAnimation(testing::AllOf(
626 testing::Field(&WebActiveWheelFlingParameters::delta,
627 testing::Eq(fling_delta)),
628 testing::Field(&WebActiveWheelFlingParameters::point,
629 testing::Eq(fling_point)),
630 testing::Field(&WebActiveWheelFlingParameters::globalPoint,
631 testing::Eq(fling_global_point)),
632 testing::Field(&WebActiveWheelFlingParameters::modifiers,
633 testing::Eq(modifiers)),
634 testing::Field(&WebActiveWheelFlingParameters::startTime,
635 testing::Eq(10)),
636 testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll,
637 testing::Field(&WebSize::width, testing::Gt(0))))));
638 time += base::TimeDelta::FromMilliseconds(100);
639 input_handler_->Animate(time);
640
641 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
642 testing::Mock::VerifyAndClearExpectations(&mock_client_);
643
644 // Since we've aborted the fling, the next animation should be a no-op and
645 // should not result in another
646 // frame being requested.
647 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()).Times(0);
648 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
649 .Times(0);
650 time += base::TimeDelta::FromMilliseconds(100);
651 input_handler_->Animate(time);
652
653 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
654
655 // Since we've transferred the fling to the main thread, we need to pass the
656 // next GestureFlingCancel to the main
657 // thread as well.
658 EXPECT_CALL(mock_client_, DidNotHandleInputEvent(true));
659 gesture_.type = WebInputEvent::GestureFlingCancel;
660 input_handler_->HandleInputEvent(gesture_);
661
662 VERIFY_AND_RESET_MOCKS();
663 input_handler_->MainThreadHasStoppedFlinging();
664
665 // Start a second gesture fling, this time in the +Y direction with no X.
666 gesture_.type = WebInputEvent::GestureFlingStart;
667 fling_delta = WebFloatPoint(0, -1000);
668 fling_point = WebPoint(95, 87);
669 fling_global_point = WebPoint(32, 71);
670 modifiers = 2;
671 gesture_.data.flingStart.velocityX = fling_delta.x;
672 gesture_.data.flingStart.velocityY = fling_delta.y;
673 gesture_.sourceDevice = WebGestureEvent::Touchpad;
674 gesture_.x = fling_point.x;
675 gesture_.y = fling_point.y;
676 gesture_.globalX = fling_global_point.x;
677 gesture_.globalY = fling_global_point.y;
678 gesture_.modifiers = modifiers;
679 EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
680 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
681 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
682 EXPECT_CALL(mock_input_handler_, ScrollEnd());
683 input_handler_->HandleInputEvent(gesture_);
684
685 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
686
687 // Start the second fling animation at time 30.
688 EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
689 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
690 .Times(0);
691 time = base::TimeTicks() + base::TimeDelta::FromSeconds(30);
692 input_handler_->Animate(time);
693
694 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
695
696 // Tick the second fling once normally.
697 EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
698 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
699 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
700 EXPECT_CALL(mock_input_handler_,
701 ScrollBy(testing::_,
702 testing::Property(&gfx::Vector2dF::y, testing::Gt(0))))
703 .WillOnce(testing::Return(true));
704 EXPECT_CALL(mock_input_handler_, ScrollEnd());
705 time += base::TimeDelta::FromMilliseconds(100);
706 input_handler_->Animate(time);
707
708 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
709
710 // Then abort the second fling.
711 EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
712 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
713 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread));
714 EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_, testing::_)).Times(0);
715 EXPECT_CALL(mock_input_handler_, ScrollEnd()).Times(0);
716
717 // We should get parameters from the second fling, nothing from the first
718 // fling should "leak".
719 EXPECT_CALL(
720 mock_client_,
721 TransferActiveWheelFlingAnimation(testing::AllOf(
722 testing::Field(&WebActiveWheelFlingParameters::delta,
723 testing::Eq(fling_delta)),
724 testing::Field(&WebActiveWheelFlingParameters::point,
725 testing::Eq(fling_point)),
726 testing::Field(&WebActiveWheelFlingParameters::globalPoint,
727 testing::Eq(fling_global_point)),
728 testing::Field(&WebActiveWheelFlingParameters::modifiers,
729 testing::Eq(modifiers)),
730 testing::Field(&WebActiveWheelFlingParameters::startTime,
731 testing::Eq(30)),
732 testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll,
733 testing::Field(&WebSize::height, testing::Lt(0))))));
734 time += base::TimeDelta::FromMilliseconds(100);
735 input_handler_->Animate(time);
736 }
737
738 TEST_F(InputHandlerProxyTest, GestureFlingStartedTouchscreen) {
739 // We shouldn't send any events to the widget for this gesture.
740 expected_disposition_ = DidHandle;
741 VERIFY_AND_RESET_MOCKS();
742
743 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
744 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
745 EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
746
747 gesture_.type = WebInputEvent::GestureFlingStart;
748 gesture_.data.flingStart.velocityX = 10;
749 gesture_.sourceDevice = WebGestureEvent::Touchscreen;
750 input_handler_->HandleInputEvent(gesture_);
751
752 VERIFY_AND_RESET_MOCKS();
753
754 EXPECT_CALL(mock_input_handler_, ScrollEnd());
755
756 // Verify that a GestureFlingCancel during an animation cancels it.
757 gesture_.type = WebInputEvent::GestureFlingCancel;
758 gesture_.sourceDevice = WebGestureEvent::Touchscreen;
759 input_handler_->HandleInputEvent(gesture_);
760 }
761
762 TEST_F(InputHandlerProxyTest, GestureFlingOnMainThreadTouchscreen) {
763 // We should send all events to the widget for this gesture.
764 expected_disposition_ = DidNotHandle;
765 VERIFY_AND_RESET_MOCKS();
766
767 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
768 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread));
769
770 gesture_.type = WebInputEvent::GestureFlingStart;
771 gesture_.sourceDevice = WebGestureEvent::Touchscreen;
772 input_handler_->HandleInputEvent(gesture_);
773
774 VERIFY_AND_RESET_MOCKS();
775
776 // Even if we didn't start a fling ourselves, we still need to send the cancel
777 // event to the widget.
778 gesture_.type = WebInputEvent::GestureFlingCancel;
779 gesture_.sourceDevice = WebGestureEvent::Touchscreen;
780 input_handler_->HandleInputEvent(gesture_);
781 }
782
783 TEST_F(InputHandlerProxyTest, GestureFlingIgnoredTouchscreen) {
784 expected_disposition_ = DropEvent;
785 VERIFY_AND_RESET_MOCKS();
786
787 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
788 .WillOnce(testing::Return(cc::InputHandler::ScrollIgnored));
789
790 gesture_.type = WebInputEvent::GestureFlingStart;
791 gesture_.sourceDevice = WebGestureEvent::Touchscreen;
792 input_handler_->HandleInputEvent(gesture_);
793
794 VERIFY_AND_RESET_MOCKS();
795
796 // Even if we didn't start a fling ourselves, we still need to send the cancel
797 // event to the widget.
798 gesture_.type = WebInputEvent::GestureFlingCancel;
799 gesture_.sourceDevice = WebGestureEvent::Touchscreen;
800 input_handler_->HandleInputEvent(gesture_);
801 }
802
803 TEST_F(InputHandlerProxyTest, GestureFlingAnimatesTouchscreen) {
804 // We shouldn't send any events to the widget for this gesture.
805 expected_disposition_ = DidHandle;
806 VERIFY_AND_RESET_MOCKS();
807
808 // On the fling start, we should schedule an animation but not actually start
809 // scrolling.
810 gesture_.type = WebInputEvent::GestureFlingStart;
811 WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
812 WebPoint fling_point = WebPoint(7, 13);
813 WebPoint fling_global_point = WebPoint(17, 23);
814 int modifiers = 7;
815 gesture_.data.flingStart.velocityX = fling_delta.x;
816 gesture_.data.flingStart.velocityY = fling_delta.y;
817 gesture_.sourceDevice = WebGestureEvent::Touchscreen;
818 gesture_.x = fling_point.x;
819 gesture_.y = fling_point.y;
820 gesture_.globalX = fling_global_point.x;
821 gesture_.globalY = fling_global_point.y;
822 gesture_.modifiers = modifiers;
823 EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
824 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
825 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
826 input_handler_->HandleInputEvent(gesture_);
827
828 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
829 // The first animate call should let us pick up an animation start time, but
830 // we shouldn't actually move anywhere just yet. The first frame after the
831 // fling start will typically include the last scroll from the gesture that
832 // lead to the scroll (either wheel or gesture scroll), so there should be no
833 // visible hitch.
834 EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
835 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
836 input_handler_->Animate(time);
837
838 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
839
840 // The second call should start scrolling in the -X direction.
841 EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
842 EXPECT_CALL(mock_input_handler_,
843 ScrollBy(testing::_,
844 testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))
845 .WillOnce(testing::Return(true));
846 time += base::TimeDelta::FromMilliseconds(100);
847 input_handler_->Animate(time);
848
849 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
850
851 EXPECT_CALL(mock_client_, DidHandleInputEvent());
852 EXPECT_CALL(mock_input_handler_, ScrollEnd());
853 gesture_.type = WebInputEvent::GestureFlingCancel;
854 input_handler_->HandleInputEvent(gesture_);
855 }
856
857 TEST_F(InputHandlerProxyTest,
858 GestureScrollOnImplThreadFlagClearedAfterFling) {
859 // We shouldn't send any events to the widget for this gesture.
860 expected_disposition_ = DidHandle;
861 VERIFY_AND_RESET_MOCKS();
862
863 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
864 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
865
866 gesture_.type = WebInputEvent::GestureScrollBegin;
867 input_handler_->HandleInputEvent(gesture_);
868
869 // After sending a GestureScrollBegin, the member variable
870 // |gesture_scroll_on_impl_thread_| should be true.
871 EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
872
873 expected_disposition_ = DidHandle;
874 VERIFY_AND_RESET_MOCKS();
875
876 // On the fling start, we should schedule an animation but not actually start
877 // scrolling.
878 gesture_.type = WebInputEvent::GestureFlingStart;
879 WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
880 WebPoint fling_point = WebPoint(7, 13);
881 WebPoint fling_global_point = WebPoint(17, 23);
882 int modifiers = 7;
883 gesture_.data.flingStart.velocityX = fling_delta.x;
884 gesture_.data.flingStart.velocityY = fling_delta.y;
885 gesture_.sourceDevice = WebGestureEvent::Touchscreen;
886 gesture_.x = fling_point.x;
887 gesture_.y = fling_point.y;
888 gesture_.globalX = fling_global_point.x;
889 gesture_.globalY = fling_global_point.y;
890 gesture_.modifiers = modifiers;
891 EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
892 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
893 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
894 input_handler_->HandleInputEvent(gesture_);
895
896 // |gesture_scroll_on_impl_thread_| should still be true after
897 // a GestureFlingStart is sent.
898 EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
899
900 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
901 // The first animate call should let us pick up an animation start time, but
902 // we shouldn't actually move anywhere just yet. The first frame after the
903 // fling start will typically include the last scroll from the gesture that
904 // lead to the scroll (either wheel or gesture scroll), so there should be no
905 // visible hitch.
906 EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
907 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
908 input_handler_->Animate(time);
909
910 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
911
912 // The second call should start scrolling in the -X direction.
913 EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
914 EXPECT_CALL(mock_input_handler_,
915 ScrollBy(testing::_,
916 testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))
917 .WillOnce(testing::Return(true));
918 time += base::TimeDelta::FromMilliseconds(100);
919 input_handler_->Animate(time);
920
921 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
922
923 EXPECT_CALL(mock_client_, DidHandleInputEvent());
924 EXPECT_CALL(mock_input_handler_, ScrollEnd());
925 gesture_.type = WebInputEvent::GestureFlingCancel;
926 input_handler_->HandleInputEvent(gesture_);
927
928 // |gesture_scroll_on_impl_thread_| should be false once
929 // the fling has finished (note no GestureScrollEnd has been sent).
930 EXPECT_TRUE(!input_handler_->gesture_scroll_on_impl_thread_for_testing());
931 }
932
933 TEST_F(InputHandlerProxyTest, LastInputEventForVSync) {
934 expected_disposition_ = DropEvent;
935 VERIFY_AND_RESET_MOCKS();
936
937 gesture_.type = WebInputEvent::GestureFlingCancel;
938 gesture_.timeStampSeconds = 1234;
939 base::TimeTicks time =
940 base::TimeTicks() +
941 base::TimeDelta::FromSeconds(gesture_.timeStampSeconds);
942 gesture_.modifiers |= WebInputEvent::IsLastInputEventForCurrentVSync;
943 EXPECT_CALL(mock_input_handler_, DidReceiveLastInputEventForVSync(time));
944 input_handler_->HandleInputEvent(gesture_);
945 }
946
947 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698