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

Side by Side Diff: content/renderer/input/input_scroll_elasticity_controller_unittest.cc

Issue 1415953004: Move content/renderer input handling for web input events to ui (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase. Created 5 years, 1 month 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
OLDNEW
(Empty)
1 // Copyright 2014 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 "cc/input/input_handler.h"
6 #include "content/renderer/input/input_scroll_elasticity_controller.h"
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "third_party/WebKit/public/web/WebInputEvent.h"
9
10 namespace content {
11 namespace {
12
13 enum Phase {
14 PhaseNone = blink::WebMouseWheelEvent::PhaseNone,
15 PhaseBegan = blink::WebMouseWheelEvent::PhaseBegan,
16 PhaseStationary = blink::WebMouseWheelEvent::PhaseStationary,
17 PhaseChanged = blink::WebMouseWheelEvent::PhaseChanged,
18 PhaseEnded = blink::WebMouseWheelEvent::PhaseEnded,
19 PhaseCancelled = blink::WebMouseWheelEvent::PhaseCancelled,
20 PhaseMayBegin = blink::WebMouseWheelEvent::PhaseMayBegin,
21 };
22
23 class MockScrollElasticityHelper : public cc::ScrollElasticityHelper {
24 public:
25 MockScrollElasticityHelper()
26 : is_user_scrollable_(true),
27 set_stretch_amount_count_(0),
28 request_animate_count_(0) {}
29 ~MockScrollElasticityHelper() override {}
30
31 // cc::ScrollElasticityHelper implementation:
32 bool IsUserScrollable() const override { return is_user_scrollable_; }
33 gfx::Vector2dF StretchAmount() const override { return stretch_amount_; }
34 void SetStretchAmount(const gfx::Vector2dF& stretch_amount) override {
35 set_stretch_amount_count_ += 1;
36 stretch_amount_ = stretch_amount;
37 }
38 gfx::ScrollOffset ScrollOffset() const override { return scroll_offset_; }
39 gfx::ScrollOffset MaxScrollOffset() const override {
40 return max_scroll_offset_;
41 }
42 void ScrollBy(const gfx::Vector2dF& delta) override {
43 scroll_offset_ += gfx::ScrollOffset(delta);
44 }
45 void RequestAnimate() override { request_animate_count_ += 1; }
46
47 // Counters for number of times functions were called.
48 int request_animate_count() const { return request_animate_count_; }
49 int set_stretch_amount_count() const { return set_stretch_amount_count_; }
50
51 void SetScrollOffsetAndMaxScrollOffset(
52 const gfx::ScrollOffset& scroll_offset,
53 const gfx::ScrollOffset& max_scroll_offset) {
54 scroll_offset_ = scroll_offset;
55 max_scroll_offset_ = max_scroll_offset;
56 }
57 void SetUserScrollable(bool is_user_scrollable) {
58 is_user_scrollable_ = is_user_scrollable;
59 }
60
61 private:
62 bool is_user_scrollable_;
63 gfx::Vector2dF stretch_amount_;
64 int set_stretch_amount_count_;
65 int request_animate_count_;
66
67 gfx::ScrollOffset scroll_offset_;
68 gfx::ScrollOffset max_scroll_offset_;
69 };
70
71 class ScrollElasticityControllerTest : public testing::Test {
72 public:
73 ScrollElasticityControllerTest()
74 : controller_(&helper_),
75 input_event_count_(0),
76 current_time_(base::TimeTicks::FromInternalValue(100000000ull)) {}
77 ~ScrollElasticityControllerTest() override {}
78
79 void SendMouseWheelEvent(
80 Phase phase,
81 Phase momentum_phase,
82 const gfx::Vector2dF& event_delta = gfx::Vector2dF(),
83 const gfx::Vector2dF& overscroll_delta = gfx::Vector2dF()) {
84 blink::WebMouseWheelEvent event;
85 event.phase = static_cast<blink::WebMouseWheelEvent::Phase>(phase);
86 event.momentumPhase =
87 static_cast<blink::WebMouseWheelEvent::Phase>(momentum_phase);
88 event.deltaX = -event_delta.x();
89 event.deltaY = -event_delta.y();
90 TickCurrentTime();
91 event.timeStampSeconds = (current_time_ - base::TimeTicks()).InSecondsF();
92
93 cc::InputHandlerScrollResult scroll_result;
94 scroll_result.did_overscroll_root = !overscroll_delta.IsZero();
95 scroll_result.unused_scroll_delta = overscroll_delta;
96
97 controller_.ObserveWheelEventAndResult(event, scroll_result);
98 input_event_count_ += 1;
99 }
100
101 const base::TimeTicks& TickCurrentTime() {
102 current_time_ += base::TimeDelta::FromSecondsD(1 / 60.f);
103 return current_time_;
104 }
105 void TickCurrentTimeAndAnimate() {
106 TickCurrentTime();
107 controller_.Animate(current_time_);
108 }
109
110 MockScrollElasticityHelper helper_;
111 InputScrollElasticityController controller_;
112 int input_event_count_;
113 base::TimeTicks current_time_;
114 };
115
116 // Verify that stretching only occurs in one axis at a time, and that it
117 // is biased to the Y axis.
118 TEST_F(ScrollElasticityControllerTest, Axis) {
119 helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(0, 0),
120 gfx::ScrollOffset(0, 0));
121
122 // If we push equally in the X and Y directions, we should see a stretch only
123 // in the Y direction.
124 SendMouseWheelEvent(PhaseBegan, PhaseNone);
125 SendMouseWheelEvent(PhaseChanged, PhaseNone, gfx::Vector2dF(10, 10),
126 gfx::Vector2dF(10, 10));
127 EXPECT_EQ(1, helper_.set_stretch_amount_count());
128 EXPECT_EQ(0.f, helper_.StretchAmount().x());
129 EXPECT_LT(0.f, helper_.StretchAmount().y());
130 helper_.SetStretchAmount(gfx::Vector2dF());
131 EXPECT_EQ(2, helper_.set_stretch_amount_count());
132 SendMouseWheelEvent(PhaseEnded, PhaseNone);
133 EXPECT_EQ(0, helper_.request_animate_count());
134
135 // If we push more in the X direction than the Y direction, we should see a
136 // stretch only in the X direction. This decision should be based on the
137 // input delta, not the actual overscroll delta.
138 SendMouseWheelEvent(PhaseBegan, PhaseNone);
139 SendMouseWheelEvent(PhaseChanged, PhaseNone, gfx::Vector2dF(-25, 10),
140 gfx::Vector2dF(-25, 40));
141 EXPECT_EQ(3, helper_.set_stretch_amount_count());
142 EXPECT_GT(0.f, helper_.StretchAmount().x());
143 EXPECT_EQ(0.f, helper_.StretchAmount().y());
144 helper_.SetStretchAmount(gfx::Vector2dF());
145 EXPECT_EQ(4, helper_.set_stretch_amount_count());
146 SendMouseWheelEvent(PhaseEnded, PhaseNone);
147 EXPECT_EQ(0, helper_.request_animate_count());
148 }
149
150 // Verify that we need a total overscroll delta of at least 10 in a pinned
151 // direction before we start stretching.
152 TEST_F(ScrollElasticityControllerTest, MinimumDeltaBeforeStretch) {
153 // We should not start stretching while we are not pinned in the direction
154 // of the scroll (even if there is an overscroll delta). We have to wait for
155 // the regular scroll to eat all of the events.
156 helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(5, 5),
157 gfx::ScrollOffset(10, 10));
158 SendMouseWheelEvent(PhaseMayBegin, PhaseNone);
159 SendMouseWheelEvent(PhaseBegan, PhaseNone);
160 SendMouseWheelEvent(PhaseChanged, PhaseNone, gfx::Vector2dF(0, 10),
161 gfx::Vector2dF(0, 10));
162 SendMouseWheelEvent(PhaseChanged, PhaseNone, gfx::Vector2dF(0, 10),
163 gfx::Vector2dF(0, 10));
164 EXPECT_EQ(0, helper_.set_stretch_amount_count());
165
166 // Now pin the -X and +Y direction. The first event will not generate a
167 // stretch
168 // because it is below the delta threshold of 10.
169 helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(0, 10),
170 gfx::ScrollOffset(10, 10));
171 SendMouseWheelEvent(PhaseChanged, PhaseNone, gfx::Vector2dF(0, 10),
172 gfx::Vector2dF(0, 8));
173 EXPECT_EQ(0, helper_.set_stretch_amount_count());
174
175 // Make the next scroll be in the -X direction more than the +Y direction,
176 // which will erase the memory of the previous unused delta of 8.
177 SendMouseWheelEvent(PhaseChanged, PhaseNone, gfx::Vector2dF(-10, 5),
178 gfx::Vector2dF(-8, 10));
179 EXPECT_EQ(0, helper_.set_stretch_amount_count());
180
181 // Now push against the pinned +Y direction again by 8. We reset the
182 // previous delta, so this will not generate a stretch.
183 SendMouseWheelEvent(PhaseChanged, PhaseNone, gfx::Vector2dF(0, 10),
184 gfx::Vector2dF(0, 8));
185 EXPECT_EQ(0, helper_.set_stretch_amount_count());
186
187 // Push against +Y by another 8. This gets us above the delta threshold of
188 // 10, so we should now have had the stretch set, and it should be in the
189 // +Y direction. The scroll in the -X direction should have been forgotten.
190 SendMouseWheelEvent(PhaseChanged, PhaseNone, gfx::Vector2dF(0, 10),
191 gfx::Vector2dF(0, 8));
192 EXPECT_EQ(1, helper_.set_stretch_amount_count());
193 EXPECT_EQ(0.f, helper_.StretchAmount().x());
194 EXPECT_LT(0.f, helper_.StretchAmount().y());
195
196 // End the gesture. Because there is a non-zero stretch, we should be in the
197 // animated state, and should have had a frame requested.
198 EXPECT_EQ(0, helper_.request_animate_count());
199 SendMouseWheelEvent(PhaseEnded, PhaseNone);
200 EXPECT_EQ(1, helper_.request_animate_count());
201 }
202
203 // Verify that an stretch caused by a momentum scroll will switch to the
204 // animating mode, where input events are ignored, and the stretch is updated
205 // while animating.
206 TEST_F(ScrollElasticityControllerTest, MomentumAnimate) {
207 // Do an active scroll, then switch to the momentum phase and scroll for a
208 // bit.
209 helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(5, 5),
210 gfx::ScrollOffset(10, 10));
211 SendMouseWheelEvent(PhaseBegan, PhaseNone);
212 SendMouseWheelEvent(PhaseChanged, PhaseNone, gfx::Vector2dF(0, -80),
213 gfx::Vector2dF(0, 0));
214 SendMouseWheelEvent(PhaseChanged, PhaseNone, gfx::Vector2dF(0, -80),
215 gfx::Vector2dF(0, 0));
216 SendMouseWheelEvent(PhaseChanged, PhaseNone, gfx::Vector2dF(0, -80),
217 gfx::Vector2dF(0, 0));
218 SendMouseWheelEvent(PhaseEnded, PhaseNone);
219 SendMouseWheelEvent(PhaseNone, PhaseBegan);
220 SendMouseWheelEvent(PhaseNone, PhaseChanged, gfx::Vector2dF(0, -80),
221 gfx::Vector2dF(0, 0));
222 SendMouseWheelEvent(PhaseNone, PhaseChanged, gfx::Vector2dF(0, -80),
223 gfx::Vector2dF(0, 0));
224 SendMouseWheelEvent(PhaseNone, PhaseChanged, gfx::Vector2dF(0, -80),
225 gfx::Vector2dF(0, 0));
226 EXPECT_EQ(0, helper_.set_stretch_amount_count());
227
228 // Hit the -Y edge and overscroll slightly, but not enough to go over the
229 // threshold to cause a stretch.
230 helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(5, 0),
231 gfx::ScrollOffset(10, 10));
232 SendMouseWheelEvent(PhaseNone, PhaseChanged, gfx::Vector2dF(0, -80),
233 gfx::Vector2dF(0, -8));
234 EXPECT_EQ(0, helper_.set_stretch_amount_count());
235 EXPECT_EQ(0, helper_.request_animate_count());
236
237 // Take another step, this time going over the threshold. This should update
238 // the stretch amount, and then switch to the animating mode.
239 SendMouseWheelEvent(PhaseNone, PhaseChanged, gfx::Vector2dF(0, -80),
240 gfx::Vector2dF(0, -80));
241 EXPECT_EQ(1, helper_.set_stretch_amount_count());
242 EXPECT_EQ(1, helper_.request_animate_count());
243 EXPECT_GT(-1.f, helper_.StretchAmount().y());
244
245 // Subsequent momentum events should do nothing.
246 SendMouseWheelEvent(PhaseNone, PhaseChanged, gfx::Vector2dF(0, -80),
247 gfx::Vector2dF(0, -80));
248 SendMouseWheelEvent(PhaseNone, PhaseChanged, gfx::Vector2dF(0, -80),
249 gfx::Vector2dF(0, -80));
250 SendMouseWheelEvent(PhaseNone, PhaseEnded, gfx::Vector2dF(0, -80),
251 gfx::Vector2dF(0, -80));
252 EXPECT_EQ(1, helper_.set_stretch_amount_count());
253 EXPECT_EQ(1, helper_.request_animate_count());
254
255 // Subsequent animate events should update the stretch amount and request
256 // another frame.
257 TickCurrentTimeAndAnimate();
258 EXPECT_EQ(2, helper_.set_stretch_amount_count());
259 EXPECT_EQ(2, helper_.request_animate_count());
260 EXPECT_GT(-1.f, helper_.StretchAmount().y());
261
262 // Touching the trackpad (a PhaseMayBegin event) should disable animation.
263 SendMouseWheelEvent(PhaseMayBegin, PhaseNone);
264 TickCurrentTimeAndAnimate();
265 EXPECT_EQ(2, helper_.set_stretch_amount_count());
266 EXPECT_EQ(2, helper_.request_animate_count());
267
268 // Releasing the trackpad should re-enable animation.
269 SendMouseWheelEvent(PhaseCancelled, PhaseNone);
270 EXPECT_EQ(2, helper_.set_stretch_amount_count());
271 EXPECT_EQ(3, helper_.request_animate_count());
272 TickCurrentTimeAndAnimate();
273 EXPECT_EQ(3, helper_.set_stretch_amount_count());
274 EXPECT_EQ(4, helper_.request_animate_count());
275
276 // Keep animating frames until the stretch returns to rest.
277 int stretch_count = 3;
278 int animate_count = 4;
279 while (1) {
280 TickCurrentTimeAndAnimate();
281 if (helper_.StretchAmount().IsZero()) {
282 stretch_count += 1;
283 EXPECT_EQ(stretch_count, helper_.set_stretch_amount_count());
284 EXPECT_EQ(animate_count, helper_.request_animate_count());
285 break;
286 }
287 stretch_count += 1;
288 animate_count += 1;
289 EXPECT_EQ(stretch_count, helper_.set_stretch_amount_count());
290 EXPECT_EQ(animate_count, helper_.request_animate_count());
291 }
292
293 // After coming to rest, no subsequent animate calls change anything.
294 TickCurrentTimeAndAnimate();
295 EXPECT_EQ(stretch_count, helper_.set_stretch_amount_count());
296 EXPECT_EQ(animate_count, helper_.request_animate_count());
297 }
298
299 // Verify that an stretch opposing a scroll is correctly resolved.
300 TEST_F(ScrollElasticityControllerTest, ReconcileStretchAndScroll) {
301 SendMouseWheelEvent(PhaseBegan, PhaseNone);
302
303 // Verify completely knocking out the scroll in the -Y direction.
304 helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(5, 5),
305 gfx::ScrollOffset(10, 10));
306 helper_.SetStretchAmount(gfx::Vector2dF(0, -10));
307 controller_.ReconcileStretchAndScroll();
308 EXPECT_EQ(helper_.StretchAmount(), gfx::Vector2dF(0, -5));
309 EXPECT_EQ(helper_.ScrollOffset(), gfx::ScrollOffset(5, 0));
310
311 // Verify partially knocking out the scroll in the -Y direction.
312 helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(5, 8),
313 gfx::ScrollOffset(10, 10));
314 helper_.SetStretchAmount(gfx::Vector2dF(0, -5));
315 controller_.ReconcileStretchAndScroll();
316 EXPECT_EQ(helper_.StretchAmount(), gfx::Vector2dF(0, 0));
317 EXPECT_EQ(helper_.ScrollOffset(), gfx::ScrollOffset(5, 3));
318
319 // Verify completely knocking out the scroll in the +X direction.
320 helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(5, 5),
321 gfx::ScrollOffset(10, 10));
322 helper_.SetStretchAmount(gfx::Vector2dF(10, 0));
323 controller_.ReconcileStretchAndScroll();
324 EXPECT_EQ(helper_.StretchAmount(), gfx::Vector2dF(5, 0));
325 EXPECT_EQ(helper_.ScrollOffset(), gfx::ScrollOffset(10, 5));
326
327 // Verify partially knocking out the scroll in the +X and +Y directions.
328 helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(2, 3),
329 gfx::ScrollOffset(10, 10));
330 helper_.SetStretchAmount(gfx::Vector2dF(5, 5));
331 controller_.ReconcileStretchAndScroll();
332 EXPECT_EQ(helper_.StretchAmount(), gfx::Vector2dF(0, 0));
333 EXPECT_EQ(helper_.ScrollOffset(), gfx::ScrollOffset(7, 8));
334 }
335
336 // Verify that stretching only happens when the area is user scrollable.
337 TEST_F(ScrollElasticityControllerTest, UserScrollableRequiredForStretch) {
338 helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(0, 0),
339 gfx::ScrollOffset(10, 10));
340 gfx::Vector2dF delta(0, -15);
341
342 // Do an active scroll, and ensure that the stretch amount doesn't change,
343 // and also that the stretch amount isn't even ever changed.
344 helper_.SetUserScrollable(false);
345 SendMouseWheelEvent(PhaseBegan, PhaseNone);
346 SendMouseWheelEvent(PhaseChanged, PhaseNone, delta, delta);
347 SendMouseWheelEvent(PhaseChanged, PhaseNone, delta, delta);
348 SendMouseWheelEvent(PhaseEnded, PhaseNone);
349 EXPECT_EQ(helper_.StretchAmount(), gfx::Vector2dF(0, 0));
350 EXPECT_EQ(0, helper_.set_stretch_amount_count());
351 SendMouseWheelEvent(PhaseNone, PhaseBegan);
352 SendMouseWheelEvent(PhaseNone, PhaseChanged, delta, delta);
353 SendMouseWheelEvent(PhaseNone, PhaseChanged, delta, delta);
354 SendMouseWheelEvent(PhaseNone, PhaseEnded);
355 EXPECT_EQ(helper_.StretchAmount(), gfx::Vector2dF(0, 0));
356 EXPECT_EQ(0, helper_.set_stretch_amount_count());
357
358 // Re-enable user scrolling and ensure that stretching is re-enabled.
359 helper_.SetUserScrollable(true);
360 SendMouseWheelEvent(PhaseBegan, PhaseNone);
361 SendMouseWheelEvent(PhaseChanged, PhaseNone, delta, delta);
362 SendMouseWheelEvent(PhaseChanged, PhaseNone, delta, delta);
363 SendMouseWheelEvent(PhaseEnded, PhaseNone);
364 EXPECT_NE(helper_.StretchAmount(), gfx::Vector2dF(0, 0));
365 EXPECT_GT(helper_.set_stretch_amount_count(), 0);
366 SendMouseWheelEvent(PhaseNone, PhaseBegan);
367 SendMouseWheelEvent(PhaseNone, PhaseChanged, delta, delta);
368 SendMouseWheelEvent(PhaseNone, PhaseChanged, delta, delta);
369 SendMouseWheelEvent(PhaseNone, PhaseEnded);
370 EXPECT_NE(helper_.StretchAmount(), gfx::Vector2dF(0, 0));
371 EXPECT_GT(helper_.set_stretch_amount_count(), 0);
372
373 // Disable user scrolling and tick the timer until the stretch goes back
374 // to zero. Ensure that the return to zero doesn't happen immediately.
375 helper_.SetUserScrollable(false);
376 int ticks_to_zero = 0;
377 while (1) {
378 TickCurrentTimeAndAnimate();
379 if (helper_.StretchAmount().IsZero())
380 break;
381 ticks_to_zero += 1;
382 }
383 EXPECT_GT(ticks_to_zero, 3);
384 }
385
386 } // namespace
387 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/input/input_scroll_elasticity_controller.cc ('k') | content/renderer/input/synchronous_input_handler_proxy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698