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"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/time/time.h"
9 #include "cc/input/top_controls_manager_client.h"
10 #include "cc/layers/layer_impl.h"
11 #include "cc/test/fake_impl_proxy.h"
12 #include "cc/test/fake_layer_tree_host_impl.h"
13 #include "cc/test/test_shared_bitmap_manager.h"
14 #include "cc/trees/layer_tree_impl.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "ui/gfx/frame_time.h"
17 #include "ui/gfx/geometry/vector2d_f.h"
22 class MockTopControlsManagerClient
: public TopControlsManagerClient
{
24 MockTopControlsManagerClient(float top_controls_height
,
25 float top_controls_show_threshold
,
26 float top_controls_hide_threshold
)
27 : host_impl_(&proxy_
, &shared_bitmap_manager_
),
28 redraw_needed_(false),
29 update_draw_properties_needed_(false),
30 top_controls_top_offset_(0.f
),
31 top_controls_height_(top_controls_height
),
32 top_controls_show_threshold_(top_controls_show_threshold
),
33 top_controls_hide_threshold_(top_controls_hide_threshold
) {
35 LayerTreeImpl::create(&host_impl_
, new SyncedProperty
<ScaleGroup
>,
36 new SyncedElasticOverscroll
);
37 root_scroll_layer_
= LayerImpl::Create(active_tree_
.get(), 1);
40 ~MockTopControlsManagerClient() override
{}
42 void DidChangeTopControlsPosition() override
{
43 redraw_needed_
= true;
44 update_draw_properties_needed_
= true;
47 bool HaveRootScrollLayer() const override
{ return true; }
49 void SetControlsTopOffset(float offset
) override
{
50 top_controls_top_offset_
= offset
;
53 float ControlsTopOffset() const override
{ return top_controls_top_offset_
; }
55 LayerImpl
* rootScrollLayer() {
56 return root_scroll_layer_
.get();
59 TopControlsManager
* manager() {
61 manager_
= TopControlsManager::Create(this,
62 top_controls_show_threshold_
,
63 top_controls_hide_threshold_
);
64 manager_
->SetTopControlsHeight(top_controls_height_
);
66 return manager_
.get();
71 TestSharedBitmapManager shared_bitmap_manager_
;
72 FakeLayerTreeHostImpl host_impl_
;
73 scoped_ptr
<LayerTreeImpl
> active_tree_
;
74 scoped_ptr
<LayerImpl
> root_scroll_layer_
;
75 scoped_ptr
<TopControlsManager
> manager_
;
77 bool update_draw_properties_needed_
;
79 float top_controls_top_offset_
;
80 float top_controls_height_
;
81 float top_controls_show_threshold_
;
82 float top_controls_hide_threshold_
;
85 TEST(TopControlsManagerTest
, EnsureScrollThresholdApplied
) {
86 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
87 TopControlsManager
* manager
= client
.manager();
89 manager
->ScrollBegin();
91 // Scroll down to hide the controls entirely.
92 manager
->ScrollBy(gfx::Vector2dF(0.f
, 30.f
));
93 EXPECT_EQ(-30.f
, manager
->ControlsTopOffset());
95 manager
->ScrollBy(gfx::Vector2dF(0.f
, 30.f
));
96 EXPECT_EQ(-60.f
, manager
->ControlsTopOffset());
98 manager
->ScrollBy(gfx::Vector2dF(0.f
, 100.f
));
99 EXPECT_EQ(-100.f
, manager
->ControlsTopOffset());
101 // Scroll back up a bit and ensure the controls don't move until we cross
103 manager
->ScrollBy(gfx::Vector2dF(0.f
, -10.f
));
104 EXPECT_EQ(-100.f
, manager
->ControlsTopOffset());
106 manager
->ScrollBy(gfx::Vector2dF(0.f
, -50.f
));
107 EXPECT_EQ(-100.f
, manager
->ControlsTopOffset());
109 // After hitting the threshold, further scrolling up should result in the top
111 manager
->ScrollBy(gfx::Vector2dF(0.f
, -10.f
));
112 EXPECT_EQ(-90.f
, manager
->ControlsTopOffset());
114 manager
->ScrollBy(gfx::Vector2dF(0.f
, -50.f
));
115 EXPECT_EQ(-40.f
, manager
->ControlsTopOffset());
117 // Reset the scroll threshold by going further up the page than the initial
119 manager
->ScrollBy(gfx::Vector2dF(0.f
, -100.f
));
120 EXPECT_EQ(0.f
, manager
->ControlsTopOffset());
122 // See that scrolling down the page now will result in the controls hiding.
123 manager
->ScrollBy(gfx::Vector2dF(0.f
, 20.f
));
124 EXPECT_EQ(-20.f
, manager
->ControlsTopOffset());
126 manager
->ScrollEnd();
129 TEST(TopControlsManagerTest
, PartialShownHideAnimation
) {
130 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
131 TopControlsManager
* manager
= client
.manager();
132 manager
->ScrollBegin();
133 manager
->ScrollBy(gfx::Vector2dF(0.f
, 300.f
));
134 EXPECT_EQ(-100.f
, manager
->ControlsTopOffset());
135 EXPECT_EQ(0.f
, manager
->ContentTopOffset());
136 manager
->ScrollEnd();
138 manager
->ScrollBegin();
139 manager
->ScrollBy(gfx::Vector2dF(0.f
, -15.f
));
140 EXPECT_EQ(-85.f
, manager
->ControlsTopOffset());
141 EXPECT_EQ(15.f
, manager
->ContentTopOffset());
142 manager
->ScrollEnd();
144 EXPECT_TRUE(manager
->animation());
146 base::TimeTicks time
= gfx::FrameTime::Now();
147 float previous_offset
= manager
->ControlsTopOffset();
148 while (manager
->animation()) {
149 time
= base::TimeDelta::FromMicroseconds(100) + time
;
150 manager
->Animate(time
);
151 EXPECT_LT(manager
->ControlsTopOffset(), previous_offset
);
152 previous_offset
= manager
->ControlsTopOffset();
154 EXPECT_FALSE(manager
->animation());
155 EXPECT_EQ(-100.f
, manager
->ControlsTopOffset());
156 EXPECT_EQ(0.f
, manager
->ContentTopOffset());
159 TEST(TopControlsManagerTest
, PartialShownShowAnimation
) {
160 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
161 TopControlsManager
* manager
= client
.manager();
162 manager
->ScrollBegin();
163 manager
->ScrollBy(gfx::Vector2dF(0.f
, 300.f
));
164 EXPECT_EQ(-100.f
, manager
->ControlsTopOffset());
165 EXPECT_EQ(0.f
, manager
->ContentTopOffset());
166 manager
->ScrollEnd();
168 manager
->ScrollBegin();
169 manager
->ScrollBy(gfx::Vector2dF(0.f
, -70.f
));
170 EXPECT_EQ(-30.f
, manager
->ControlsTopOffset());
171 EXPECT_EQ(70.f
, manager
->ContentTopOffset());
172 manager
->ScrollEnd();
174 EXPECT_TRUE(manager
->animation());
176 base::TimeTicks time
= gfx::FrameTime::Now();
177 float previous_offset
= manager
->ControlsTopOffset();
178 while (manager
->animation()) {
179 time
= base::TimeDelta::FromMicroseconds(100) + time
;
180 manager
->Animate(time
);
181 EXPECT_GT(manager
->ControlsTopOffset(), previous_offset
);
182 previous_offset
= manager
->ControlsTopOffset();
184 EXPECT_FALSE(manager
->animation());
185 EXPECT_EQ(0.f
, manager
->ControlsTopOffset());
186 EXPECT_EQ(100.f
, manager
->ContentTopOffset());
189 TEST(TopControlsManagerTest
, PartialHiddenWithAmbiguousThresholdShows
) {
190 MockTopControlsManagerClient
client(100.f
, 0.25f
, 0.25f
);
191 TopControlsManager
* manager
= client
.manager();
193 manager
->ScrollBegin();
195 manager
->ScrollBy(gfx::Vector2dF(0.f
, 20.f
));
196 EXPECT_EQ(-20.f
, manager
->ControlsTopOffset());
197 EXPECT_EQ(80.f
, manager
->ContentTopOffset());
199 manager
->ScrollEnd();
200 EXPECT_TRUE(manager
->animation());
202 base::TimeTicks time
= gfx::FrameTime::Now();
203 float previous_offset
= manager
->ControlsTopOffset();
204 while (manager
->animation()) {
205 time
= base::TimeDelta::FromMicroseconds(100) + time
;
206 manager
->Animate(time
);
207 EXPECT_GT(manager
->ControlsTopOffset(), previous_offset
);
208 previous_offset
= manager
->ControlsTopOffset();
210 EXPECT_FALSE(manager
->animation());
211 EXPECT_EQ(0.f
, manager
->ControlsTopOffset());
212 EXPECT_EQ(100.f
, manager
->ContentTopOffset());
215 TEST(TopControlsManagerTest
, PartialHiddenWithAmbiguousThresholdHides
) {
216 MockTopControlsManagerClient
client(100.f
, 0.25f
, 0.25f
);
217 TopControlsManager
* manager
= client
.manager();
219 manager
->ScrollBegin();
221 manager
->ScrollBy(gfx::Vector2dF(0.f
, 30.f
));
222 EXPECT_EQ(-30.f
, manager
->ControlsTopOffset());
223 EXPECT_EQ(70.f
, manager
->ContentTopOffset());
225 manager
->ScrollEnd();
226 EXPECT_TRUE(manager
->animation());
228 base::TimeTicks time
= gfx::FrameTime::Now();
229 float previous_offset
= manager
->ControlsTopOffset();
230 while (manager
->animation()) {
231 time
= base::TimeDelta::FromMicroseconds(100) + time
;
232 manager
->Animate(time
);
233 EXPECT_LT(manager
->ControlsTopOffset(), previous_offset
);
234 previous_offset
= manager
->ControlsTopOffset();
236 EXPECT_FALSE(manager
->animation());
237 EXPECT_EQ(-100.f
, manager
->ControlsTopOffset());
238 EXPECT_EQ(0.f
, manager
->ContentTopOffset());
241 TEST(TopControlsManagerTest
, PartialShownWithAmbiguousThresholdHides
) {
242 MockTopControlsManagerClient
client(100.f
, 0.25f
, 0.25f
);
243 TopControlsManager
* manager
= client
.manager();
245 manager
->ScrollBy(gfx::Vector2dF(0.f
, 200.f
));
246 EXPECT_EQ(-100.f
, manager
->ControlsTopOffset());
247 EXPECT_EQ(0.f
, manager
->ContentTopOffset());
249 manager
->ScrollBegin();
251 manager
->ScrollBy(gfx::Vector2dF(0.f
, -20.f
));
252 EXPECT_EQ(-80.f
, manager
->ControlsTopOffset());
253 EXPECT_EQ(20.f
, manager
->ContentTopOffset());
255 manager
->ScrollEnd();
256 EXPECT_TRUE(manager
->animation());
258 base::TimeTicks time
= gfx::FrameTime::Now();
259 float previous_offset
= manager
->ControlsTopOffset();
260 while (manager
->animation()) {
261 time
= base::TimeDelta::FromMicroseconds(100) + time
;
262 manager
->Animate(time
);
263 EXPECT_LT(manager
->ControlsTopOffset(), previous_offset
);
264 previous_offset
= manager
->ControlsTopOffset();
266 EXPECT_FALSE(manager
->animation());
267 EXPECT_EQ(-100.f
, manager
->ControlsTopOffset());
268 EXPECT_EQ(0.f
, manager
->ContentTopOffset());
271 TEST(TopControlsManagerTest
, PartialShownWithAmbiguousThresholdShows
) {
272 MockTopControlsManagerClient
client(100.f
, 0.25f
, 0.25f
);
273 TopControlsManager
* manager
= client
.manager();
275 manager
->ScrollBy(gfx::Vector2dF(0.f
, 200.f
));
276 EXPECT_EQ(-100.f
, manager
->ControlsTopOffset());
277 EXPECT_EQ(0.f
, manager
->ContentTopOffset());
279 manager
->ScrollBegin();
281 manager
->ScrollBy(gfx::Vector2dF(0.f
, -30.f
));
282 EXPECT_EQ(-70.f
, manager
->ControlsTopOffset());
283 EXPECT_EQ(30.f
, manager
->ContentTopOffset());
285 manager
->ScrollEnd();
286 EXPECT_TRUE(manager
->animation());
288 base::TimeTicks time
= gfx::FrameTime::Now();
289 float previous_offset
= manager
->ControlsTopOffset();
290 while (manager
->animation()) {
291 time
= base::TimeDelta::FromMicroseconds(100) + time
;
292 manager
->Animate(time
);
293 EXPECT_GT(manager
->ControlsTopOffset(), previous_offset
);
294 previous_offset
= manager
->ControlsTopOffset();
296 EXPECT_FALSE(manager
->animation());
297 EXPECT_EQ(0.f
, manager
->ControlsTopOffset());
298 EXPECT_EQ(100.f
, manager
->ContentTopOffset());
301 TEST(TopControlsManagerTest
, PinchIgnoresScroll
) {
302 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
303 TopControlsManager
* manager
= client
.manager();
305 // Hide the controls.
306 manager
->ScrollBegin();
307 EXPECT_EQ(0.f
, manager
->ControlsTopOffset());
309 manager
->ScrollBy(gfx::Vector2dF(0.f
, 300.f
));
310 EXPECT_EQ(-100.f
, manager
->ControlsTopOffset());
312 manager
->PinchBegin();
313 EXPECT_EQ(-100.f
, manager
->ControlsTopOffset());
315 // Scrolls are ignored during pinch.
316 manager
->ScrollBy(gfx::Vector2dF(0.f
, -15.f
));
317 EXPECT_EQ(-100.f
, manager
->ControlsTopOffset());
319 EXPECT_EQ(-100.f
, manager
->ControlsTopOffset());
321 // Scrolls should no long be ignored.
322 manager
->ScrollBy(gfx::Vector2dF(0.f
, -15.f
));
323 EXPECT_EQ(-85.f
, manager
->ControlsTopOffset());
324 EXPECT_EQ(15.f
, manager
->ContentTopOffset());
325 manager
->ScrollEnd();
327 EXPECT_TRUE(manager
->animation());
330 TEST(TopControlsManagerTest
, PinchBeginStartsAnimationIfNecessary
) {
331 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
332 TopControlsManager
* manager
= client
.manager();
334 manager
->ScrollBegin();
335 manager
->ScrollBy(gfx::Vector2dF(0.f
, 300.f
));
336 EXPECT_EQ(-100.f
, manager
->ControlsTopOffset());
338 manager
->PinchBegin();
339 EXPECT_FALSE(manager
->animation());
342 EXPECT_FALSE(manager
->animation());
344 manager
->ScrollBy(gfx::Vector2dF(0.f
, -15.f
));
345 EXPECT_EQ(-85.f
, manager
->ControlsTopOffset());
346 EXPECT_EQ(15.f
, manager
->ContentTopOffset());
348 manager
->PinchBegin();
349 EXPECT_TRUE(manager
->animation());
351 base::TimeTicks time
= base::TimeTicks::Now();
352 float previous_offset
= manager
->ControlsTopOffset();
353 while (manager
->animation()) {
354 time
= base::TimeDelta::FromMicroseconds(100) + time
;
355 manager
->Animate(time
);
356 EXPECT_LT(manager
->ControlsTopOffset(), previous_offset
);
357 previous_offset
= manager
->ControlsTopOffset();
359 EXPECT_FALSE(manager
->animation());
362 EXPECT_FALSE(manager
->animation());
364 manager
->ScrollBy(gfx::Vector2dF(0.f
, -55.f
));
365 EXPECT_EQ(-45.f
, manager
->ControlsTopOffset());
366 EXPECT_EQ(55.f
, manager
->ContentTopOffset());
367 EXPECT_FALSE(manager
->animation());
369 manager
->ScrollEnd();
370 EXPECT_TRUE(manager
->animation());
372 time
= base::TimeTicks::Now();
373 previous_offset
= manager
->ControlsTopOffset();
374 while (manager
->animation()) {
375 time
= base::TimeDelta::FromMicroseconds(100) + time
;
376 manager
->Animate(time
);
377 EXPECT_GT(manager
->ControlsTopOffset(), previous_offset
);
378 previous_offset
= manager
->ControlsTopOffset();
380 EXPECT_FALSE(manager
->animation());
381 EXPECT_EQ(0.f
, manager
->ControlsTopOffset());
384 TEST(TopControlsManagerTest
, HeightChangeMaintainsFullyVisibleControls
) {
385 MockTopControlsManagerClient
client(0.f
, 0.5f
, 0.5f
);
386 TopControlsManager
* manager
= client
.manager();
388 EXPECT_EQ(0.f
, manager
->top_controls_height());
389 EXPECT_EQ(0.f
, manager
->ControlsTopOffset());
391 manager
->SetTopControlsHeight(100.f
);
392 EXPECT_FALSE(manager
->animation());
393 EXPECT_EQ(100.f
, manager
->top_controls_height());
394 EXPECT_EQ(0, manager
->ControlsTopOffset());
396 manager
->SetTopControlsHeight(50.f
);
397 EXPECT_FALSE(manager
->animation());
398 EXPECT_EQ(50.f
, manager
->top_controls_height());
399 EXPECT_EQ(0.f
, manager
->ControlsTopOffset());
402 TEST(TopControlsManagerTest
, ShrinkingHeightKeepsTopControlsHidden
) {
403 MockTopControlsManagerClient
client(100.f
, 0.5f
, 0.5f
);
404 TopControlsManager
* manager
= client
.manager();
406 manager
->ScrollBegin();
407 manager
->ScrollBy(gfx::Vector2dF(0.f
, 300.f
));
408 EXPECT_EQ(-100.f
, manager
->ControlsTopOffset());
409 EXPECT_EQ(0.f
, manager
->ContentTopOffset());
410 manager
->ScrollEnd();
412 manager
->SetTopControlsHeight(50.f
);
413 EXPECT_FALSE(manager
->animation());
414 EXPECT_EQ(-50.f
, manager
->ControlsTopOffset());
415 EXPECT_EQ(0.f
, manager
->ContentTopOffset());
417 manager
->SetTopControlsHeight(0.f
);
418 EXPECT_FALSE(manager
->animation());
419 EXPECT_EQ(0.f
, manager
->ControlsTopOffset());
420 EXPECT_EQ(0.f
, manager
->ContentTopOffset());
423 TEST(TopControlsManagerTest
, HiddenTopControlsReadjustOnIncreasedHeight
) {
424 MockTopControlsManagerClient
client(10.f
, 0.5f
, 0.5f
);
425 TopControlsManager
* manager
= client
.manager();
427 manager
->ScrollBegin();
428 manager
->ScrollBy(gfx::Vector2dF(0.f
, 300.f
));
429 EXPECT_EQ(-10.f
, manager
->ControlsTopOffset());
430 EXPECT_EQ(0.f
, manager
->ContentTopOffset());
431 manager
->ScrollEnd();
433 manager
->SetTopControlsHeight(15.f
);
434 EXPECT_TRUE(manager
->animation());
435 base::TimeTicks time
= base::TimeTicks::Now();
436 float previous_offset
= manager
->ControlsTopOffset();
437 while (manager
->animation()) {
438 time
= base::TimeDelta::FromMicroseconds(100) + time
;
439 manager
->Animate(time
);
440 EXPECT_LT(manager
->ControlsTopOffset(), previous_offset
);
441 previous_offset
= manager
->ControlsTopOffset();
443 EXPECT_FALSE(manager
->animation());
444 EXPECT_EQ(-15.f
, manager
->ControlsTopOffset());
446 manager
->SetTopControlsHeight(35.f
);
447 EXPECT_TRUE(manager
->animation());
448 time
= base::TimeTicks::Now();
449 previous_offset
= manager
->ControlsTopOffset();
450 while (manager
->animation()) {
451 time
= base::TimeDelta::FromMicroseconds(100) + time
;
452 manager
->Animate(time
);
453 EXPECT_GT(manager
->ControlsTopOffset(), previous_offset
);
454 previous_offset
= manager
->ControlsTopOffset();
456 EXPECT_FALSE(manager
->animation());
457 EXPECT_EQ(0.f
, manager
->ControlsTopOffset());