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/input/top_controls_manager.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/time/time.h"
11 #include "cc/input/top_controls_manager_client.h"
12 #include "cc/layers/layer_impl.h"
13 #include "cc/test/fake_impl_proxy.h"
14 #include "cc/test/fake_layer_tree_host_impl.h"
15 #include "cc/test/test_shared_bitmap_manager.h"
16 #include "cc/trees/layer_tree_impl.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "ui/gfx/frame_time.h"
19 #include "ui/gfx/geometry/vector2d_f.h"
24 class MockTopControlsManagerClient
: public TopControlsManagerClient
{
26 MockTopControlsManagerClient(float top_controls_height
,
27 float top_controls_show_threshold
,
28 float top_controls_hide_threshold
)
29 : host_impl_(&proxy_
, &shared_bitmap_manager_
),
30 redraw_needed_(false),
31 update_draw_properties_needed_(false),
32 top_controls_shown_ratio_(1.f
),
33 top_controls_height_(top_controls_height
),
34 top_controls_show_threshold_(top_controls_show_threshold
),
35 top_controls_hide_threshold_(top_controls_hide_threshold
) {
36 active_tree_
= LayerTreeImpl::create(
37 &host_impl_
, new SyncedProperty
<ScaleGroup
>, new SyncedTopControls
,
38 new SyncedElasticOverscroll
);
39 root_scroll_layer_
= LayerImpl::Create(active_tree_
.get(), 1);
42 ~MockTopControlsManagerClient() override
{}
44 void DidChangeTopControlsPosition() override
{
45 redraw_needed_
= true;
46 update_draw_properties_needed_
= true;
49 bool HaveRootScrollLayer() const override
{ return true; }
51 float TopControlsHeight() const override
{ return top_controls_height_
; }
53 void SetCurrentTopControlsShownRatio(float ratio
) override
{
54 ratio
= std::max(ratio
, 0.f
);
55 ratio
= std::min(ratio
, 1.f
);
56 top_controls_shown_ratio_
= ratio
;
59 float CurrentTopControlsShownRatio() const override
{
60 return top_controls_shown_ratio_
;
63 LayerImpl
* rootScrollLayer() {
64 return root_scroll_layer_
.get();
67 TopControlsManager
* manager() {
69 manager_
= TopControlsManager::Create(this,
70 top_controls_show_threshold_
,
71 top_controls_hide_threshold_
);
73 return manager_
.get();
76 void SetTopControlsHeight(float height
) { top_controls_height_
= height
; }
80 TestSharedBitmapManager shared_bitmap_manager_
;
81 FakeLayerTreeHostImpl host_impl_
;
82 scoped_ptr
<LayerTreeImpl
> active_tree_
;
83 scoped_ptr
<LayerImpl
> root_scroll_layer_
;
84 scoped_ptr
<TopControlsManager
> manager_
;
86 bool update_draw_properties_needed_
;
88 float top_controls_shown_ratio_
;
89 float top_controls_height_
;
90 float top_controls_show_threshold_
;
91 float top_controls_hide_threshold_
;
94 TEST(TopControlsManagerTest
, EnsureScrollThresholdApplied
) {
95 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
96 TopControlsManager
* manager
= client
.manager();
98 manager
->ScrollBegin();
100 // Scroll down to hide the controls entirely.
101 manager
->ScrollBy(gfx::Vector2dF(0.f
, 30.f
));
102 EXPECT_FLOAT_EQ(-30.f
, manager
->ControlsTopOffset());
104 manager
->ScrollBy(gfx::Vector2dF(0.f
, 30.f
));
105 EXPECT_FLOAT_EQ(-60.f
, manager
->ControlsTopOffset());
107 manager
->ScrollBy(gfx::Vector2dF(0.f
, 100.f
));
108 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
110 // Scroll back up a bit and ensure the controls don't move until we cross
112 manager
->ScrollBy(gfx::Vector2dF(0.f
, -10.f
));
113 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
115 manager
->ScrollBy(gfx::Vector2dF(0.f
, -50.f
));
116 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
118 // After hitting the threshold, further scrolling up should result in the top
120 manager
->ScrollBy(gfx::Vector2dF(0.f
, -10.f
));
121 EXPECT_FLOAT_EQ(-90.f
, manager
->ControlsTopOffset());
123 manager
->ScrollBy(gfx::Vector2dF(0.f
, -50.f
));
124 EXPECT_FLOAT_EQ(-40.f
, manager
->ControlsTopOffset());
126 // Reset the scroll threshold by going further up the page than the initial
128 manager
->ScrollBy(gfx::Vector2dF(0.f
, -100.f
));
129 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
131 // See that scrolling down the page now will result in the controls hiding.
132 manager
->ScrollBy(gfx::Vector2dF(0.f
, 20.f
));
133 EXPECT_FLOAT_EQ(-20.f
, manager
->ControlsTopOffset());
135 manager
->ScrollEnd();
138 TEST(TopControlsManagerTest
, PartialShownHideAnimation
) {
139 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
140 TopControlsManager
* manager
= client
.manager();
141 manager
->ScrollBegin();
142 manager
->ScrollBy(gfx::Vector2dF(0.f
, 300.f
));
143 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
144 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
145 manager
->ScrollEnd();
147 manager
->ScrollBegin();
148 manager
->ScrollBy(gfx::Vector2dF(0.f
, -15.f
));
149 EXPECT_FLOAT_EQ(-85.f
, manager
->ControlsTopOffset());
150 EXPECT_FLOAT_EQ(15.f
, manager
->ContentTopOffset());
151 manager
->ScrollEnd();
153 EXPECT_TRUE(manager
->animation());
155 base::TimeTicks time
= gfx::FrameTime::Now();
157 while (manager
->animation()) {
158 previous
= manager
->TopControlsShownRatio();
159 time
= base::TimeDelta::FromMicroseconds(100) + time
;
160 manager
->Animate(time
);
161 EXPECT_LT(manager
->TopControlsShownRatio(), previous
);
163 EXPECT_FALSE(manager
->animation());
164 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
165 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
168 TEST(TopControlsManagerTest
, PartialShownShowAnimation
) {
169 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
170 TopControlsManager
* manager
= client
.manager();
171 manager
->ScrollBegin();
172 manager
->ScrollBy(gfx::Vector2dF(0.f
, 300.f
));
173 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
174 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
175 manager
->ScrollEnd();
177 manager
->ScrollBegin();
178 manager
->ScrollBy(gfx::Vector2dF(0.f
, -70.f
));
179 EXPECT_FLOAT_EQ(-30.f
, manager
->ControlsTopOffset());
180 EXPECT_FLOAT_EQ(70.f
, manager
->ContentTopOffset());
181 manager
->ScrollEnd();
183 EXPECT_TRUE(manager
->animation());
185 base::TimeTicks time
= gfx::FrameTime::Now();
187 while (manager
->animation()) {
188 previous
= manager
->TopControlsShownRatio();
189 time
= base::TimeDelta::FromMicroseconds(100) + time
;
190 manager
->Animate(time
);
191 EXPECT_GT(manager
->TopControlsShownRatio(), previous
);
193 EXPECT_FALSE(manager
->animation());
194 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
195 EXPECT_FLOAT_EQ(100.f
, manager
->ContentTopOffset());
198 TEST(TopControlsManagerTest
, PartialHiddenWithAmbiguousThresholdShows
) {
199 MockTopControlsManagerClient
client(100.f
, 0.25f
, 0.25f
);
200 TopControlsManager
* manager
= client
.manager();
202 manager
->ScrollBegin();
204 manager
->ScrollBy(gfx::Vector2dF(0.f
, 20.f
));
205 EXPECT_FLOAT_EQ(-20.f
, manager
->ControlsTopOffset());
206 EXPECT_FLOAT_EQ(80.f
, manager
->ContentTopOffset());
208 manager
->ScrollEnd();
209 EXPECT_TRUE(manager
->animation());
211 base::TimeTicks time
= gfx::FrameTime::Now();
213 while (manager
->animation()) {
214 previous
= manager
->TopControlsShownRatio();
215 time
= base::TimeDelta::FromMicroseconds(100) + time
;
216 manager
->Animate(time
);
217 EXPECT_GT(manager
->TopControlsShownRatio(), previous
);
219 EXPECT_FALSE(manager
->animation());
220 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
221 EXPECT_FLOAT_EQ(100.f
, manager
->ContentTopOffset());
224 TEST(TopControlsManagerTest
, PartialHiddenWithAmbiguousThresholdHides
) {
225 MockTopControlsManagerClient
client(100.f
, 0.25f
, 0.25f
);
226 TopControlsManager
* manager
= client
.manager();
228 manager
->ScrollBegin();
230 manager
->ScrollBy(gfx::Vector2dF(0.f
, 30.f
));
231 EXPECT_FLOAT_EQ(-30.f
, manager
->ControlsTopOffset());
232 EXPECT_FLOAT_EQ(70.f
, manager
->ContentTopOffset());
234 manager
->ScrollEnd();
235 EXPECT_TRUE(manager
->animation());
237 base::TimeTicks time
= gfx::FrameTime::Now();
239 while (manager
->animation()) {
240 previous
= manager
->TopControlsShownRatio();
241 time
= base::TimeDelta::FromMicroseconds(100) + time
;
242 manager
->Animate(time
);
243 EXPECT_LT(manager
->TopControlsShownRatio(), previous
);
245 EXPECT_FALSE(manager
->animation());
246 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
247 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
250 TEST(TopControlsManagerTest
, PartialShownWithAmbiguousThresholdHides
) {
251 MockTopControlsManagerClient
client(100.f
, 0.25f
, 0.25f
);
252 TopControlsManager
* manager
= client
.manager();
254 manager
->ScrollBy(gfx::Vector2dF(0.f
, 200.f
));
255 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
256 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
258 manager
->ScrollBegin();
260 manager
->ScrollBy(gfx::Vector2dF(0.f
, -20.f
));
261 EXPECT_FLOAT_EQ(-80.f
, manager
->ControlsTopOffset());
262 EXPECT_FLOAT_EQ(20.f
, manager
->ContentTopOffset());
264 manager
->ScrollEnd();
265 EXPECT_TRUE(manager
->animation());
267 base::TimeTicks time
= gfx::FrameTime::Now();
269 while (manager
->animation()) {
270 previous
= manager
->TopControlsShownRatio();
271 time
= base::TimeDelta::FromMicroseconds(100) + time
;
272 manager
->Animate(time
);
273 EXPECT_LT(manager
->TopControlsShownRatio(), previous
);
275 EXPECT_FALSE(manager
->animation());
276 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
277 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
280 TEST(TopControlsManagerTest
, PartialShownWithAmbiguousThresholdShows
) {
281 MockTopControlsManagerClient
client(100.f
, 0.25f
, 0.25f
);
282 TopControlsManager
* manager
= client
.manager();
284 manager
->ScrollBy(gfx::Vector2dF(0.f
, 200.f
));
285 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
286 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
288 manager
->ScrollBegin();
290 manager
->ScrollBy(gfx::Vector2dF(0.f
, -30.f
));
291 EXPECT_FLOAT_EQ(-70.f
, manager
->ControlsTopOffset());
292 EXPECT_FLOAT_EQ(30.f
, manager
->ContentTopOffset());
294 manager
->ScrollEnd();
295 EXPECT_TRUE(manager
->animation());
297 base::TimeTicks time
= gfx::FrameTime::Now();
299 while (manager
->animation()) {
300 previous
= manager
->TopControlsShownRatio();
301 time
= base::TimeDelta::FromMicroseconds(100) + time
;
302 manager
->Animate(time
);
303 EXPECT_GT(manager
->TopControlsShownRatio(), previous
);
305 EXPECT_FALSE(manager
->animation());
306 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
307 EXPECT_FLOAT_EQ(100.f
, manager
->ContentTopOffset());
310 TEST(TopControlsManagerTest
, PinchIgnoresScroll
) {
311 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
312 TopControlsManager
* manager
= client
.manager();
314 // Hide the controls.
315 manager
->ScrollBegin();
316 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
318 manager
->ScrollBy(gfx::Vector2dF(0.f
, 300.f
));
319 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
321 manager
->PinchBegin();
322 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
324 // Scrolls are ignored during pinch.
325 manager
->ScrollBy(gfx::Vector2dF(0.f
, -15.f
));
326 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
328 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
330 // Scrolls should no long be ignored.
331 manager
->ScrollBy(gfx::Vector2dF(0.f
, -15.f
));
332 EXPECT_FLOAT_EQ(-85.f
, manager
->ControlsTopOffset());
333 EXPECT_FLOAT_EQ(15.f
, manager
->ContentTopOffset());
334 manager
->ScrollEnd();
336 EXPECT_TRUE(manager
->animation());
339 TEST(TopControlsManagerTest
, PinchBeginStartsAnimationIfNecessary
) {
340 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
341 TopControlsManager
* manager
= client
.manager();
343 manager
->ScrollBegin();
344 manager
->ScrollBy(gfx::Vector2dF(0.f
, 300.f
));
345 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
347 manager
->PinchBegin();
348 EXPECT_FALSE(manager
->animation());
351 EXPECT_FALSE(manager
->animation());
353 manager
->ScrollBy(gfx::Vector2dF(0.f
, -15.f
));
354 EXPECT_FLOAT_EQ(-85.f
, manager
->ControlsTopOffset());
355 EXPECT_FLOAT_EQ(15.f
, manager
->ContentTopOffset());
357 manager
->PinchBegin();
358 EXPECT_TRUE(manager
->animation());
360 base::TimeTicks time
= base::TimeTicks::Now();
362 while (manager
->animation()) {
363 previous
= manager
->TopControlsShownRatio();
364 time
= base::TimeDelta::FromMicroseconds(100) + time
;
365 manager
->Animate(time
);
366 EXPECT_LT(manager
->TopControlsShownRatio(), previous
);
368 EXPECT_FALSE(manager
->animation());
371 EXPECT_FALSE(manager
->animation());
373 manager
->ScrollBy(gfx::Vector2dF(0.f
, -55.f
));
374 EXPECT_FLOAT_EQ(-45.f
, manager
->ControlsTopOffset());
375 EXPECT_FLOAT_EQ(55.f
, manager
->ContentTopOffset());
376 EXPECT_FALSE(manager
->animation());
378 manager
->ScrollEnd();
379 EXPECT_TRUE(manager
->animation());
381 time
= base::TimeTicks::Now();
382 while (manager
->animation()) {
383 previous
= manager
->TopControlsShownRatio();
384 time
= base::TimeDelta::FromMicroseconds(100) + time
;
385 manager
->Animate(time
);
386 EXPECT_GT(manager
->TopControlsShownRatio(), previous
);
388 EXPECT_FALSE(manager
->animation());
389 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
392 TEST(TopControlsManagerTest
, HeightChangeMaintainsFullyVisibleControls
) {
393 MockTopControlsManagerClient
client(0.f
, 0.5f
, 0.5f
);
394 TopControlsManager
* manager
= client
.manager();
396 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
398 client
.SetTopControlsHeight(100.f
);
399 EXPECT_FALSE(manager
->animation());
400 EXPECT_FLOAT_EQ(100.f
, manager
->TopControlsHeight());
401 EXPECT_FLOAT_EQ(0, manager
->ControlsTopOffset());
403 client
.SetTopControlsHeight(50.f
);
404 EXPECT_FALSE(manager
->animation());
405 EXPECT_FLOAT_EQ(50.f
, manager
->TopControlsHeight());
406 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
409 TEST(TopControlsManagerTest
, GrowingHeightKeepsTopControlsHidden
) {
410 MockTopControlsManagerClient
client(0.f
, 0.5f
, 0.5f
);
411 TopControlsManager
* manager
= client
.manager();
412 manager
->UpdateTopControlsState(HIDDEN
, HIDDEN
, false);
413 EXPECT_EQ(0.f
, manager
->ControlsTopOffset());
414 EXPECT_EQ(0.f
, manager
->ContentTopOffset());
416 client
.SetTopControlsHeight(50.f
);
417 EXPECT_FALSE(manager
->animation());
418 EXPECT_EQ(-50.f
, manager
->ControlsTopOffset());
419 EXPECT_EQ(0.f
, manager
->ContentTopOffset());
421 client
.SetTopControlsHeight(100.f
);
422 EXPECT_FALSE(manager
->animation());
423 EXPECT_EQ(-100.f
, manager
->ControlsTopOffset());
424 EXPECT_EQ(0.f
, manager
->ContentTopOffset());
427 TEST(TopControlsManagerTest
, ShrinkingHeightKeepsTopControlsHidden
) {
428 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
429 TopControlsManager
* manager
= client
.manager();
431 manager
->ScrollBegin();
432 manager
->ScrollBy(gfx::Vector2dF(0.f
, 300.f
));
433 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
434 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
435 manager
->ScrollEnd();
437 client
.SetTopControlsHeight(50.f
);
438 EXPECT_FALSE(manager
->animation());
439 EXPECT_FLOAT_EQ(-50.f
, manager
->ControlsTopOffset());
440 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
442 client
.SetTopControlsHeight(0.f
);
443 EXPECT_FALSE(manager
->animation());
444 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
445 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());