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.
5 #include "cc/animation/scrollbar_animation_controller_thinning.h"
7 #include "cc/layers/solid_color_scrollbar_layer_impl.h"
8 #include "cc/test/fake_impl_proxy.h"
9 #include "cc/test/fake_layer_tree_host_impl.h"
10 #include "testing/gtest/include/gtest/gtest.h"
15 class ScrollbarAnimationControllerThinningTest
: public testing::Test
{
17 ScrollbarAnimationControllerThinningTest() : host_impl_(&proxy_
) {}
20 virtual void SetUp() {
21 scroll_layer_
= LayerImpl::Create(host_impl_
.active_tree(), 1);
23 const int kThumbThickness
= 10;
24 const bool kIsLeftSideVerticalScrollbar
= false;
25 scrollbar_layer_
= SolidColorScrollbarLayerImpl::Create(
26 host_impl_
.active_tree(), kId
, HORIZONTAL
, kThumbThickness
,
27 kIsLeftSideVerticalScrollbar
);
29 scroll_layer_
->SetMaxScrollOffset(gfx::Vector2d(50, 50));
30 scroll_layer_
->SetBounds(gfx::Size(50, 50));
31 scroll_layer_
->SetHorizontalScrollbarLayer(scrollbar_layer_
.get());
33 scrollbar_controller_
= ScrollbarAnimationControllerThinning::CreateForTest(
35 base::TimeDelta::FromSeconds(2),
36 base::TimeDelta::FromSeconds(3));
40 FakeLayerTreeHostImpl host_impl_
;
41 scoped_ptr
<ScrollbarAnimationControllerThinning
> scrollbar_controller_
;
42 scoped_ptr
<LayerImpl
> scroll_layer_
;
43 scoped_ptr
<SolidColorScrollbarLayerImpl
> scrollbar_layer_
;
46 // Check initialization of scrollbar.
47 TEST_F(ScrollbarAnimationControllerThinningTest
, Idle
) {
48 scrollbar_controller_
->Animate(base::TimeTicks());
49 EXPECT_FLOAT_EQ(0.7f
, scrollbar_layer_
->opacity());
50 EXPECT_FLOAT_EQ(0.4f
, scrollbar_layer_
->thumb_thickness_scale_factor());
53 // Scroll content. Confirm the scrollbar gets dark and then becomes light
55 TEST_F(ScrollbarAnimationControllerThinningTest
, AwakenByProgrammaticScroll
) {
57 time
+= base::TimeDelta::FromSeconds(1);
58 EXPECT_TRUE(scrollbar_controller_
->DidScrollUpdate(time
));
59 EXPECT_TRUE(scrollbar_controller_
->IsAnimating());
60 EXPECT_EQ(2, scrollbar_controller_
->DelayBeforeStart(time
).InSeconds());
61 EXPECT_FLOAT_EQ(1.0f
, scrollbar_layer_
->opacity());
62 // Scrollbar doesn't change size if triggered by scroll.
63 EXPECT_FLOAT_EQ(0.4f
, scrollbar_layer_
->thumb_thickness_scale_factor());
65 time
+= base::TimeDelta::FromSeconds(1);
66 EXPECT_EQ(1, scrollbar_controller_
->DelayBeforeStart(time
).InSeconds());
67 scrollbar_controller_
->Animate(time
);
68 EXPECT_FLOAT_EQ(1.0f
, scrollbar_layer_
->opacity());
69 EXPECT_FLOAT_EQ(0.4f
, scrollbar_layer_
->thumb_thickness_scale_factor());
71 // Subsequent scroll restarts animation.
72 EXPECT_TRUE(scrollbar_controller_
->DidScrollUpdate(time
));
73 EXPECT_EQ(2, scrollbar_controller_
->DelayBeforeStart(time
).InSeconds());
75 time
+= base::TimeDelta::FromSeconds(1);
76 EXPECT_EQ(1, scrollbar_controller_
->DelayBeforeStart(time
).InSeconds());
77 scrollbar_controller_
->Animate(time
);
78 EXPECT_FLOAT_EQ(1.0f
, scrollbar_layer_
->opacity());
79 EXPECT_FLOAT_EQ(0.4f
, scrollbar_layer_
->thumb_thickness_scale_factor());
81 time
+= base::TimeDelta::FromSeconds(1);
82 EXPECT_EQ(0, scrollbar_controller_
->DelayBeforeStart(time
).InSeconds());
83 scrollbar_controller_
->Animate(time
);
84 EXPECT_FLOAT_EQ(1.0f
, scrollbar_layer_
->opacity());
85 EXPECT_FLOAT_EQ(0.4f
, scrollbar_layer_
->thumb_thickness_scale_factor());
87 time
+= base::TimeDelta::FromSeconds(1);
88 scrollbar_controller_
->Animate(time
);
89 EXPECT_FLOAT_EQ(0.9f
, scrollbar_layer_
->opacity());
90 EXPECT_FLOAT_EQ(0.4f
, scrollbar_layer_
->thumb_thickness_scale_factor());
92 time
+= base::TimeDelta::FromSeconds(1);
93 scrollbar_controller_
->Animate(time
);
94 EXPECT_FLOAT_EQ(0.8f
, scrollbar_layer_
->opacity());
95 EXPECT_FLOAT_EQ(0.4f
, scrollbar_layer_
->thumb_thickness_scale_factor());
97 time
+= base::TimeDelta::FromSeconds(1);
98 scrollbar_controller_
->Animate(time
);
99 EXPECT_FLOAT_EQ(0.7f
, scrollbar_layer_
->opacity());
100 EXPECT_FLOAT_EQ(0.4f
, scrollbar_layer_
->thumb_thickness_scale_factor());
102 EXPECT_FALSE(scrollbar_controller_
->IsAnimating());
105 // Initiate a scroll when the pointer is already near the scrollbar. It should
107 TEST_F(ScrollbarAnimationControllerThinningTest
, ScrollWithMouseNear
) {
108 base::TimeTicks time
;
109 time
+= base::TimeDelta::FromSeconds(1);
111 scrollbar_controller_
->DidMouseMoveNear(time
, 1);
112 time
+= base::TimeDelta::FromSeconds(3);
113 scrollbar_controller_
->Animate(time
);
114 EXPECT_FALSE(scrollbar_controller_
->IsAnimating());
115 EXPECT_FLOAT_EQ(1.0f
, scrollbar_layer_
->thumb_thickness_scale_factor());
117 EXPECT_TRUE(scrollbar_controller_
->DidScrollUpdate(time
));
118 EXPECT_TRUE(scrollbar_controller_
->IsAnimating());
119 EXPECT_EQ(2, scrollbar_controller_
->DelayBeforeStart(time
).InSeconds());
120 EXPECT_FLOAT_EQ(1.0f
, scrollbar_layer_
->opacity());
121 // Scrollbar should still be thick.
122 EXPECT_FLOAT_EQ(1.0f
, scrollbar_layer_
->thumb_thickness_scale_factor());
124 time
+= base::TimeDelta::FromSeconds(5);
125 scrollbar_controller_
->Animate(time
);
126 EXPECT_FALSE(scrollbar_controller_
->IsAnimating());
127 EXPECT_FLOAT_EQ(0.7f
, scrollbar_layer_
->opacity());
128 EXPECT_FLOAT_EQ(1.0f
, scrollbar_layer_
->thumb_thickness_scale_factor());
131 // Move the pointer near the scrollbar. Confirm it gets thick and narrow when
133 TEST_F(ScrollbarAnimationControllerThinningTest
, MouseNear
) {
134 base::TimeTicks time
;
135 time
+= base::TimeDelta::FromSeconds(1);
136 scrollbar_controller_
->DidMouseMoveNear(time
, 1);
137 EXPECT_TRUE(scrollbar_controller_
->IsAnimating());
138 EXPECT_EQ(0, scrollbar_controller_
->DelayBeforeStart(time
).InSeconds());
139 EXPECT_FLOAT_EQ(0.7f
, scrollbar_layer_
->opacity());
140 EXPECT_FLOAT_EQ(0.4f
, scrollbar_layer_
->thumb_thickness_scale_factor());
142 // Should animate to thickened but not darken.
143 time
+= base::TimeDelta::FromSeconds(1);
144 scrollbar_controller_
->Animate(time
);
145 EXPECT_FLOAT_EQ(0.7f
, scrollbar_layer_
->opacity());
146 EXPECT_FLOAT_EQ(0.6f
, scrollbar_layer_
->thumb_thickness_scale_factor());
148 time
+= base::TimeDelta::FromSeconds(1);
149 scrollbar_controller_
->Animate(time
);
150 EXPECT_FLOAT_EQ(0.7f
, scrollbar_layer_
->opacity());
151 EXPECT_FLOAT_EQ(0.8f
, scrollbar_layer_
->thumb_thickness_scale_factor());
153 time
+= base::TimeDelta::FromSeconds(1);
154 scrollbar_controller_
->Animate(time
);
155 EXPECT_FLOAT_EQ(0.7f
, scrollbar_layer_
->opacity());
156 EXPECT_FLOAT_EQ(1.0f
, scrollbar_layer_
->thumb_thickness_scale_factor());
157 EXPECT_FALSE(scrollbar_controller_
->IsAnimating());
159 // Subsequent moves should not change anything.
160 scrollbar_controller_
->DidMouseMoveNear(time
, 1);
161 EXPECT_FLOAT_EQ(0.7f
, scrollbar_layer_
->opacity());
162 EXPECT_FLOAT_EQ(1.0f
, scrollbar_layer_
->thumb_thickness_scale_factor());
163 EXPECT_FALSE(scrollbar_controller_
->IsAnimating());
165 // Now move away from bar.
166 time
+= base::TimeDelta::FromSeconds(1);
167 scrollbar_controller_
->DidMouseMoveNear(time
, 26);
168 EXPECT_TRUE(scrollbar_controller_
->IsAnimating());
169 EXPECT_EQ(0, scrollbar_controller_
->DelayBeforeStart(time
).InSeconds());
170 EXPECT_FLOAT_EQ(0.7f
, scrollbar_layer_
->opacity());
171 EXPECT_FLOAT_EQ(1.0f
, scrollbar_layer_
->thumb_thickness_scale_factor());
173 // Animate to narrow.
174 time
+= base::TimeDelta::FromSeconds(1);
175 scrollbar_controller_
->Animate(time
);
176 EXPECT_FLOAT_EQ(0.7f
, scrollbar_layer_
->opacity());
177 EXPECT_FLOAT_EQ(0.8f
, scrollbar_layer_
->thumb_thickness_scale_factor());
179 time
+= base::TimeDelta::FromSeconds(1);
180 scrollbar_controller_
->Animate(time
);
181 EXPECT_FLOAT_EQ(0.7f
, scrollbar_layer_
->opacity());
182 EXPECT_FLOAT_EQ(0.6f
, scrollbar_layer_
->thumb_thickness_scale_factor());
184 time
+= base::TimeDelta::FromSeconds(1);
185 scrollbar_controller_
->Animate(time
);
186 EXPECT_FLOAT_EQ(0.7f
, scrollbar_layer_
->opacity());
187 EXPECT_FLOAT_EQ(0.4f
, scrollbar_layer_
->thumb_thickness_scale_factor());
188 EXPECT_FALSE(scrollbar_controller_
->IsAnimating());
191 // Move the pointer over the scrollbar. Make sure it gets thick and dark
192 // and that it gets thin and light when moved away.
193 TEST_F(ScrollbarAnimationControllerThinningTest
, MouseOver
) {
194 base::TimeTicks time
;
195 time
+= base::TimeDelta::FromSeconds(1);
196 scrollbar_controller_
->DidMouseMoveNear(time
, 0);
197 EXPECT_TRUE(scrollbar_controller_
->IsAnimating());
198 EXPECT_EQ(0, scrollbar_controller_
->DelayBeforeStart(time
).InSeconds());
199 EXPECT_FLOAT_EQ(0.7f
, scrollbar_layer_
->opacity());
200 EXPECT_FLOAT_EQ(0.4f
, scrollbar_layer_
->thumb_thickness_scale_factor());
202 // Should animate to thickened and darkened.
203 time
+= base::TimeDelta::FromSeconds(1);
204 scrollbar_controller_
->Animate(time
);
205 EXPECT_FLOAT_EQ(0.8f
, scrollbar_layer_
->opacity());
206 EXPECT_FLOAT_EQ(0.6f
, scrollbar_layer_
->thumb_thickness_scale_factor());
208 time
+= base::TimeDelta::FromSeconds(1);
209 scrollbar_controller_
->Animate(time
);
210 EXPECT_FLOAT_EQ(0.9f
, scrollbar_layer_
->opacity());
211 EXPECT_FLOAT_EQ(0.8f
, scrollbar_layer_
->thumb_thickness_scale_factor());
213 time
+= base::TimeDelta::FromSeconds(1);
214 scrollbar_controller_
->Animate(time
);
215 EXPECT_FLOAT_EQ(1.0f
, scrollbar_layer_
->opacity());
216 EXPECT_FLOAT_EQ(1.0f
, scrollbar_layer_
->thumb_thickness_scale_factor());
217 EXPECT_FALSE(scrollbar_controller_
->IsAnimating());
219 // Subsequent moves should not change anything.
220 scrollbar_controller_
->DidMouseMoveNear(time
, 0);
221 EXPECT_FLOAT_EQ(1.0f
, scrollbar_layer_
->opacity());
222 EXPECT_FLOAT_EQ(1.0f
, scrollbar_layer_
->thumb_thickness_scale_factor());
223 EXPECT_FALSE(scrollbar_controller_
->IsAnimating());
225 // Now move away from bar.
226 time
+= base::TimeDelta::FromSeconds(1);
227 scrollbar_controller_
->DidMouseMoveNear(time
, 26);
228 EXPECT_TRUE(scrollbar_controller_
->IsAnimating());
229 EXPECT_EQ(0, scrollbar_controller_
->DelayBeforeStart(time
).InSeconds());
230 EXPECT_FLOAT_EQ(1.0f
, scrollbar_layer_
->opacity());
231 EXPECT_FLOAT_EQ(1.0f
, scrollbar_layer_
->thumb_thickness_scale_factor());
233 // Animate to narrow.
234 time
+= base::TimeDelta::FromSeconds(1);
235 scrollbar_controller_
->Animate(time
);
236 EXPECT_FLOAT_EQ(0.9f
, scrollbar_layer_
->opacity());
237 EXPECT_FLOAT_EQ(0.8f
, scrollbar_layer_
->thumb_thickness_scale_factor());
239 time
+= base::TimeDelta::FromSeconds(1);
240 scrollbar_controller_
->Animate(time
);
241 EXPECT_FLOAT_EQ(0.8f
, scrollbar_layer_
->opacity());
242 EXPECT_FLOAT_EQ(0.6f
, scrollbar_layer_
->thumb_thickness_scale_factor());
244 time
+= base::TimeDelta::FromSeconds(1);
245 scrollbar_controller_
->Animate(time
);
246 EXPECT_FLOAT_EQ(0.7f
, scrollbar_layer_
->opacity());
247 EXPECT_FLOAT_EQ(0.4f
, scrollbar_layer_
->thumb_thickness_scale_factor());
248 EXPECT_FALSE(scrollbar_controller_
->IsAnimating());
251 // First move the pointer near the scrollbar, then over it, then back near
252 // then far away. Confirm that first the bar gets thick, then dark, then light,
254 TEST_F(ScrollbarAnimationControllerThinningTest
, MouseNearThenOver
) {
255 base::TimeTicks time
;
256 time
+= base::TimeDelta::FromSeconds(1);
257 scrollbar_controller_
->DidMouseMoveNear(time
, 1);
258 EXPECT_TRUE(scrollbar_controller_
->IsAnimating());
259 EXPECT_EQ(0, scrollbar_controller_
->DelayBeforeStart(time
).InSeconds());
260 EXPECT_FLOAT_EQ(0.7f
, scrollbar_layer_
->opacity());
261 EXPECT_FLOAT_EQ(0.4f
, scrollbar_layer_
->thumb_thickness_scale_factor());
263 // Should animate to thickened but not darken.
264 time
+= base::TimeDelta::FromSeconds(3);
265 scrollbar_controller_
->Animate(time
);
266 EXPECT_FLOAT_EQ(0.7f
, scrollbar_layer_
->opacity());
267 EXPECT_FLOAT_EQ(1.0f
, scrollbar_layer_
->thumb_thickness_scale_factor());
268 EXPECT_FALSE(scrollbar_controller_
->IsAnimating());
271 scrollbar_controller_
->DidMouseMoveNear(time
, 0);
272 EXPECT_TRUE(scrollbar_controller_
->IsAnimating());
273 EXPECT_EQ(0, scrollbar_controller_
->DelayBeforeStart(time
).InSeconds());
275 // Should animate to darkened.
276 time
+= base::TimeDelta::FromSeconds(1);
277 scrollbar_controller_
->Animate(time
);
278 EXPECT_FLOAT_EQ(0.8f
, scrollbar_layer_
->opacity());
279 EXPECT_FLOAT_EQ(1.0f
, scrollbar_layer_
->thumb_thickness_scale_factor());
281 time
+= base::TimeDelta::FromSeconds(1);
282 scrollbar_controller_
->Animate(time
);
283 EXPECT_FLOAT_EQ(0.9f
, scrollbar_layer_
->opacity());
284 EXPECT_FLOAT_EQ(1.0f
, scrollbar_layer_
->thumb_thickness_scale_factor());
286 time
+= base::TimeDelta::FromSeconds(1);
287 scrollbar_controller_
->Animate(time
);
288 EXPECT_FLOAT_EQ(1.0f
, scrollbar_layer_
->opacity());
289 EXPECT_FLOAT_EQ(1.0f
, scrollbar_layer_
->thumb_thickness_scale_factor());
290 EXPECT_FALSE(scrollbar_controller_
->IsAnimating());
292 // This is tricky. The DidMouseMoveOffScrollbar() is sent before the
293 // subsequent DidMouseMoveNear(), if the mouse moves in that direction.
294 // This results in the thumb thinning. We want to make sure that when the
295 // thumb starts expanding it doesn't first narrow to the idle thinness.
296 time
+= base::TimeDelta::FromSeconds(1);
297 scrollbar_controller_
->DidMouseMoveOffScrollbar(time
);
298 EXPECT_TRUE(scrollbar_controller_
->IsAnimating());
300 time
+= base::TimeDelta::FromSeconds(1);
301 scrollbar_controller_
->Animate(time
);
302 EXPECT_FLOAT_EQ(0.9f
, scrollbar_layer_
->opacity());
303 EXPECT_FLOAT_EQ(0.8f
, scrollbar_layer_
->thumb_thickness_scale_factor());
305 scrollbar_controller_
->DidMouseMoveNear(time
, 1);
306 // A new animation is kicked off.
307 EXPECT_TRUE(scrollbar_controller_
->IsAnimating());
309 time
+= base::TimeDelta::FromSeconds(1);
310 scrollbar_controller_
->Animate(time
);
311 // We will initiate the narrowing again, but it won't get decremented until
312 // the new animation catches up to it.
313 EXPECT_FLOAT_EQ(0.9f
, scrollbar_layer_
->opacity());
314 // Now the thickness should be increasing, but it shouldn't happen until the
315 // animation catches up.
316 EXPECT_FLOAT_EQ(0.8f
, scrollbar_layer_
->thumb_thickness_scale_factor());
318 time
+= base::TimeDelta::FromSeconds(1);
319 scrollbar_controller_
->Animate(time
);
320 EXPECT_FLOAT_EQ(0.8f
, scrollbar_layer_
->opacity());
321 // The thickness now gets big again.
322 EXPECT_FLOAT_EQ(0.8f
, scrollbar_layer_
->thumb_thickness_scale_factor());
324 time
+= base::TimeDelta::FromSeconds(1);
325 scrollbar_controller_
->Animate(time
);
326 EXPECT_FLOAT_EQ(0.7f
, scrollbar_layer_
->opacity());
327 // The thickness now gets big again.
328 EXPECT_FLOAT_EQ(1.0f
, scrollbar_layer_
->thumb_thickness_scale_factor());