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

Side by Side Diff: cc/input/single_scrollbar_animation_controller_thinning_unittest.cc

Issue 2554913002: Prevent overlay scrollbars expand or hover together (Closed)
Patch Set: Merge remote-tracking branch 'origin/master' into fix-669677 Created 3 years, 11 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
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "cc/input/single_scrollbar_animation_controller_thinning.h"
6
7 #include "cc/layers/solid_color_scrollbar_layer_impl.h"
8 #include "cc/test/fake_impl_task_runner_provider.h"
9 #include "cc/test/fake_layer_tree_host_impl.h"
10 #include "cc/test/geometry_test_utils.h"
11 #include "cc/test/test_task_graph_runner.h"
12 #include "cc/trees/layer_tree_impl.h"
13 #include "testing/gmock/include/gmock/gmock.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 using testing::AtLeast;
17 using testing::Mock;
18 using testing::NiceMock;
19 using testing::_;
20
21 namespace cc {
22 namespace {
23
24 // These constants are hard-coded and should match the values in
25 // single_scrollbar_animation_controller_thinning.cc.
26 const float kIdleThicknessScale = 0.4f;
27 const float kDefaultMouseMoveDistanceToTriggerAnimation = 25.f;
28
29 class MockSingleScrollbarAnimationControllerClient
30 : public ScrollbarAnimationControllerClient {
31 public:
32 explicit MockSingleScrollbarAnimationControllerClient(
33 LayerTreeHostImpl* host_impl)
34 : host_impl_(host_impl) {}
35 virtual ~MockSingleScrollbarAnimationControllerClient() {}
36
37 void PostDelayedScrollbarAnimationTask(const base::Closure& start_fade,
bokan 2017/01/06 20:17:56 This should never be called, you can mock this. In
38 base::TimeDelta delay) override {
39 start_fade_ = start_fade;
40 delay_ = delay;
41 }
42 void SetNeedsRedrawForScrollbarAnimation() override {}
43 void SetNeedsAnimateForScrollbarAnimation() override {}
44 ScrollbarSet ScrollbarsFor(int scroll_layer_id) const override {
45 return host_impl_->ScrollbarsFor(scroll_layer_id);
46 }
47 MOCK_METHOD0(DidChangeScrollbarVisibility, void());
48
49 base::Closure& start_fade() { return start_fade_; }
50 base::TimeDelta& delay() { return delay_; }
51
52 private:
53 base::Closure start_fade_;
54 base::TimeDelta delay_;
55 LayerTreeHostImpl* host_impl_;
56 };
57
58 class SingleScrollbarAnimationControllerThinningTest : public testing::Test {
59 public:
60 SingleScrollbarAnimationControllerThinningTest()
61 : host_impl_(&task_runner_provider_, &task_graph_runner_),
62 client_(&host_impl_) {}
63
64 protected:
65 const base::TimeDelta kThinningDuration = base::TimeDelta::FromSeconds(2);
66
67 void SetUp() override {
68 std::unique_ptr<LayerImpl> scroll_layer =
69 LayerImpl::Create(host_impl_.active_tree(), 1);
70 std::unique_ptr<LayerImpl> clip =
71 LayerImpl::Create(host_impl_.active_tree(), 3);
72 clip_layer_ = clip.get();
73 scroll_layer->SetScrollClipLayer(clip_layer_->id());
74 LayerImpl* scroll_layer_ptr = scroll_layer.get();
75
76 const int kId = 2;
77 const int kThumbThickness = 10;
78 const int kTrackStart = 0;
79 const bool kIsLeftSideVerticalScrollbar = false;
80 const bool kIsOverlayScrollbar = true;
81
82 std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar =
83 SolidColorScrollbarLayerImpl::Create(
84 host_impl_.active_tree(), kId, HORIZONTAL, kThumbThickness,
85 kTrackStart, kIsLeftSideVerticalScrollbar, kIsOverlayScrollbar);
86 scrollbar_layer_ = scrollbar.get();
87
88 scroll_layer->test_properties()->AddChild(std::move(scrollbar));
89 clip_layer_->test_properties()->AddChild(std::move(scroll_layer));
90 host_impl_.active_tree()->SetRootLayerForTesting(std::move(clip));
91
92 scrollbar_layer_->SetScrollLayerId(scroll_layer_ptr->id());
93 scrollbar_layer_->test_properties()->opacity_can_animate = true;
94 clip_layer_->SetBounds(gfx::Size(100, 100));
95 scroll_layer_ptr->SetBounds(gfx::Size(200, 200));
96 host_impl_.active_tree()->BuildLayerListAndPropertyTreesForTesting();
97
98 scrollbar_controller_ = SingleScrollbarAnimationControllerThinning::Create(
99 scroll_layer_ptr->id(), HORIZONTAL, &client_, kThinningDuration);
100 }
101
102 FakeImplTaskRunnerProvider task_runner_provider_;
103 TestTaskGraphRunner task_graph_runner_;
104 FakeLayerTreeHostImpl host_impl_;
105 std::unique_ptr<SingleScrollbarAnimationControllerThinning>
106 scrollbar_controller_;
107 LayerImpl* clip_layer_;
108 SolidColorScrollbarLayerImpl* scrollbar_layer_;
109 NiceMock<MockSingleScrollbarAnimationControllerClient> client_;
110 };
111
112 // Check initialization of scrollbar. Should start thin.
113 TEST_F(SingleScrollbarAnimationControllerThinningTest, Idle) {
114 EXPECT_FLOAT_EQ(kIdleThicknessScale,
115 scrollbar_layer_->thumb_thickness_scale_factor());
116 }
117
118 // Move the pointer near the scrollbar. Confirm it gets thick and narrow when
119 // moved away.
120 TEST_F(SingleScrollbarAnimationControllerThinningTest, MouseNear) {
121 base::TimeTicks time;
122 time += base::TimeDelta::FromSeconds(1);
123
124 scrollbar_controller_->DidMouseMoveNear(1);
125 scrollbar_controller_->Animate(time);
126 EXPECT_FLOAT_EQ(kIdleThicknessScale,
127 scrollbar_layer_->thumb_thickness_scale_factor());
128
129 // Should animate to thickened.
130 time += kThinningDuration;
131 scrollbar_controller_->Animate(time);
132 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
133
134 // Subsequent moves within the nearness threshold should not change anything.
135 scrollbar_controller_->DidMouseMoveNear(2);
136 scrollbar_controller_->Animate(time);
137 time += base::TimeDelta::FromSeconds(10);
138 scrollbar_controller_->Animate(time);
139 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
140
141 // Now move away from bar.
142 scrollbar_controller_->DidMouseMoveNear(
143 kDefaultMouseMoveDistanceToTriggerAnimation);
144 scrollbar_controller_->Animate(time);
145 time += kThinningDuration;
146 scrollbar_controller_->Animate(time);
147 EXPECT_FLOAT_EQ(kIdleThicknessScale,
148 scrollbar_layer_->thumb_thickness_scale_factor());
149 }
150
151 // Move the pointer over the scrollbar. Make sure it gets thick that it gets
152 // thin when moved away.
153 TEST_F(SingleScrollbarAnimationControllerThinningTest, MouseOver) {
154 base::TimeTicks time;
155 time += base::TimeDelta::FromSeconds(1);
156
157 scrollbar_controller_->DidMouseMoveNear(0);
158 scrollbar_controller_->Animate(time);
159 EXPECT_FLOAT_EQ(kIdleThicknessScale,
160 scrollbar_layer_->thumb_thickness_scale_factor());
161
162 // Should animate to thickened.
163 time += kThinningDuration;
164 scrollbar_controller_->Animate(time);
165 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
166
167 // Subsequent moves should not change anything.
168 scrollbar_controller_->DidMouseMoveNear(0);
169 scrollbar_controller_->Animate(time);
170 time += base::TimeDelta::FromSeconds(10);
171 scrollbar_controller_->Animate(time);
172 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
173
174 // Moving off the scrollbar but still withing the "near" threshold should do
175 // nothing.
176 scrollbar_controller_->DidMouseMoveNear(
177 kDefaultMouseMoveDistanceToTriggerAnimation - 1.f);
178 scrollbar_controller_->Animate(time);
179 time += base::TimeDelta::FromSeconds(10);
180 scrollbar_controller_->Animate(time);
181 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
182
183 // Now move away from bar.
184 scrollbar_controller_->DidMouseMoveNear(
185 kDefaultMouseMoveDistanceToTriggerAnimation);
186 scrollbar_controller_->Animate(time);
187 time += kThinningDuration;
188 scrollbar_controller_->Animate(time);
189 EXPECT_FLOAT_EQ(kIdleThicknessScale,
190 scrollbar_layer_->thumb_thickness_scale_factor());
191 }
192
193 // First move the pointer over the scrollbar off of it. Make sure the thinning
194 // animation kicked off in DidMouseMoveOffScrollbar gets overridden by the
195 // thickening animation in the DidMouseMoveNear call.
196 TEST_F(SingleScrollbarAnimationControllerThinningTest,
197 MouseNearThenAwayWhileAnimating) {
198 base::TimeTicks time;
199 time += base::TimeDelta::FromSeconds(1);
200
201 scrollbar_controller_->DidMouseMoveNear(0);
202 scrollbar_controller_->Animate(time);
203 EXPECT_FLOAT_EQ(kIdleThicknessScale,
204 scrollbar_layer_->thumb_thickness_scale_factor());
205
206 // Should animate to thickened.
207 time += kThinningDuration;
208 scrollbar_controller_->Animate(time);
209 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
210
211 // This is tricky. The DidMouseLeave() is sent before the
212 // subsequent DidMouseMoveNear(), if the mouse moves in that direction.
213 // This results in the thumb thinning. We want to make sure that when the
214 // thumb starts expanding it doesn't first narrow to the idle thinness.
215 time += base::TimeDelta::FromSeconds(1);
216 scrollbar_controller_->DidMouseLeave();
217 scrollbar_controller_->Animate(time);
218 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
219
220 // Let the animation run half of the way through the thinning animation.
221 time += kThinningDuration / 2;
222 scrollbar_controller_->Animate(time);
223 EXPECT_FLOAT_EQ(1.0f - (1.0f - kIdleThicknessScale) / 2.0f,
224 scrollbar_layer_->thumb_thickness_scale_factor());
225
226 // Now we get a notification for the mouse moving over the scroller. The
227 // animation is reset to the thickening direction but we won't start
228 // thickening until the new animation catches up to the current thickness.
bokan 2017/01/06 20:17:56 Hmm, I don't like this. Could we make it that the
chaopeng 2017/01/10 20:49:50 Yes, today we just change the animation direction
229 scrollbar_controller_->DidMouseMoveNear(1);
230 scrollbar_controller_->Animate(time);
231 EXPECT_FLOAT_EQ(1.0f - (1.0f - kIdleThicknessScale) / 2.0f,
232 scrollbar_layer_->thumb_thickness_scale_factor());
233
234 // Until we reach the half way point, the animation will have no effect.
235 time += kThinningDuration / 4;
236 scrollbar_controller_->Animate(time);
237 EXPECT_FLOAT_EQ(1.0f - (1.0f - kIdleThicknessScale) / 2.0f,
238 scrollbar_layer_->thumb_thickness_scale_factor());
239
240 time += kThinningDuration / 4;
241 scrollbar_controller_->Animate(time);
242 EXPECT_FLOAT_EQ(1.0f - (1.0f - kIdleThicknessScale) / 2.0f,
243 scrollbar_layer_->thumb_thickness_scale_factor());
244
245 // We're now at three quarters of the way through so it should now started
246 // thickening again.
247 time += kThinningDuration / 4;
248 scrollbar_controller_->Animate(time);
249 EXPECT_FLOAT_EQ(kIdleThicknessScale + 3 * (1.0f - kIdleThicknessScale) / 4.0f,
250 scrollbar_layer_->thumb_thickness_scale_factor());
251
252 // And all the way to the end.
253 time += kThinningDuration / 4;
254 scrollbar_controller_->Animate(time);
255 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
256 }
257
258 // First move the pointer on the scrollbar, then press it, then away.
259 // Confirm that the bar gets thick. Then mouse up. Confirm that
260 // the bar gets thin.
261 TEST_F(SingleScrollbarAnimationControllerThinningTest,
262 MouseCaptureAndReleaseOutOfBar) {
263 base::TimeTicks time;
264 time += base::TimeDelta::FromSeconds(1);
265
266 // Move over the scrollbar.
267 scrollbar_controller_->DidMouseMoveNear(0);
268 scrollbar_controller_->Animate(time);
269 time += kThinningDuration;
270 scrollbar_controller_->Animate(time);
271 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
272
273 // Capture
274 scrollbar_controller_->DidMouseDown();
275 time += base::TimeDelta::FromSeconds(1);
276 scrollbar_controller_->Animate(time);
277 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
278
279 // Should stay thick for a while.
280 time += base::TimeDelta::FromSeconds(10);
281 scrollbar_controller_->Animate(time);
282
283 // Move outside the "near" threshold. Because the scrollbar is captured it
284 // should remain thick.
285 scrollbar_controller_->DidMouseMoveNear(
286 kDefaultMouseMoveDistanceToTriggerAnimation);
287 time += kThinningDuration;
288 scrollbar_controller_->Animate(time);
289 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
290
291 // Release.
292 scrollbar_controller_->DidMouseUp();
293
294 // Should become thin.
295 time += base::TimeDelta::FromSeconds(1);
296 scrollbar_controller_->Animate(time);
297 time += kThinningDuration;
298 scrollbar_controller_->Animate(time);
299 EXPECT_FLOAT_EQ(kIdleThicknessScale,
300 scrollbar_layer_->thumb_thickness_scale_factor());
301 }
302
303 // First move the pointer on the scrollbar, then press it, then away. Confirm
304 // that the bar gets thick. Then move point on the scrollbar and mouse up.
305 // Confirm that the bar stays thick.
306 TEST_F(SingleScrollbarAnimationControllerThinningTest,
307 MouseCaptureAndReleaseOnBar) {
308 base::TimeTicks time;
309 time += base::TimeDelta::FromSeconds(1);
310
311 // Move over scrollbar.
312 scrollbar_controller_->DidMouseMoveNear(0);
313 scrollbar_controller_->Animate(time);
314 time += kThinningDuration;
315 scrollbar_controller_->Animate(time);
316 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
317
318 // Capture. Nothing should change.
319 scrollbar_controller_->DidMouseDown();
320 time += base::TimeDelta::FromSeconds(1);
321 scrollbar_controller_->Animate(time);
322 time += base::TimeDelta::FromSeconds(10);
323 scrollbar_controller_->Animate(time);
324 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
325
326 // Move away from scrollbar. Nothing should change.
327 scrollbar_controller_->DidMouseMoveNear(
328 kDefaultMouseMoveDistanceToTriggerAnimation);
329 time += base::TimeDelta::FromSeconds(1);
330 scrollbar_controller_->Animate(time);
331 time += base::TimeDelta::FromSeconds(10);
332 scrollbar_controller_->Animate(time);
333 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
334
335 // Move over scrollbar and release. Since we're near the scrollbar, it should
336 // remain thick.
337 scrollbar_controller_->DidMouseMoveNear(0);
338 scrollbar_controller_->DidMouseUp();
339 time += base::TimeDelta::FromSeconds(1);
340 scrollbar_controller_->Animate(time);
341 time += base::TimeDelta::FromSeconds(10);
342 scrollbar_controller_->Animate(time);
343 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
344 }
345
346 // Tests that the thickening/thinning effects are animated.
347 TEST_F(SingleScrollbarAnimationControllerThinningTest, ThicknessAnimated) {
348 base::TimeTicks time;
349 time += base::TimeDelta::FromSeconds(1);
350
351 // Move mouse near scrollbar. Test that at half the duration time, the
352 // thickness is half way through its animation.
353 scrollbar_controller_->DidMouseMoveNear(1);
354 scrollbar_controller_->Animate(time);
355 EXPECT_FLOAT_EQ(kIdleThicknessScale,
356 scrollbar_layer_->thumb_thickness_scale_factor());
357
358 time += kThinningDuration / 2;
359 scrollbar_controller_->Animate(time);
360 EXPECT_FLOAT_EQ(kIdleThicknessScale + (1.0f - kIdleThicknessScale) / 2.0f,
361 scrollbar_layer_->thumb_thickness_scale_factor());
362
363 time += kThinningDuration / 2;
364 scrollbar_controller_->Animate(time);
365 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
366
367 // Move mouse away from scrollbar. Same check.
368 time += base::TimeDelta::FromSeconds(1);
369 scrollbar_controller_->DidMouseMoveNear(
370 kDefaultMouseMoveDistanceToTriggerAnimation);
371 scrollbar_controller_->Animate(time);
372 EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
373
374 time += kThinningDuration / 2;
375 scrollbar_controller_->Animate(time);
376 EXPECT_FLOAT_EQ(1.0f - (1.0f - kIdleThicknessScale) / 2.0f,
377 scrollbar_layer_->thumb_thickness_scale_factor());
378
379 time += kThinningDuration / 2;
380 scrollbar_controller_->Animate(time);
381 EXPECT_FLOAT_EQ(kIdleThicknessScale,
382 scrollbar_layer_->thumb_thickness_scale_factor());
383 }
384
385 } // namespace
386 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698