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

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

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

Powered by Google App Engine
This is Rietveld 408576698