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/trees/layer_tree_impl.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "ui/gfx/frame_time.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_
),
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 FakeLayerTreeHostImpl host_impl_
;
87 scoped_ptr
<LayerTreeImpl
> active_tree_
;
88 scoped_ptr
<LayerImpl
> root_scroll_layer_
;
89 scoped_ptr
<TopControlsManager
> manager_
;
91 bool update_draw_properties_needed_
;
93 float top_controls_shown_ratio_
;
94 float top_controls_height_
;
95 float top_controls_show_threshold_
;
96 float top_controls_hide_threshold_
;
99 TEST(TopControlsManagerTest
, EnsureScrollThresholdApplied
) {
100 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
101 TopControlsManager
* manager
= client
.manager();
103 manager
->ScrollBegin();
105 // Scroll down to hide the controls entirely.
106 manager
->ScrollBy(gfx::Vector2dF(0.f
, 30.f
));
107 EXPECT_FLOAT_EQ(-30.f
, manager
->ControlsTopOffset());
109 manager
->ScrollBy(gfx::Vector2dF(0.f
, 30.f
));
110 EXPECT_FLOAT_EQ(-60.f
, manager
->ControlsTopOffset());
112 manager
->ScrollBy(gfx::Vector2dF(0.f
, 100.f
));
113 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
115 // Scroll back up a bit and ensure the controls don't move until we cross
117 manager
->ScrollBy(gfx::Vector2dF(0.f
, -10.f
));
118 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
120 manager
->ScrollBy(gfx::Vector2dF(0.f
, -50.f
));
121 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
123 // After hitting the threshold, further scrolling up should result in the top
125 manager
->ScrollBy(gfx::Vector2dF(0.f
, -10.f
));
126 EXPECT_FLOAT_EQ(-90.f
, manager
->ControlsTopOffset());
128 manager
->ScrollBy(gfx::Vector2dF(0.f
, -50.f
));
129 EXPECT_FLOAT_EQ(-40.f
, manager
->ControlsTopOffset());
131 // Reset the scroll threshold by going further up the page than the initial
133 manager
->ScrollBy(gfx::Vector2dF(0.f
, -100.f
));
134 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
136 // See that scrolling down the page now will result in the controls hiding.
137 manager
->ScrollBy(gfx::Vector2dF(0.f
, 20.f
));
138 EXPECT_FLOAT_EQ(-20.f
, manager
->ControlsTopOffset());
140 manager
->ScrollEnd();
143 TEST(TopControlsManagerTest
, PartialShownHideAnimation
) {
144 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
145 TopControlsManager
* manager
= client
.manager();
146 manager
->ScrollBegin();
147 manager
->ScrollBy(gfx::Vector2dF(0.f
, 300.f
));
148 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
149 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
150 manager
->ScrollEnd();
152 manager
->ScrollBegin();
153 manager
->ScrollBy(gfx::Vector2dF(0.f
, -15.f
));
154 EXPECT_FLOAT_EQ(-85.f
, manager
->ControlsTopOffset());
155 EXPECT_FLOAT_EQ(15.f
, manager
->ContentTopOffset());
156 manager
->ScrollEnd();
158 EXPECT_TRUE(manager
->animation());
160 base::TimeTicks time
= gfx::FrameTime::Now();
162 while (manager
->animation()) {
163 previous
= manager
->TopControlsShownRatio();
164 time
= base::TimeDelta::FromMicroseconds(100) + time
;
165 manager
->Animate(time
);
166 EXPECT_LT(manager
->TopControlsShownRatio(), previous
);
168 EXPECT_FALSE(manager
->animation());
169 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
170 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
173 TEST(TopControlsManagerTest
, PartialShownShowAnimation
) {
174 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
175 TopControlsManager
* manager
= client
.manager();
176 manager
->ScrollBegin();
177 manager
->ScrollBy(gfx::Vector2dF(0.f
, 300.f
));
178 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
179 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
180 manager
->ScrollEnd();
182 manager
->ScrollBegin();
183 manager
->ScrollBy(gfx::Vector2dF(0.f
, -70.f
));
184 EXPECT_FLOAT_EQ(-30.f
, manager
->ControlsTopOffset());
185 EXPECT_FLOAT_EQ(70.f
, manager
->ContentTopOffset());
186 manager
->ScrollEnd();
188 EXPECT_TRUE(manager
->animation());
190 base::TimeTicks time
= gfx::FrameTime::Now();
192 while (manager
->animation()) {
193 previous
= manager
->TopControlsShownRatio();
194 time
= base::TimeDelta::FromMicroseconds(100) + time
;
195 manager
->Animate(time
);
196 EXPECT_GT(manager
->TopControlsShownRatio(), previous
);
198 EXPECT_FALSE(manager
->animation());
199 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
200 EXPECT_FLOAT_EQ(100.f
, manager
->ContentTopOffset());
203 TEST(TopControlsManagerTest
, PartialHiddenWithAmbiguousThresholdShows
) {
204 MockTopControlsManagerClient
client(100.f
, 0.25f
, 0.25f
);
205 TopControlsManager
* manager
= client
.manager();
207 manager
->ScrollBegin();
209 manager
->ScrollBy(gfx::Vector2dF(0.f
, 20.f
));
210 EXPECT_FLOAT_EQ(-20.f
, manager
->ControlsTopOffset());
211 EXPECT_FLOAT_EQ(80.f
, manager
->ContentTopOffset());
213 manager
->ScrollEnd();
214 EXPECT_TRUE(manager
->animation());
216 base::TimeTicks time
= gfx::FrameTime::Now();
218 while (manager
->animation()) {
219 previous
= manager
->TopControlsShownRatio();
220 time
= base::TimeDelta::FromMicroseconds(100) + time
;
221 manager
->Animate(time
);
222 EXPECT_GT(manager
->TopControlsShownRatio(), previous
);
224 EXPECT_FALSE(manager
->animation());
225 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
226 EXPECT_FLOAT_EQ(100.f
, manager
->ContentTopOffset());
229 TEST(TopControlsManagerTest
, PartialHiddenWithAmbiguousThresholdHides
) {
230 MockTopControlsManagerClient
client(100.f
, 0.25f
, 0.25f
);
231 TopControlsManager
* manager
= client
.manager();
233 manager
->ScrollBegin();
235 manager
->ScrollBy(gfx::Vector2dF(0.f
, 30.f
));
236 EXPECT_FLOAT_EQ(-30.f
, manager
->ControlsTopOffset());
237 EXPECT_FLOAT_EQ(70.f
, manager
->ContentTopOffset());
239 manager
->ScrollEnd();
240 EXPECT_TRUE(manager
->animation());
242 base::TimeTicks time
= gfx::FrameTime::Now();
244 while (manager
->animation()) {
245 previous
= manager
->TopControlsShownRatio();
246 time
= base::TimeDelta::FromMicroseconds(100) + time
;
247 manager
->Animate(time
);
248 EXPECT_LT(manager
->TopControlsShownRatio(), previous
);
250 EXPECT_FALSE(manager
->animation());
251 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
252 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
255 TEST(TopControlsManagerTest
, PartialShownWithAmbiguousThresholdHides
) {
256 MockTopControlsManagerClient
client(100.f
, 0.25f
, 0.25f
);
257 TopControlsManager
* manager
= client
.manager();
259 manager
->ScrollBy(gfx::Vector2dF(0.f
, 200.f
));
260 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
261 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
263 manager
->ScrollBegin();
265 manager
->ScrollBy(gfx::Vector2dF(0.f
, -20.f
));
266 EXPECT_FLOAT_EQ(-80.f
, manager
->ControlsTopOffset());
267 EXPECT_FLOAT_EQ(20.f
, manager
->ContentTopOffset());
269 manager
->ScrollEnd();
270 EXPECT_TRUE(manager
->animation());
272 base::TimeTicks time
= gfx::FrameTime::Now();
274 while (manager
->animation()) {
275 previous
= manager
->TopControlsShownRatio();
276 time
= base::TimeDelta::FromMicroseconds(100) + time
;
277 manager
->Animate(time
);
278 EXPECT_LT(manager
->TopControlsShownRatio(), previous
);
280 EXPECT_FALSE(manager
->animation());
281 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
282 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
285 TEST(TopControlsManagerTest
, PartialShownWithAmbiguousThresholdShows
) {
286 MockTopControlsManagerClient
client(100.f
, 0.25f
, 0.25f
);
287 TopControlsManager
* manager
= client
.manager();
289 manager
->ScrollBy(gfx::Vector2dF(0.f
, 200.f
));
290 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
291 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
293 manager
->ScrollBegin();
295 manager
->ScrollBy(gfx::Vector2dF(0.f
, -30.f
));
296 EXPECT_FLOAT_EQ(-70.f
, manager
->ControlsTopOffset());
297 EXPECT_FLOAT_EQ(30.f
, manager
->ContentTopOffset());
299 manager
->ScrollEnd();
300 EXPECT_TRUE(manager
->animation());
302 base::TimeTicks time
= gfx::FrameTime::Now();
304 while (manager
->animation()) {
305 previous
= manager
->TopControlsShownRatio();
306 time
= base::TimeDelta::FromMicroseconds(100) + time
;
307 manager
->Animate(time
);
308 EXPECT_GT(manager
->TopControlsShownRatio(), previous
);
310 EXPECT_FALSE(manager
->animation());
311 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
312 EXPECT_FLOAT_EQ(100.f
, manager
->ContentTopOffset());
315 TEST(TopControlsManagerTest
, PinchIgnoresScroll
) {
316 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
317 TopControlsManager
* manager
= client
.manager();
319 // Hide the controls.
320 manager
->ScrollBegin();
321 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
323 manager
->ScrollBy(gfx::Vector2dF(0.f
, 300.f
));
324 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
326 manager
->PinchBegin();
327 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
329 // Scrolls are ignored during pinch.
330 manager
->ScrollBy(gfx::Vector2dF(0.f
, -15.f
));
331 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
333 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
335 // Scrolls should no long be ignored.
336 manager
->ScrollBy(gfx::Vector2dF(0.f
, -15.f
));
337 EXPECT_FLOAT_EQ(-85.f
, manager
->ControlsTopOffset());
338 EXPECT_FLOAT_EQ(15.f
, manager
->ContentTopOffset());
339 manager
->ScrollEnd();
341 EXPECT_TRUE(manager
->animation());
344 TEST(TopControlsManagerTest
, PinchBeginStartsAnimationIfNecessary
) {
345 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
346 TopControlsManager
* manager
= client
.manager();
348 manager
->ScrollBegin();
349 manager
->ScrollBy(gfx::Vector2dF(0.f
, 300.f
));
350 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
352 manager
->PinchBegin();
353 EXPECT_FALSE(manager
->animation());
356 EXPECT_FALSE(manager
->animation());
358 manager
->ScrollBy(gfx::Vector2dF(0.f
, -15.f
));
359 EXPECT_FLOAT_EQ(-85.f
, manager
->ControlsTopOffset());
360 EXPECT_FLOAT_EQ(15.f
, manager
->ContentTopOffset());
362 manager
->PinchBegin();
363 EXPECT_TRUE(manager
->animation());
365 base::TimeTicks time
= base::TimeTicks::Now();
367 while (manager
->animation()) {
368 previous
= manager
->TopControlsShownRatio();
369 time
= base::TimeDelta::FromMicroseconds(100) + time
;
370 manager
->Animate(time
);
371 EXPECT_LT(manager
->TopControlsShownRatio(), previous
);
373 EXPECT_FALSE(manager
->animation());
376 EXPECT_FALSE(manager
->animation());
378 manager
->ScrollBy(gfx::Vector2dF(0.f
, -55.f
));
379 EXPECT_FLOAT_EQ(-45.f
, manager
->ControlsTopOffset());
380 EXPECT_FLOAT_EQ(55.f
, manager
->ContentTopOffset());
381 EXPECT_FALSE(manager
->animation());
383 manager
->ScrollEnd();
384 EXPECT_TRUE(manager
->animation());
386 time
= base::TimeTicks::Now();
387 while (manager
->animation()) {
388 previous
= manager
->TopControlsShownRatio();
389 time
= base::TimeDelta::FromMicroseconds(100) + time
;
390 manager
->Animate(time
);
391 EXPECT_GT(manager
->TopControlsShownRatio(), previous
);
393 EXPECT_FALSE(manager
->animation());
394 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
397 TEST(TopControlsManagerTest
, HeightChangeMaintainsFullyVisibleControls
) {
398 MockTopControlsManagerClient
client(0.f
, 0.5f
, 0.5f
);
399 TopControlsManager
* manager
= client
.manager();
401 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
403 client
.SetTopControlsHeight(100.f
);
404 EXPECT_FALSE(manager
->animation());
405 EXPECT_FLOAT_EQ(100.f
, manager
->TopControlsHeight());
406 EXPECT_FLOAT_EQ(0, manager
->ControlsTopOffset());
408 client
.SetTopControlsHeight(50.f
);
409 EXPECT_FALSE(manager
->animation());
410 EXPECT_FLOAT_EQ(50.f
, manager
->TopControlsHeight());
411 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
414 TEST(TopControlsManagerTest
, GrowingHeightKeepsTopControlsHidden
) {
415 MockTopControlsManagerClient
client(0.f
, 0.5f
, 0.5f
);
416 TopControlsManager
* manager
= client
.manager();
417 client
.SetTopControlsHeight(1.f
);
418 manager
->UpdateTopControlsState(HIDDEN
, HIDDEN
, false);
419 EXPECT_EQ(-1.f
, manager
->ControlsTopOffset());
420 EXPECT_EQ(0.f
, manager
->ContentTopOffset());
422 client
.SetTopControlsHeight(50.f
);
423 EXPECT_FALSE(manager
->animation());
424 EXPECT_EQ(-50.f
, manager
->ControlsTopOffset());
425 EXPECT_EQ(0.f
, manager
->ContentTopOffset());
427 client
.SetTopControlsHeight(100.f
);
428 EXPECT_FALSE(manager
->animation());
429 EXPECT_EQ(-100.f
, manager
->ControlsTopOffset());
430 EXPECT_EQ(0.f
, manager
->ContentTopOffset());
433 TEST(TopControlsManagerTest
, ShrinkingHeightKeepsTopControlsHidden
) {
434 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
435 TopControlsManager
* manager
= client
.manager();
437 manager
->ScrollBegin();
438 manager
->ScrollBy(gfx::Vector2dF(0.f
, 300.f
));
439 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
440 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
441 manager
->ScrollEnd();
443 client
.SetTopControlsHeight(50.f
);
444 EXPECT_FALSE(manager
->animation());
445 EXPECT_FLOAT_EQ(-50.f
, manager
->ControlsTopOffset());
446 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
448 client
.SetTopControlsHeight(0.f
);
449 EXPECT_FALSE(manager
->animation());
450 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
451 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
454 TEST(TopControlsManagerTest
, ScrollByWithZeroHeightControlsIsNoop
) {
455 MockTopControlsManagerClient
client(0.f
, 0.5f
, 0.5f
);
456 TopControlsManager
* manager
= client
.manager();
457 manager
->UpdateTopControlsState(BOTH
, BOTH
, false);
459 manager
->ScrollBegin();
460 gfx::Vector2dF pending
= manager
->ScrollBy(gfx::Vector2dF(0.f
, 20.f
));
461 EXPECT_FLOAT_EQ(20.f
, pending
.y());
462 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
463 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
464 EXPECT_FLOAT_EQ(1.f
, client
.CurrentTopControlsShownRatio());
465 manager
->ScrollEnd();