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"
10 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/time/time.h"
13 #include "cc/input/top_controls_manager_client.h"
14 #include "cc/layers/layer_impl.h"
15 #include "cc/test/fake_impl_proxy.h"
16 #include "cc/test/fake_layer_tree_host_impl.h"
17 #include "cc/test/test_shared_bitmap_manager.h"
18 #include "cc/test/test_task_graph_runner.h"
19 #include "cc/trees/layer_tree_impl.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "ui/gfx/frame_time.h"
22 #include "ui/gfx/geometry/vector2d_f.h"
27 class MockTopControlsManagerClient
: public TopControlsManagerClient
{
29 MockTopControlsManagerClient(float top_controls_height
,
30 float top_controls_show_threshold
,
31 float top_controls_hide_threshold
)
32 : host_impl_(&proxy_
, &shared_bitmap_manager_
, &task_graph_runner_
),
33 redraw_needed_(false),
34 update_draw_properties_needed_(false),
35 top_controls_shown_ratio_(1.f
),
36 top_controls_height_(top_controls_height
),
37 top_controls_show_threshold_(top_controls_show_threshold
),
38 top_controls_hide_threshold_(top_controls_hide_threshold
) {
39 active_tree_
= LayerTreeImpl::create(
40 &host_impl_
, new SyncedProperty
<ScaleGroup
>, new SyncedTopControls
,
41 new SyncedElasticOverscroll
);
42 root_scroll_layer_
= LayerImpl::Create(active_tree_
.get(), 1);
45 ~MockTopControlsManagerClient() override
{}
47 void DidChangeTopControlsPosition() override
{
48 redraw_needed_
= true;
49 update_draw_properties_needed_
= true;
52 bool HaveRootScrollLayer() const override
{ return true; }
54 float TopControlsHeight() const override
{ return top_controls_height_
; }
56 void SetCurrentTopControlsShownRatio(float ratio
) override
{
57 ASSERT_FALSE(std::isnan(ratio
));
58 ASSERT_FALSE(ratio
== std::numeric_limits
<float>::infinity());
59 ASSERT_FALSE(ratio
== -std::numeric_limits
<float>::infinity());
60 ratio
= std::max(ratio
, 0.f
);
61 ratio
= std::min(ratio
, 1.f
);
62 top_controls_shown_ratio_
= ratio
;
65 float CurrentTopControlsShownRatio() const override
{
66 return top_controls_shown_ratio_
;
69 LayerImpl
* rootScrollLayer() {
70 return root_scroll_layer_
.get();
73 TopControlsManager
* manager() {
75 manager_
= TopControlsManager::Create(this,
76 top_controls_show_threshold_
,
77 top_controls_hide_threshold_
);
79 return manager_
.get();
82 void SetTopControlsHeight(float height
) { top_controls_height_
= height
; }
86 TestSharedBitmapManager shared_bitmap_manager_
;
87 TestTaskGraphRunner task_graph_runner_
;
88 FakeLayerTreeHostImpl host_impl_
;
89 scoped_ptr
<LayerTreeImpl
> active_tree_
;
90 scoped_ptr
<LayerImpl
> root_scroll_layer_
;
91 scoped_ptr
<TopControlsManager
> manager_
;
93 bool update_draw_properties_needed_
;
95 float top_controls_shown_ratio_
;
96 float top_controls_height_
;
97 float top_controls_show_threshold_
;
98 float top_controls_hide_threshold_
;
101 TEST(TopControlsManagerTest
, EnsureScrollThresholdApplied
) {
102 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
103 TopControlsManager
* manager
= client
.manager();
105 manager
->ScrollBegin();
107 // Scroll down to hide the controls entirely.
108 manager
->ScrollBy(gfx::Vector2dF(0.f
, 30.f
));
109 EXPECT_FLOAT_EQ(-30.f
, manager
->ControlsTopOffset());
111 manager
->ScrollBy(gfx::Vector2dF(0.f
, 30.f
));
112 EXPECT_FLOAT_EQ(-60.f
, manager
->ControlsTopOffset());
114 manager
->ScrollBy(gfx::Vector2dF(0.f
, 100.f
));
115 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
117 // Scroll back up a bit and ensure the controls don't move until we cross
119 manager
->ScrollBy(gfx::Vector2dF(0.f
, -10.f
));
120 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
122 manager
->ScrollBy(gfx::Vector2dF(0.f
, -50.f
));
123 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
125 // After hitting the threshold, further scrolling up should result in the top
127 manager
->ScrollBy(gfx::Vector2dF(0.f
, -10.f
));
128 EXPECT_FLOAT_EQ(-90.f
, manager
->ControlsTopOffset());
130 manager
->ScrollBy(gfx::Vector2dF(0.f
, -50.f
));
131 EXPECT_FLOAT_EQ(-40.f
, manager
->ControlsTopOffset());
133 // Reset the scroll threshold by going further up the page than the initial
135 manager
->ScrollBy(gfx::Vector2dF(0.f
, -100.f
));
136 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
138 // See that scrolling down the page now will result in the controls hiding.
139 manager
->ScrollBy(gfx::Vector2dF(0.f
, 20.f
));
140 EXPECT_FLOAT_EQ(-20.f
, manager
->ControlsTopOffset());
142 manager
->ScrollEnd();
145 TEST(TopControlsManagerTest
, PartialShownHideAnimation
) {
146 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
147 TopControlsManager
* manager
= client
.manager();
148 manager
->ScrollBegin();
149 manager
->ScrollBy(gfx::Vector2dF(0.f
, 300.f
));
150 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
151 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
152 manager
->ScrollEnd();
154 manager
->ScrollBegin();
155 manager
->ScrollBy(gfx::Vector2dF(0.f
, -15.f
));
156 EXPECT_FLOAT_EQ(-85.f
, manager
->ControlsTopOffset());
157 EXPECT_FLOAT_EQ(15.f
, manager
->ContentTopOffset());
158 manager
->ScrollEnd();
160 EXPECT_TRUE(manager
->animation());
162 base::TimeTicks time
= gfx::FrameTime::Now();
164 while (manager
->animation()) {
165 previous
= manager
->TopControlsShownRatio();
166 time
= base::TimeDelta::FromMicroseconds(100) + time
;
167 manager
->Animate(time
);
168 EXPECT_LT(manager
->TopControlsShownRatio(), previous
);
170 EXPECT_FALSE(manager
->animation());
171 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
172 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
175 TEST(TopControlsManagerTest
, PartialShownShowAnimation
) {
176 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
177 TopControlsManager
* manager
= client
.manager();
178 manager
->ScrollBegin();
179 manager
->ScrollBy(gfx::Vector2dF(0.f
, 300.f
));
180 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
181 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
182 manager
->ScrollEnd();
184 manager
->ScrollBegin();
185 manager
->ScrollBy(gfx::Vector2dF(0.f
, -70.f
));
186 EXPECT_FLOAT_EQ(-30.f
, manager
->ControlsTopOffset());
187 EXPECT_FLOAT_EQ(70.f
, manager
->ContentTopOffset());
188 manager
->ScrollEnd();
190 EXPECT_TRUE(manager
->animation());
192 base::TimeTicks time
= gfx::FrameTime::Now();
194 while (manager
->animation()) {
195 previous
= manager
->TopControlsShownRatio();
196 time
= base::TimeDelta::FromMicroseconds(100) + time
;
197 manager
->Animate(time
);
198 EXPECT_GT(manager
->TopControlsShownRatio(), previous
);
200 EXPECT_FALSE(manager
->animation());
201 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
202 EXPECT_FLOAT_EQ(100.f
, manager
->ContentTopOffset());
205 TEST(TopControlsManagerTest
, PartialHiddenWithAmbiguousThresholdShows
) {
206 MockTopControlsManagerClient
client(100.f
, 0.25f
, 0.25f
);
207 TopControlsManager
* manager
= client
.manager();
209 manager
->ScrollBegin();
211 manager
->ScrollBy(gfx::Vector2dF(0.f
, 20.f
));
212 EXPECT_FLOAT_EQ(-20.f
, manager
->ControlsTopOffset());
213 EXPECT_FLOAT_EQ(80.f
, manager
->ContentTopOffset());
215 manager
->ScrollEnd();
216 EXPECT_TRUE(manager
->animation());
218 base::TimeTicks time
= gfx::FrameTime::Now();
220 while (manager
->animation()) {
221 previous
= manager
->TopControlsShownRatio();
222 time
= base::TimeDelta::FromMicroseconds(100) + time
;
223 manager
->Animate(time
);
224 EXPECT_GT(manager
->TopControlsShownRatio(), previous
);
226 EXPECT_FALSE(manager
->animation());
227 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
228 EXPECT_FLOAT_EQ(100.f
, manager
->ContentTopOffset());
231 TEST(TopControlsManagerTest
, PartialHiddenWithAmbiguousThresholdHides
) {
232 MockTopControlsManagerClient
client(100.f
, 0.25f
, 0.25f
);
233 TopControlsManager
* manager
= client
.manager();
235 manager
->ScrollBegin();
237 manager
->ScrollBy(gfx::Vector2dF(0.f
, 30.f
));
238 EXPECT_FLOAT_EQ(-30.f
, manager
->ControlsTopOffset());
239 EXPECT_FLOAT_EQ(70.f
, manager
->ContentTopOffset());
241 manager
->ScrollEnd();
242 EXPECT_TRUE(manager
->animation());
244 base::TimeTicks time
= gfx::FrameTime::Now();
246 while (manager
->animation()) {
247 previous
= manager
->TopControlsShownRatio();
248 time
= base::TimeDelta::FromMicroseconds(100) + time
;
249 manager
->Animate(time
);
250 EXPECT_LT(manager
->TopControlsShownRatio(), previous
);
252 EXPECT_FALSE(manager
->animation());
253 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
254 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
257 TEST(TopControlsManagerTest
, PartialShownWithAmbiguousThresholdHides
) {
258 MockTopControlsManagerClient
client(100.f
, 0.25f
, 0.25f
);
259 TopControlsManager
* manager
= client
.manager();
261 manager
->ScrollBy(gfx::Vector2dF(0.f
, 200.f
));
262 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
263 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
265 manager
->ScrollBegin();
267 manager
->ScrollBy(gfx::Vector2dF(0.f
, -20.f
));
268 EXPECT_FLOAT_EQ(-80.f
, manager
->ControlsTopOffset());
269 EXPECT_FLOAT_EQ(20.f
, manager
->ContentTopOffset());
271 manager
->ScrollEnd();
272 EXPECT_TRUE(manager
->animation());
274 base::TimeTicks time
= gfx::FrameTime::Now();
276 while (manager
->animation()) {
277 previous
= manager
->TopControlsShownRatio();
278 time
= base::TimeDelta::FromMicroseconds(100) + time
;
279 manager
->Animate(time
);
280 EXPECT_LT(manager
->TopControlsShownRatio(), previous
);
282 EXPECT_FALSE(manager
->animation());
283 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
284 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
287 TEST(TopControlsManagerTest
, PartialShownWithAmbiguousThresholdShows
) {
288 MockTopControlsManagerClient
client(100.f
, 0.25f
, 0.25f
);
289 TopControlsManager
* manager
= client
.manager();
291 manager
->ScrollBy(gfx::Vector2dF(0.f
, 200.f
));
292 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
293 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
295 manager
->ScrollBegin();
297 manager
->ScrollBy(gfx::Vector2dF(0.f
, -30.f
));
298 EXPECT_FLOAT_EQ(-70.f
, manager
->ControlsTopOffset());
299 EXPECT_FLOAT_EQ(30.f
, manager
->ContentTopOffset());
301 manager
->ScrollEnd();
302 EXPECT_TRUE(manager
->animation());
304 base::TimeTicks time
= gfx::FrameTime::Now();
306 while (manager
->animation()) {
307 previous
= manager
->TopControlsShownRatio();
308 time
= base::TimeDelta::FromMicroseconds(100) + time
;
309 manager
->Animate(time
);
310 EXPECT_GT(manager
->TopControlsShownRatio(), previous
);
312 EXPECT_FALSE(manager
->animation());
313 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
314 EXPECT_FLOAT_EQ(100.f
, manager
->ContentTopOffset());
317 TEST(TopControlsManagerTest
, PinchIgnoresScroll
) {
318 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
319 TopControlsManager
* manager
= client
.manager();
321 // Hide the controls.
322 manager
->ScrollBegin();
323 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
325 manager
->ScrollBy(gfx::Vector2dF(0.f
, 300.f
));
326 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
328 manager
->PinchBegin();
329 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
331 // Scrolls are ignored during pinch.
332 manager
->ScrollBy(gfx::Vector2dF(0.f
, -15.f
));
333 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
335 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
337 // Scrolls should no long be ignored.
338 manager
->ScrollBy(gfx::Vector2dF(0.f
, -15.f
));
339 EXPECT_FLOAT_EQ(-85.f
, manager
->ControlsTopOffset());
340 EXPECT_FLOAT_EQ(15.f
, manager
->ContentTopOffset());
341 manager
->ScrollEnd();
343 EXPECT_TRUE(manager
->animation());
346 TEST(TopControlsManagerTest
, PinchBeginStartsAnimationIfNecessary
) {
347 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
348 TopControlsManager
* manager
= client
.manager();
350 manager
->ScrollBegin();
351 manager
->ScrollBy(gfx::Vector2dF(0.f
, 300.f
));
352 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
354 manager
->PinchBegin();
355 EXPECT_FALSE(manager
->animation());
358 EXPECT_FALSE(manager
->animation());
360 manager
->ScrollBy(gfx::Vector2dF(0.f
, -15.f
));
361 EXPECT_FLOAT_EQ(-85.f
, manager
->ControlsTopOffset());
362 EXPECT_FLOAT_EQ(15.f
, manager
->ContentTopOffset());
364 manager
->PinchBegin();
365 EXPECT_TRUE(manager
->animation());
367 base::TimeTicks time
= base::TimeTicks::Now();
369 while (manager
->animation()) {
370 previous
= manager
->TopControlsShownRatio();
371 time
= base::TimeDelta::FromMicroseconds(100) + time
;
372 manager
->Animate(time
);
373 EXPECT_LT(manager
->TopControlsShownRatio(), previous
);
375 EXPECT_FALSE(manager
->animation());
378 EXPECT_FALSE(manager
->animation());
380 manager
->ScrollBy(gfx::Vector2dF(0.f
, -55.f
));
381 EXPECT_FLOAT_EQ(-45.f
, manager
->ControlsTopOffset());
382 EXPECT_FLOAT_EQ(55.f
, manager
->ContentTopOffset());
383 EXPECT_FALSE(manager
->animation());
385 manager
->ScrollEnd();
386 EXPECT_TRUE(manager
->animation());
388 time
= base::TimeTicks::Now();
389 while (manager
->animation()) {
390 previous
= manager
->TopControlsShownRatio();
391 time
= base::TimeDelta::FromMicroseconds(100) + time
;
392 manager
->Animate(time
);
393 EXPECT_GT(manager
->TopControlsShownRatio(), previous
);
395 EXPECT_FALSE(manager
->animation());
396 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
399 TEST(TopControlsManagerTest
, HeightChangeMaintainsFullyVisibleControls
) {
400 MockTopControlsManagerClient
client(0.f
, 0.5f
, 0.5f
);
401 TopControlsManager
* manager
= client
.manager();
403 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
405 client
.SetTopControlsHeight(100.f
);
406 EXPECT_FALSE(manager
->animation());
407 EXPECT_FLOAT_EQ(100.f
, manager
->TopControlsHeight());
408 EXPECT_FLOAT_EQ(0, manager
->ControlsTopOffset());
410 client
.SetTopControlsHeight(50.f
);
411 EXPECT_FALSE(manager
->animation());
412 EXPECT_FLOAT_EQ(50.f
, manager
->TopControlsHeight());
413 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
416 TEST(TopControlsManagerTest
, GrowingHeightKeepsTopControlsHidden
) {
417 MockTopControlsManagerClient
client(0.f
, 0.5f
, 0.5f
);
418 TopControlsManager
* manager
= client
.manager();
419 client
.SetTopControlsHeight(1.f
);
420 manager
->UpdateTopControlsState(HIDDEN
, HIDDEN
, false);
421 EXPECT_EQ(-1.f
, manager
->ControlsTopOffset());
422 EXPECT_EQ(0.f
, manager
->ContentTopOffset());
424 client
.SetTopControlsHeight(50.f
);
425 EXPECT_FALSE(manager
->animation());
426 EXPECT_EQ(-50.f
, manager
->ControlsTopOffset());
427 EXPECT_EQ(0.f
, manager
->ContentTopOffset());
429 client
.SetTopControlsHeight(100.f
);
430 EXPECT_FALSE(manager
->animation());
431 EXPECT_EQ(-100.f
, manager
->ControlsTopOffset());
432 EXPECT_EQ(0.f
, manager
->ContentTopOffset());
435 TEST(TopControlsManagerTest
, ShrinkingHeightKeepsTopControlsHidden
) {
436 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
437 TopControlsManager
* manager
= client
.manager();
439 manager
->ScrollBegin();
440 manager
->ScrollBy(gfx::Vector2dF(0.f
, 300.f
));
441 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
442 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
443 manager
->ScrollEnd();
445 client
.SetTopControlsHeight(50.f
);
446 EXPECT_FALSE(manager
->animation());
447 EXPECT_FLOAT_EQ(-50.f
, manager
->ControlsTopOffset());
448 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
450 client
.SetTopControlsHeight(0.f
);
451 EXPECT_FALSE(manager
->animation());
452 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
453 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
456 TEST(TopControlsManagerTest
, ScrollByWithZeroHeightControlsIsNoop
) {
457 MockTopControlsManagerClient
client(0.f
, 0.5f
, 0.5f
);
458 TopControlsManager
* manager
= client
.manager();
459 manager
->UpdateTopControlsState(BOTH
, BOTH
, false);
461 manager
->ScrollBegin();
462 gfx::Vector2dF pending
= manager
->ScrollBy(gfx::Vector2dF(0.f
, 20.f
));
463 EXPECT_FLOAT_EQ(20.f
, pending
.y());
464 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
465 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
466 EXPECT_FLOAT_EQ(1.f
, client
.CurrentTopControlsShownRatio());
467 manager
->ScrollEnd();