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/trees/layer_tree_impl.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "ui/gfx/frame_time.h"
16 #include "ui/gfx/vector2d_f.h"
21 static const float kTopControlsHeight = 100;
23 class MockTopControlsManagerClient : public TopControlsManagerClient {
25 MockTopControlsManagerClient(float top_controls_show_threshold,
26 float top_controls_hide_threshold)
27 : host_impl_(&proxy_),
28 redraw_needed_(false),
29 update_draw_properties_needed_(false),
30 top_controls_show_threshold_(top_controls_show_threshold),
31 top_controls_hide_threshold_(top_controls_hide_threshold) {
32 active_tree_ = LayerTreeImpl::create(&host_impl_);
33 root_scroll_layer_ = LayerImpl::Create(active_tree_.get(), 1);
36 virtual ~MockTopControlsManagerClient() {}
38 virtual void DidChangeTopControlsPosition() OVERRIDE {
39 redraw_needed_ = true;
40 update_draw_properties_needed_ = true;
43 virtual bool HaveRootScrollLayer() const OVERRIDE {
47 LayerImpl* rootScrollLayer() {
48 return root_scroll_layer_.get();
51 TopControlsManager* manager() {
53 manager_ = TopControlsManager::Create(this,
55 top_controls_show_threshold_,
56 top_controls_hide_threshold_);
58 return manager_.get();
63 FakeLayerTreeHostImpl host_impl_;
64 scoped_ptr<LayerTreeImpl> active_tree_;
65 scoped_ptr<LayerImpl> root_scroll_layer_;
66 scoped_ptr<TopControlsManager> manager_;
68 bool update_draw_properties_needed_;
70 float top_controls_show_threshold_;
71 float top_controls_hide_threshold_;
74 TEST(TopControlsManagerTest, EnsureScrollThresholdApplied) {
75 MockTopControlsManagerClient client(0.5f, 0.5f);
76 TopControlsManager* manager = client.manager();
78 manager->ScrollBegin();
80 // Scroll down to hide the controls entirely.
81 manager->ScrollBy(gfx::Vector2dF(0.f, 30.f));
82 EXPECT_EQ(-30.f, manager->controls_top_offset());
84 manager->ScrollBy(gfx::Vector2dF(0.f, 30.f));
85 EXPECT_EQ(-60.f, manager->controls_top_offset());
87 manager->ScrollBy(gfx::Vector2dF(0.f, 100.f));
88 EXPECT_EQ(-100.f, manager->controls_top_offset());
90 // Scroll back up a bit and ensure the controls don't move until we cross
92 manager->ScrollBy(gfx::Vector2dF(0.f, -10.f));
93 EXPECT_EQ(-100.f, manager->controls_top_offset());
95 manager->ScrollBy(gfx::Vector2dF(0.f, -50.f));
96 EXPECT_EQ(-100.f, manager->controls_top_offset());
98 // After hitting the threshold, further scrolling up should result in the top
100 manager->ScrollBy(gfx::Vector2dF(0.f, -10.f));
101 EXPECT_EQ(-90.f, manager->controls_top_offset());
103 manager->ScrollBy(gfx::Vector2dF(0.f, -50.f));
104 EXPECT_EQ(-40.f, manager->controls_top_offset());
106 // Reset the scroll threshold by going further up the page than the initial
108 manager->ScrollBy(gfx::Vector2dF(0.f, -100.f));
109 EXPECT_EQ(0.f, manager->controls_top_offset());
111 // See that scrolling down the page now will result in the controls hiding.
112 manager->ScrollBy(gfx::Vector2dF(0.f, 20.f));
113 EXPECT_EQ(-20.f, manager->controls_top_offset());
115 manager->ScrollEnd();
118 TEST(TopControlsManagerTest, PartialShownHideAnimation) {
119 MockTopControlsManagerClient client(0.5f, 0.5f);
120 TopControlsManager* manager = client.manager();
121 manager->ScrollBegin();
122 manager->ScrollBy(gfx::Vector2dF(0.f, 300.f));
123 EXPECT_EQ(-100.f, manager->controls_top_offset());
124 EXPECT_EQ(0.f, manager->content_top_offset());
125 manager->ScrollEnd();
127 manager->ScrollBegin();
128 manager->ScrollBy(gfx::Vector2dF(0.f, -15.f));
129 EXPECT_EQ(-85.f, manager->controls_top_offset());
130 EXPECT_EQ(15.f, manager->content_top_offset());
131 manager->ScrollEnd();
133 EXPECT_TRUE(manager->animation());
135 base::TimeTicks time = gfx::FrameTime::Now();
136 float previous_offset = manager->controls_top_offset();
137 while (manager->animation()) {
138 time = base::TimeDelta::FromMicroseconds(100) + time;
139 manager->Animate(time);
140 EXPECT_LT(manager->controls_top_offset(), previous_offset);
141 previous_offset = manager->controls_top_offset();
143 EXPECT_FALSE(manager->animation());
144 EXPECT_EQ(-100.f, manager->controls_top_offset());
145 EXPECT_EQ(0.f, manager->content_top_offset());
148 TEST(TopControlsManagerTest, PartialShownShowAnimation) {
149 MockTopControlsManagerClient client(0.5f, 0.5f);
150 TopControlsManager* manager = client.manager();
151 manager->ScrollBegin();
152 manager->ScrollBy(gfx::Vector2dF(0.f, 300.f));
153 EXPECT_EQ(-100.f, manager->controls_top_offset());
154 EXPECT_EQ(0.f, manager->content_top_offset());
155 manager->ScrollEnd();
157 manager->ScrollBegin();
158 manager->ScrollBy(gfx::Vector2dF(0.f, -70.f));
159 EXPECT_EQ(-30.f, manager->controls_top_offset());
160 EXPECT_EQ(70.f, manager->content_top_offset());
161 manager->ScrollEnd();
163 EXPECT_TRUE(manager->animation());
165 base::TimeTicks time = gfx::FrameTime::Now();
166 float previous_offset = manager->controls_top_offset();
167 while (manager->animation()) {
168 time = base::TimeDelta::FromMicroseconds(100) + time;
169 manager->Animate(time);
170 EXPECT_GT(manager->controls_top_offset(), previous_offset);
171 previous_offset = manager->controls_top_offset();
173 EXPECT_FALSE(manager->animation());
174 EXPECT_EQ(0.f, manager->controls_top_offset());
175 EXPECT_EQ(100.f, manager->content_top_offset());
178 TEST(TopControlsManagerTest, PartialHiddenWithAmbiguousThresholdShows) {
179 MockTopControlsManagerClient client(0.25f, 0.25f);
180 TopControlsManager* manager = client.manager();
182 manager->ScrollBegin();
184 manager->ScrollBy(gfx::Vector2dF(0.f, 20.f));
185 EXPECT_EQ(-20.f, manager->controls_top_offset());
186 EXPECT_EQ(80.f, manager->content_top_offset());
188 manager->ScrollEnd();
189 EXPECT_TRUE(manager->animation());
191 base::TimeTicks time = gfx::FrameTime::Now();
192 float previous_offset = manager->controls_top_offset();
193 while (manager->animation()) {
194 time = base::TimeDelta::FromMicroseconds(100) + time;
195 manager->Animate(time);
196 EXPECT_GT(manager->controls_top_offset(), previous_offset);
197 previous_offset = manager->controls_top_offset();
199 EXPECT_FALSE(manager->animation());
200 EXPECT_EQ(0.f, manager->controls_top_offset());
201 EXPECT_EQ(100.f, manager->content_top_offset());
204 TEST(TopControlsManagerTest, PartialHiddenWithAmbiguousThresholdHides) {
205 MockTopControlsManagerClient client(0.25f, 0.25f);
206 TopControlsManager* manager = client.manager();
208 manager->ScrollBegin();
210 manager->ScrollBy(gfx::Vector2dF(0.f, 30.f));
211 EXPECT_EQ(-30.f, manager->controls_top_offset());
212 EXPECT_EQ(70.f, manager->content_top_offset());
214 manager->ScrollEnd();
215 EXPECT_TRUE(manager->animation());
217 base::TimeTicks time = gfx::FrameTime::Now();
218 float previous_offset = manager->controls_top_offset();
219 while (manager->animation()) {
220 time = base::TimeDelta::FromMicroseconds(100) + time;
221 manager->Animate(time);
222 EXPECT_LT(manager->controls_top_offset(), previous_offset);
223 previous_offset = manager->controls_top_offset();
225 EXPECT_FALSE(manager->animation());
226 EXPECT_EQ(-100.f, manager->controls_top_offset());
227 EXPECT_EQ(0.f, manager->content_top_offset());
230 TEST(TopControlsManagerTest, PartialShownWithAmbiguousThresholdHides) {
231 MockTopControlsManagerClient client(0.25f, 0.25f);
232 TopControlsManager* manager = client.manager();
234 manager->ScrollBy(gfx::Vector2dF(0.f, 200.f));
235 EXPECT_EQ(-100.f, manager->controls_top_offset());
236 EXPECT_EQ(0.f, manager->content_top_offset());
238 manager->ScrollBegin();
240 manager->ScrollBy(gfx::Vector2dF(0.f, -20.f));
241 EXPECT_EQ(-80.f, manager->controls_top_offset());
242 EXPECT_EQ(20.f, manager->content_top_offset());
244 manager->ScrollEnd();
245 EXPECT_TRUE(manager->animation());
247 base::TimeTicks time = gfx::FrameTime::Now();
248 float previous_offset = manager->controls_top_offset();
249 while (manager->animation()) {
250 time = base::TimeDelta::FromMicroseconds(100) + time;
251 manager->Animate(time);
252 EXPECT_LT(manager->controls_top_offset(), previous_offset);
253 previous_offset = manager->controls_top_offset();
255 EXPECT_FALSE(manager->animation());
256 EXPECT_EQ(-100.f, manager->controls_top_offset());
257 EXPECT_EQ(0.f, manager->content_top_offset());
260 TEST(TopControlsManagerTest, PartialShownWithAmbiguousThresholdShows) {
261 MockTopControlsManagerClient client(0.25f, 0.25f);
262 TopControlsManager* manager = client.manager();
264 manager->ScrollBy(gfx::Vector2dF(0.f, 200.f));
265 EXPECT_EQ(-100.f, manager->controls_top_offset());
266 EXPECT_EQ(0.f, manager->content_top_offset());
268 manager->ScrollBegin();
270 manager->ScrollBy(gfx::Vector2dF(0.f, -30.f));
271 EXPECT_EQ(-70.f, manager->controls_top_offset());
272 EXPECT_EQ(30.f, manager->content_top_offset());
274 manager->ScrollEnd();
275 EXPECT_TRUE(manager->animation());
277 base::TimeTicks time = gfx::FrameTime::Now();
278 float previous_offset = manager->controls_top_offset();
279 while (manager->animation()) {
280 time = base::TimeDelta::FromMicroseconds(100) + time;
281 manager->Animate(time);
282 EXPECT_GT(manager->controls_top_offset(), previous_offset);
283 previous_offset = manager->controls_top_offset();
285 EXPECT_FALSE(manager->animation());
286 EXPECT_EQ(0.f, manager->controls_top_offset());
287 EXPECT_EQ(100.f, manager->content_top_offset());
290 TEST(TopControlsManagerTest, PinchIgnoresScroll) {
291 MockTopControlsManagerClient client(0.5f, 0.5f);
292 TopControlsManager* manager = client.manager();
294 // Hide the controls.
295 manager->ScrollBegin();
296 EXPECT_EQ(0.f, manager->controls_top_offset());
298 manager->ScrollBy(gfx::Vector2dF(0.f, 300.f));
299 EXPECT_EQ(-100.f, manager->controls_top_offset());
301 manager->PinchBegin();
302 EXPECT_EQ(-100.f, manager->controls_top_offset());
304 // Scrolls are ignored during pinch.
305 manager->ScrollBy(gfx::Vector2dF(0.f, -15.f));
306 EXPECT_EQ(-100.f, manager->controls_top_offset());
308 EXPECT_EQ(-100.f, manager->controls_top_offset());
310 // Scrolls should no long be ignored.
311 manager->ScrollBy(gfx::Vector2dF(0.f, -15.f));
312 EXPECT_EQ(-85.f, manager->controls_top_offset());
313 EXPECT_EQ(15.f, manager->content_top_offset());
314 manager->ScrollEnd();
316 EXPECT_TRUE(manager->animation());
319 TEST(TopControlsManagerTest, PinchBeginStartsAnimationIfNecessary) {
320 MockTopControlsManagerClient client(0.5f, 0.5f);
321 TopControlsManager* manager = client.manager();
323 manager->ScrollBegin();
324 manager->ScrollBy(gfx::Vector2dF(0.f, 300.f));
325 EXPECT_EQ(-100.f, manager->controls_top_offset());
327 manager->PinchBegin();
328 EXPECT_FALSE(manager->animation());
331 EXPECT_FALSE(manager->animation());
333 manager->ScrollBy(gfx::Vector2dF(0.f, -15.f));
334 EXPECT_EQ(-85.f, manager->controls_top_offset());
335 EXPECT_EQ(15.f, manager->content_top_offset());
337 manager->PinchBegin();
338 EXPECT_TRUE(manager->animation());
340 base::TimeTicks time = base::TimeTicks::Now();
341 float previous_offset = manager->controls_top_offset();
342 while (manager->animation()) {
343 time = base::TimeDelta::FromMicroseconds(100) + time;
344 manager->Animate(time);
345 EXPECT_LT(manager->controls_top_offset(), previous_offset);
346 previous_offset = manager->controls_top_offset();
348 EXPECT_FALSE(manager->animation());
351 EXPECT_FALSE(manager->animation());
353 manager->ScrollBy(gfx::Vector2dF(0.f, -55.f));
354 EXPECT_EQ(-45.f, manager->controls_top_offset());
355 EXPECT_EQ(55.f, manager->content_top_offset());
356 EXPECT_FALSE(manager->animation());
358 manager->ScrollEnd();
359 EXPECT_TRUE(manager->animation());
361 time = base::TimeTicks::Now();
362 previous_offset = manager->controls_top_offset();
363 while (manager->animation()) {
364 time = base::TimeDelta::FromMicroseconds(100) + time;
365 manager->Animate(time);
366 EXPECT_GT(manager->controls_top_offset(), previous_offset);
367 previous_offset = manager->controls_top_offset();
369 EXPECT_FALSE(manager->animation());
370 EXPECT_EQ(0.f, manager->controls_top_offset());