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 // Flaky. See http://crbug.com/456617.
139 TEST(TopControlsManagerTest
, DISABLED_PartialShownHideAnimation
) {
140 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
141 TopControlsManager
* manager
= client
.manager();
142 manager
->ScrollBegin();
143 manager
->ScrollBy(gfx::Vector2dF(0.f
, 300.f
));
144 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
145 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
146 manager
->ScrollEnd();
148 manager
->ScrollBegin();
149 manager
->ScrollBy(gfx::Vector2dF(0.f
, -15.f
));
150 EXPECT_FLOAT_EQ(-85.f
, manager
->ControlsTopOffset());
151 EXPECT_FLOAT_EQ(15.f
, manager
->ContentTopOffset());
152 manager
->ScrollEnd();
154 EXPECT_TRUE(manager
->animation());
156 base::TimeTicks time
= gfx::FrameTime::Now();
157 float previous_offset
= manager
->ControlsTopOffset();
158 while (manager
->animation()) {
159 time
= base::TimeDelta::FromMicroseconds(100) + time
;
160 manager
->Animate(time
);
161 EXPECT_LT(manager
->ControlsTopOffset(), previous_offset
);
162 previous_offset
= manager
->ControlsTopOffset();
164 EXPECT_FALSE(manager
->animation());
165 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
166 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
169 TEST(TopControlsManagerTest
, PartialShownShowAnimation
) {
170 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
171 TopControlsManager
* manager
= client
.manager();
172 manager
->ScrollBegin();
173 manager
->ScrollBy(gfx::Vector2dF(0.f
, 300.f
));
174 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
175 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
176 manager
->ScrollEnd();
178 manager
->ScrollBegin();
179 manager
->ScrollBy(gfx::Vector2dF(0.f
, -70.f
));
180 EXPECT_FLOAT_EQ(-30.f
, manager
->ControlsTopOffset());
181 EXPECT_FLOAT_EQ(70.f
, manager
->ContentTopOffset());
182 manager
->ScrollEnd();
184 EXPECT_TRUE(manager
->animation());
186 base::TimeTicks time
= gfx::FrameTime::Now();
187 float previous_offset
= manager
->ControlsTopOffset();
188 while (manager
->animation()) {
189 time
= base::TimeDelta::FromMicroseconds(100) + time
;
190 manager
->Animate(time
);
191 EXPECT_GT(manager
->ControlsTopOffset(), previous_offset
);
192 previous_offset
= manager
->ControlsTopOffset();
194 EXPECT_FALSE(manager
->animation());
195 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
196 EXPECT_FLOAT_EQ(100.f
, manager
->ContentTopOffset());
199 TEST(TopControlsManagerTest
, PartialHiddenWithAmbiguousThresholdShows
) {
200 MockTopControlsManagerClient
client(100.f
, 0.25f
, 0.25f
);
201 TopControlsManager
* manager
= client
.manager();
203 manager
->ScrollBegin();
205 manager
->ScrollBy(gfx::Vector2dF(0.f
, 20.f
));
206 EXPECT_FLOAT_EQ(-20.f
, manager
->ControlsTopOffset());
207 EXPECT_FLOAT_EQ(80.f
, manager
->ContentTopOffset());
209 manager
->ScrollEnd();
210 EXPECT_TRUE(manager
->animation());
212 base::TimeTicks time
= gfx::FrameTime::Now();
213 float previous_offset
= manager
->ControlsTopOffset();
214 while (manager
->animation()) {
215 time
= base::TimeDelta::FromMicroseconds(100) + time
;
216 manager
->Animate(time
);
217 EXPECT_GT(manager
->ControlsTopOffset(), previous_offset
);
218 previous_offset
= manager
->ControlsTopOffset();
220 EXPECT_FALSE(manager
->animation());
221 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
222 EXPECT_FLOAT_EQ(100.f
, manager
->ContentTopOffset());
225 // Flaky. See http://crbug.com/456617.
226 TEST(TopControlsManagerTest
,
227 DISABLED_PartialHiddenWithAmbiguousThresholdHides
) {
228 MockTopControlsManagerClient
client(100.f
, 0.25f
, 0.25f
);
229 TopControlsManager
* manager
= client
.manager();
231 manager
->ScrollBegin();
233 manager
->ScrollBy(gfx::Vector2dF(0.f
, 30.f
));
234 EXPECT_FLOAT_EQ(-30.f
, manager
->ControlsTopOffset());
235 EXPECT_FLOAT_EQ(70.f
, manager
->ContentTopOffset());
237 manager
->ScrollEnd();
238 EXPECT_TRUE(manager
->animation());
240 base::TimeTicks time
= gfx::FrameTime::Now();
241 float previous_offset
= manager
->ControlsTopOffset();
242 while (manager
->animation()) {
243 time
= base::TimeDelta::FromMicroseconds(100) + time
;
244 manager
->Animate(time
);
245 EXPECT_LT(manager
->ControlsTopOffset(), previous_offset
);
246 previous_offset
= manager
->ControlsTopOffset();
248 EXPECT_FALSE(manager
->animation());
249 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
250 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
253 TEST(TopControlsManagerTest
, DISABLED_PartialShownWithAmbiguousThresholdHides
) {
254 MockTopControlsManagerClient
client(100.f
, 0.25f
, 0.25f
);
255 TopControlsManager
* manager
= client
.manager();
257 manager
->ScrollBy(gfx::Vector2dF(0.f
, 200.f
));
258 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
259 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
261 manager
->ScrollBegin();
263 manager
->ScrollBy(gfx::Vector2dF(0.f
, -20.f
));
264 EXPECT_FLOAT_EQ(-80.f
, manager
->ControlsTopOffset());
265 EXPECT_FLOAT_EQ(20.f
, manager
->ContentTopOffset());
267 manager
->ScrollEnd();
268 EXPECT_TRUE(manager
->animation());
270 base::TimeTicks time
= gfx::FrameTime::Now();
271 float previous_offset
= manager
->ControlsTopOffset();
272 while (manager
->animation()) {
273 time
= base::TimeDelta::FromMicroseconds(100) + time
;
274 manager
->Animate(time
);
275 EXPECT_LT(manager
->ControlsTopOffset(), previous_offset
);
276 previous_offset
= manager
->ControlsTopOffset();
278 EXPECT_FALSE(manager
->animation());
279 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
280 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
283 TEST(TopControlsManagerTest
, PartialShownWithAmbiguousThresholdShows
) {
284 MockTopControlsManagerClient
client(100.f
, 0.25f
, 0.25f
);
285 TopControlsManager
* manager
= client
.manager();
287 manager
->ScrollBy(gfx::Vector2dF(0.f
, 200.f
));
288 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
289 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
291 manager
->ScrollBegin();
293 manager
->ScrollBy(gfx::Vector2dF(0.f
, -30.f
));
294 EXPECT_FLOAT_EQ(-70.f
, manager
->ControlsTopOffset());
295 EXPECT_FLOAT_EQ(30.f
, manager
->ContentTopOffset());
297 manager
->ScrollEnd();
298 EXPECT_TRUE(manager
->animation());
300 base::TimeTicks time
= gfx::FrameTime::Now();
301 float previous_offset
= manager
->ControlsTopOffset();
302 while (manager
->animation()) {
303 time
= base::TimeDelta::FromMicroseconds(100) + time
;
304 manager
->Animate(time
);
305 EXPECT_GT(manager
->ControlsTopOffset(), previous_offset
);
306 previous_offset
= manager
->ControlsTopOffset();
308 EXPECT_FALSE(manager
->animation());
309 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
310 EXPECT_FLOAT_EQ(100.f
, manager
->ContentTopOffset());
313 TEST(TopControlsManagerTest
, PinchIgnoresScroll
) {
314 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
315 TopControlsManager
* manager
= client
.manager();
317 // Hide the controls.
318 manager
->ScrollBegin();
319 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
321 manager
->ScrollBy(gfx::Vector2dF(0.f
, 300.f
));
322 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
324 manager
->PinchBegin();
325 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
327 // Scrolls are ignored during pinch.
328 manager
->ScrollBy(gfx::Vector2dF(0.f
, -15.f
));
329 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
331 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
333 // Scrolls should no long be ignored.
334 manager
->ScrollBy(gfx::Vector2dF(0.f
, -15.f
));
335 EXPECT_FLOAT_EQ(-85.f
, manager
->ControlsTopOffset());
336 EXPECT_FLOAT_EQ(15.f
, manager
->ContentTopOffset());
337 manager
->ScrollEnd();
339 EXPECT_TRUE(manager
->animation());
342 // Flaky. See http://crbug.com/456617.
343 TEST(TopControlsManagerTest
, DISABLED_PinchBeginStartsAnimationIfNecessary
) {
344 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
345 TopControlsManager
* manager
= client
.manager();
347 manager
->ScrollBegin();
348 manager
->ScrollBy(gfx::Vector2dF(0.f
, 300.f
));
349 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
351 manager
->PinchBegin();
352 EXPECT_FALSE(manager
->animation());
355 EXPECT_FALSE(manager
->animation());
357 manager
->ScrollBy(gfx::Vector2dF(0.f
, -15.f
));
358 EXPECT_FLOAT_EQ(-85.f
, manager
->ControlsTopOffset());
359 EXPECT_FLOAT_EQ(15.f
, manager
->ContentTopOffset());
361 manager
->PinchBegin();
362 EXPECT_TRUE(manager
->animation());
364 base::TimeTicks time
= base::TimeTicks::Now();
365 float previous_offset
= manager
->ControlsTopOffset();
366 while (manager
->animation()) {
367 time
= base::TimeDelta::FromMicroseconds(100) + time
;
368 manager
->Animate(time
);
369 EXPECT_LT(manager
->ControlsTopOffset(), previous_offset
);
370 previous_offset
= manager
->ControlsTopOffset();
372 EXPECT_FALSE(manager
->animation());
375 EXPECT_FALSE(manager
->animation());
377 manager
->ScrollBy(gfx::Vector2dF(0.f
, -55.f
));
378 EXPECT_FLOAT_EQ(-45.f
, manager
->ControlsTopOffset());
379 EXPECT_FLOAT_EQ(55.f
, manager
->ContentTopOffset());
380 EXPECT_FALSE(manager
->animation());
382 manager
->ScrollEnd();
383 EXPECT_TRUE(manager
->animation());
385 time
= base::TimeTicks::Now();
386 previous_offset
= manager
->ControlsTopOffset();
387 while (manager
->animation()) {
388 time
= base::TimeDelta::FromMicroseconds(100) + time
;
389 manager
->Animate(time
);
390 EXPECT_GT(manager
->ControlsTopOffset(), previous_offset
);
391 previous_offset
= manager
->ControlsTopOffset();
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 manager
->UpdateTopControlsState(HIDDEN
, HIDDEN
, false);
418 EXPECT_EQ(0.f
, manager
->ControlsTopOffset());
419 EXPECT_EQ(0.f
, manager
->ContentTopOffset());
421 client
.SetTopControlsHeight(50.f
);
422 EXPECT_FALSE(manager
->animation());
423 EXPECT_EQ(-50.f
, manager
->ControlsTopOffset());
424 EXPECT_EQ(0.f
, manager
->ContentTopOffset());
426 client
.SetTopControlsHeight(100.f
);
427 EXPECT_FALSE(manager
->animation());
428 EXPECT_EQ(-100.f
, manager
->ControlsTopOffset());
429 EXPECT_EQ(0.f
, manager
->ContentTopOffset());
432 TEST(TopControlsManagerTest
, ShrinkingHeightKeepsTopControlsHidden
) {
433 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
434 TopControlsManager
* manager
= client
.manager();
436 manager
->ScrollBegin();
437 manager
->ScrollBy(gfx::Vector2dF(0.f
, 300.f
));
438 EXPECT_FLOAT_EQ(-100.f
, manager
->ControlsTopOffset());
439 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
440 manager
->ScrollEnd();
442 client
.SetTopControlsHeight(50.f
);
443 EXPECT_FALSE(manager
->animation());
444 EXPECT_FLOAT_EQ(-50.f
, manager
->ControlsTopOffset());
445 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());
447 client
.SetTopControlsHeight(0.f
);
448 EXPECT_FALSE(manager
->animation());
449 EXPECT_FLOAT_EQ(0.f
, manager
->ControlsTopOffset());
450 EXPECT_FLOAT_EQ(0.f
, manager
->ContentTopOffset());