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/geometry/vector2d_f.h"
26 class MockTopControlsManagerClient
: public TopControlsManagerClient
{
28 MockTopControlsManagerClient(float top_controls_height
,
29 float top_controls_show_threshold
,
30 float top_controls_hide_threshold
)
31 : host_impl_(&proxy_
, &shared_bitmap_manager_
, &task_graph_runner_
),
32 redraw_needed_(false),
33 update_draw_properties_needed_(false),
34 top_controls_shown_ratio_(1.f
),
35 top_controls_height_(top_controls_height
),
36 top_controls_show_threshold_(top_controls_show_threshold
),
37 top_controls_hide_threshold_(top_controls_hide_threshold
) {
38 active_tree_
= LayerTreeImpl::create(
39 &host_impl_
, new SyncedProperty
<ScaleGroup
>, new SyncedTopControls
,
40 new SyncedElasticOverscroll
);
41 root_scroll_layer_
= LayerImpl::Create(active_tree_
.get(), 1);
44 ~MockTopControlsManagerClient() override
{}
46 void DidChangeTopControlsPosition() override
{
47 redraw_needed_
= true;
48 update_draw_properties_needed_
= true;
51 bool HaveRootScrollLayer() const override
{ return true; }
53 float TopControlsHeight() const override
{ return top_controls_height_
; }
55 void SetCurrentTopControlsShownRatio(float ratio
) override
{
56 ASSERT_FALSE(std::isnan(ratio
));
57 ASSERT_FALSE(ratio
== std::numeric_limits
<float>::infinity());
58 ASSERT_FALSE(ratio
== -std::numeric_limits
<float>::infinity());
59 ratio
= std::max(ratio
, 0.f
);
60 ratio
= std::min(ratio
, 1.f
);
61 top_controls_shown_ratio_
= ratio
;
64 float CurrentTopControlsShownRatio() const override
{
65 return top_controls_shown_ratio_
;
68 LayerImpl
* rootScrollLayer() {
69 return root_scroll_layer_
.get();
72 TopControlsManager
* manager() {
74 manager_
= TopControlsManager::Create(this,
75 top_controls_show_threshold_
,
76 top_controls_hide_threshold_
);
78 return manager_
.get();
81 void SetTopControlsHeight(float height
) { top_controls_height_
= height
; }
85 TestSharedBitmapManager shared_bitmap_manager_
;
86 TestTaskGraphRunner task_graph_runner_
;
87 FakeLayerTreeHostImpl host_impl_
;
88 scoped_ptr
<LayerTreeImpl
> active_tree_
;
89 scoped_ptr
<LayerImpl
> root_scroll_layer_
;
90 scoped_ptr
<TopControlsManager
> manager_
;
92 bool update_draw_properties_needed_
;
94 float top_controls_shown_ratio_
;
95 float top_controls_height_
;
96 float top_controls_show_threshold_
;
97 float top_controls_hide_threshold_
;
100 TEST(TopControlsManagerTest
, EnsureScrollThresholdApplied
) {
101 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
102 TopControlsManager
* manager
= client
.manager();
104 manager
->ScrollBegin();
106 // Scroll down to hide the controls entirely.
107 manager
->ScrollBy(gfx::Vector2dF(0.f
, 30.f
));
108 EXPECT_FLOAT_EQ(-30.f
, manager
->ControlsTopOffset());
110 manager
->ScrollBy(gfx::Vector2dF(0.f
, 30.f
));
111 EXPECT_FLOAT_EQ(-60.f
, manager
->ControlsTopOffset());
113 manager
->ScrollBy(gfx::Vector2dF(0.f
, 100.f
));
114 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
116 // Scroll back up a bit and ensure the controls don't move until we cross
118 manager
->ScrollBy(gfx::Vector2dF(0.f
, -10.f
));
119 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
121 manager
->ScrollBy(gfx::Vector2dF(0.f
, -50.f
));
122 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
124 // After hitting the threshold, further scrolling up should result in the top
126 manager
->ScrollBy(gfx::Vector2dF(0.f
, -10.f
));
127 EXPECT_FLOAT_EQ(-90.f
, manager
->ControlsTopOffset());
129 manager
->ScrollBy(gfx::Vector2dF(0.f
, -50.f
));
130 EXPECT_FLOAT_EQ(-40.f
, manager
->ControlsTopOffset());
132 // Reset the scroll threshold by going further up the page than the initial
134 manager
->ScrollBy(gfx::Vector2dF(0.f
, -100.f
));
135 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
137 // See that scrolling down the page now will result in the controls hiding.
138 manager
->ScrollBy(gfx::Vector2dF(0.f
, 20.f
));
139 EXPECT_FLOAT_EQ(-20.f
, manager
->ControlsTopOffset());
141 manager
->ScrollEnd();
144 TEST(TopControlsManagerTest
, PartialShownHideAnimation
) {
145 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
146 TopControlsManager
* manager
= client
.manager();
147 manager
->ScrollBegin();
148 manager
->ScrollBy(gfx::Vector2dF(0.f
, 300.f
));
149 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
150 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
151 manager
->ScrollEnd();
153 manager
->ScrollBegin();
154 manager
->ScrollBy(gfx::Vector2dF(0.f
, -15.f
));
155 EXPECT_FLOAT_EQ(-85.f
, manager
->ControlsTopOffset());
156 EXPECT_FLOAT_EQ(15.f
, manager
->ContentTopOffset());
157 manager
->ScrollEnd();
159 EXPECT_TRUE(manager
->animation());
161 base::TimeTicks time
= base::TimeTicks::Now();
163 while (manager
->animation()) {
164 previous
= manager
->TopControlsShownRatio();
165 time
= base::TimeDelta::FromMicroseconds(100) + time
;
166 manager
->Animate(time
);
167 EXPECT_LT(manager
->TopControlsShownRatio(), previous
);
169 EXPECT_FALSE(manager
->animation());
170 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
171 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
174 TEST(TopControlsManagerTest
, PartialShownShowAnimation
) {
175 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
176 TopControlsManager
* manager
= client
.manager();
177 manager
->ScrollBegin();
178 manager
->ScrollBy(gfx::Vector2dF(0.f
, 300.f
));
179 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
180 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
181 manager
->ScrollEnd();
183 manager
->ScrollBegin();
184 manager
->ScrollBy(gfx::Vector2dF(0.f
, -70.f
));
185 EXPECT_FLOAT_EQ(-30.f
, manager
->ControlsTopOffset());
186 EXPECT_FLOAT_EQ(70.f
, manager
->ContentTopOffset());
187 manager
->ScrollEnd();
189 EXPECT_TRUE(manager
->animation());
191 base::TimeTicks time
= base::TimeTicks::Now();
193 while (manager
->animation()) {
194 previous
= manager
->TopControlsShownRatio();
195 time
= base::TimeDelta::FromMicroseconds(100) + time
;
196 manager
->Animate(time
);
197 EXPECT_GT(manager
->TopControlsShownRatio(), previous
);
199 EXPECT_FALSE(manager
->animation());
200 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
201 EXPECT_FLOAT_EQ(100.f
, manager
->ContentTopOffset());
204 TEST(TopControlsManagerTest
, PartialHiddenWithAmbiguousThresholdShows
) {
205 MockTopControlsManagerClient
client(100.f
, 0.25f
, 0.25f
);
206 TopControlsManager
* manager
= client
.manager();
208 manager
->ScrollBegin();
210 manager
->ScrollBy(gfx::Vector2dF(0.f
, 20.f
));
211 EXPECT_FLOAT_EQ(-20.f
, manager
->ControlsTopOffset());
212 EXPECT_FLOAT_EQ(80.f
, manager
->ContentTopOffset());
214 manager
->ScrollEnd();
215 EXPECT_TRUE(manager
->animation());
217 base::TimeTicks time
= base::TimeTicks::Now();
219 while (manager
->animation()) {
220 previous
= manager
->TopControlsShownRatio();
221 time
= base::TimeDelta::FromMicroseconds(100) + time
;
222 manager
->Animate(time
);
223 EXPECT_GT(manager
->TopControlsShownRatio(), previous
);
225 EXPECT_FALSE(manager
->animation());
226 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
227 EXPECT_FLOAT_EQ(100.f
, manager
->ContentTopOffset());
230 TEST(TopControlsManagerTest
, PartialHiddenWithAmbiguousThresholdHides
) {
231 MockTopControlsManagerClient
client(100.f
, 0.25f
, 0.25f
);
232 TopControlsManager
* manager
= client
.manager();
234 manager
->ScrollBegin();
236 manager
->ScrollBy(gfx::Vector2dF(0.f
, 30.f
));
237 EXPECT_FLOAT_EQ(-30.f
, manager
->ControlsTopOffset());
238 EXPECT_FLOAT_EQ(70.f
, manager
->ContentTopOffset());
240 manager
->ScrollEnd();
241 EXPECT_TRUE(manager
->animation());
243 base::TimeTicks time
= base::TimeTicks::Now();
245 while (manager
->animation()) {
246 previous
= manager
->TopControlsShownRatio();
247 time
= base::TimeDelta::FromMicroseconds(100) + time
;
248 manager
->Animate(time
);
249 EXPECT_LT(manager
->TopControlsShownRatio(), previous
);
251 EXPECT_FALSE(manager
->animation());
252 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
253 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
256 TEST(TopControlsManagerTest
, PartialShownWithAmbiguousThresholdHides
) {
257 MockTopControlsManagerClient
client(100.f
, 0.25f
, 0.25f
);
258 TopControlsManager
* manager
= client
.manager();
260 manager
->ScrollBy(gfx::Vector2dF(0.f
, 200.f
));
261 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
262 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
264 manager
->ScrollBegin();
266 manager
->ScrollBy(gfx::Vector2dF(0.f
, -20.f
));
267 EXPECT_FLOAT_EQ(-80.f
, manager
->ControlsTopOffset());
268 EXPECT_FLOAT_EQ(20.f
, manager
->ContentTopOffset());
270 manager
->ScrollEnd();
271 EXPECT_TRUE(manager
->animation());
273 base::TimeTicks time
= base::TimeTicks::Now();
275 while (manager
->animation()) {
276 previous
= manager
->TopControlsShownRatio();
277 time
= base::TimeDelta::FromMicroseconds(100) + time
;
278 manager
->Animate(time
);
279 EXPECT_LT(manager
->TopControlsShownRatio(), previous
);
281 EXPECT_FALSE(manager
->animation());
282 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
283 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
286 TEST(TopControlsManagerTest
, PartialShownWithAmbiguousThresholdShows
) {
287 MockTopControlsManagerClient
client(100.f
, 0.25f
, 0.25f
);
288 TopControlsManager
* manager
= client
.manager();
290 manager
->ScrollBy(gfx::Vector2dF(0.f
, 200.f
));
291 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
292 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
294 manager
->ScrollBegin();
296 manager
->ScrollBy(gfx::Vector2dF(0.f
, -30.f
));
297 EXPECT_FLOAT_EQ(-70.f
, manager
->ControlsTopOffset());
298 EXPECT_FLOAT_EQ(30.f
, manager
->ContentTopOffset());
300 manager
->ScrollEnd();
301 EXPECT_TRUE(manager
->animation());
303 base::TimeTicks time
= base::TimeTicks::Now();
305 while (manager
->animation()) {
306 previous
= manager
->TopControlsShownRatio();
307 time
= base::TimeDelta::FromMicroseconds(100) + time
;
308 manager
->Animate(time
);
309 EXPECT_GT(manager
->TopControlsShownRatio(), previous
);
311 EXPECT_FALSE(manager
->animation());
312 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
313 EXPECT_FLOAT_EQ(100.f
, manager
->ContentTopOffset());
316 TEST(TopControlsManagerTest
, PinchIgnoresScroll
) {
317 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
318 TopControlsManager
* manager
= client
.manager();
320 // Hide the controls.
321 manager
->ScrollBegin();
322 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
324 manager
->ScrollBy(gfx::Vector2dF(0.f
, 300.f
));
325 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
327 manager
->PinchBegin();
328 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
330 // Scrolls are ignored during pinch.
331 manager
->ScrollBy(gfx::Vector2dF(0.f
, -15.f
));
332 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
334 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
336 // Scrolls should no long be ignored.
337 manager
->ScrollBy(gfx::Vector2dF(0.f
, -15.f
));
338 EXPECT_FLOAT_EQ(-85.f
, manager
->ControlsTopOffset());
339 EXPECT_FLOAT_EQ(15.f
, manager
->ContentTopOffset());
340 manager
->ScrollEnd();
342 EXPECT_TRUE(manager
->animation());
345 TEST(TopControlsManagerTest
, PinchBeginStartsAnimationIfNecessary
) {
346 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
347 TopControlsManager
* manager
= client
.manager();
349 manager
->ScrollBegin();
350 manager
->ScrollBy(gfx::Vector2dF(0.f
, 300.f
));
351 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
353 manager
->PinchBegin();
354 EXPECT_FALSE(manager
->animation());
357 EXPECT_FALSE(manager
->animation());
359 manager
->ScrollBy(gfx::Vector2dF(0.f
, -15.f
));
360 EXPECT_FLOAT_EQ(-85.f
, manager
->ControlsTopOffset());
361 EXPECT_FLOAT_EQ(15.f
, manager
->ContentTopOffset());
363 manager
->PinchBegin();
364 EXPECT_TRUE(manager
->animation());
366 base::TimeTicks time
= base::TimeTicks::Now();
368 while (manager
->animation()) {
369 previous
= manager
->TopControlsShownRatio();
370 time
= base::TimeDelta::FromMicroseconds(100) + time
;
371 manager
->Animate(time
);
372 EXPECT_LT(manager
->TopControlsShownRatio(), previous
);
374 EXPECT_FALSE(manager
->animation());
377 EXPECT_FALSE(manager
->animation());
379 manager
->ScrollBy(gfx::Vector2dF(0.f
, -55.f
));
380 EXPECT_FLOAT_EQ(-45.f
, manager
->ControlsTopOffset());
381 EXPECT_FLOAT_EQ(55.f
, manager
->ContentTopOffset());
382 EXPECT_FALSE(manager
->animation());
384 manager
->ScrollEnd();
385 EXPECT_TRUE(manager
->animation());
387 time
= base::TimeTicks::Now();
388 while (manager
->animation()) {
389 previous
= manager
->TopControlsShownRatio();
390 time
= base::TimeDelta::FromMicroseconds(100) + time
;
391 manager
->Animate(time
);
392 EXPECT_GT(manager
->TopControlsShownRatio(), previous
);
394 EXPECT_FALSE(manager
->animation());
395 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
398 TEST(TopControlsManagerTest
, HeightChangeMaintainsFullyVisibleControls
) {
399 MockTopControlsManagerClient
client(0.f
, 0.5f
, 0.5f
);
400 TopControlsManager
* manager
= client
.manager();
402 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
404 client
.SetTopControlsHeight(100.f
);
405 EXPECT_FALSE(manager
->animation());
406 EXPECT_FLOAT_EQ(100.f
, manager
->TopControlsHeight());
407 EXPECT_FLOAT_EQ(0, manager
->ControlsTopOffset());
409 client
.SetTopControlsHeight(50.f
);
410 EXPECT_FALSE(manager
->animation());
411 EXPECT_FLOAT_EQ(50.f
, manager
->TopControlsHeight());
412 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
415 TEST(TopControlsManagerTest
, GrowingHeightKeepsTopControlsHidden
) {
416 MockTopControlsManagerClient
client(0.f
, 0.5f
, 0.5f
);
417 TopControlsManager
* manager
= client
.manager();
418 client
.SetTopControlsHeight(1.f
);
419 manager
->UpdateTopControlsState(HIDDEN
, HIDDEN
, false);
420 EXPECT_EQ(-1.f
, manager
->ControlsTopOffset());
421 EXPECT_EQ(0.f
, manager
->ContentTopOffset());
423 client
.SetTopControlsHeight(50.f
);
424 EXPECT_FALSE(manager
->animation());
425 EXPECT_EQ(-50.f
, manager
->ControlsTopOffset());
426 EXPECT_EQ(0.f
, manager
->ContentTopOffset());
428 client
.SetTopControlsHeight(100.f
);
429 EXPECT_FALSE(manager
->animation());
430 EXPECT_EQ(-100.f
, manager
->ControlsTopOffset());
431 EXPECT_EQ(0.f
, manager
->ContentTopOffset());
434 TEST(TopControlsManagerTest
, ShrinkingHeightKeepsTopControlsHidden
) {
435 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
436 TopControlsManager
* manager
= client
.manager();
438 manager
->ScrollBegin();
439 manager
->ScrollBy(gfx::Vector2dF(0.f
, 300.f
));
440 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
441 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
442 manager
->ScrollEnd();
444 client
.SetTopControlsHeight(50.f
);
445 EXPECT_FALSE(manager
->animation());
446 EXPECT_FLOAT_EQ(-50.f
, manager
->ControlsTopOffset());
447 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
449 client
.SetTopControlsHeight(0.f
);
450 EXPECT_FALSE(manager
->animation());
451 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
452 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
455 TEST(TopControlsManagerTest
, ScrollByWithZeroHeightControlsIsNoop
) {
456 MockTopControlsManagerClient
client(0.f
, 0.5f
, 0.5f
);
457 TopControlsManager
* manager
= client
.manager();
458 manager
->UpdateTopControlsState(BOTH
, BOTH
, false);
460 manager
->ScrollBegin();
461 gfx::Vector2dF pending
= manager
->ScrollBy(gfx::Vector2dF(0.f
, 20.f
));
462 EXPECT_FLOAT_EQ(20.f
, pending
.y());
463 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
464 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
465 EXPECT_FLOAT_EQ(1.f
, client
.CurrentTopControlsShownRatio());
466 manager
->ScrollEnd();