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. 4 5 #include "cc/input/top_controls_manager.h" 6 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" 17 18 namespace cc { 19 namespace { 20 21 static const float kTopControlsHeight = 100; 22 23 class MockTopControlsManagerClient : public TopControlsManagerClient { 24 public: 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); 34 } 35 36 virtual ~MockTopControlsManagerClient() {} 37 38 virtual void DidChangeTopControlsPosition() OVERRIDE { 39 redraw_needed_ = true; 40 update_draw_properties_needed_ = true; 41 } 42 43 virtual bool HaveRootScrollLayer() const OVERRIDE { 44 return true; 45 } 46 47 LayerImpl* rootScrollLayer() { 48 return root_scroll_layer_.get(); 49 } 50 51 TopControlsManager* manager() { 52 if (!manager_) { 53 manager_ = TopControlsManager::Create(this, 54 kTopControlsHeight, 55 top_controls_show_threshold_, 56 top_controls_hide_threshold_); 57 } 58 return manager_.get(); 59 } 60 61 private: 62 FakeImplProxy proxy_; 63 FakeLayerTreeHostImpl host_impl_; 64 scoped_ptr<LayerTreeImpl> active_tree_; 65 scoped_ptr<LayerImpl> root_scroll_layer_; 66 scoped_ptr<TopControlsManager> manager_; 67 bool redraw_needed_; 68 bool update_draw_properties_needed_; 69 70 float top_controls_show_threshold_; 71 float top_controls_hide_threshold_; 72 }; 73 74 TEST(TopControlsManagerTest, EnsureScrollThresholdApplied) { 75 MockTopControlsManagerClient client(0.5f, 0.5f); 76 TopControlsManager* manager = client.manager(); 77 78 manager->ScrollBegin(); 79 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()); 83 84 manager->ScrollBy(gfx::Vector2dF(0.f, 30.f)); 85 EXPECT_EQ(-60.f, manager->controls_top_offset()); 86 87 manager->ScrollBy(gfx::Vector2dF(0.f, 100.f)); 88 EXPECT_EQ(-100.f, manager->controls_top_offset()); 89 90 // Scroll back up a bit and ensure the controls don't move until we cross 91 // the threshold. 92 manager->ScrollBy(gfx::Vector2dF(0.f, -10.f)); 93 EXPECT_EQ(-100.f, manager->controls_top_offset()); 94 95 manager->ScrollBy(gfx::Vector2dF(0.f, -50.f)); 96 EXPECT_EQ(-100.f, manager->controls_top_offset()); 97 98 // After hitting the threshold, further scrolling up should result in the top 99 // controls showing. 100 manager->ScrollBy(gfx::Vector2dF(0.f, -10.f)); 101 EXPECT_EQ(-90.f, manager->controls_top_offset()); 102 103 manager->ScrollBy(gfx::Vector2dF(0.f, -50.f)); 104 EXPECT_EQ(-40.f, manager->controls_top_offset()); 105 106 // Reset the scroll threshold by going further up the page than the initial 107 // threshold. 108 manager->ScrollBy(gfx::Vector2dF(0.f, -100.f)); 109 EXPECT_EQ(0.f, manager->controls_top_offset()); 110 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()); 114 115 manager->ScrollEnd(); 116 } 117 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(); 126 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(); 132 133 EXPECT_TRUE(manager->animation()); 134 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(); 142 } 143 EXPECT_FALSE(manager->animation()); 144 EXPECT_EQ(-100.f, manager->controls_top_offset()); 145 EXPECT_EQ(0.f, manager->content_top_offset()); 146 } 147 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(); 156 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(); 162 163 EXPECT_TRUE(manager->animation()); 164 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(); 172 } 173 EXPECT_FALSE(manager->animation()); 174 EXPECT_EQ(0.f, manager->controls_top_offset()); 175 EXPECT_EQ(100.f, manager->content_top_offset()); 176 } 177 178 TEST(TopControlsManagerTest, PartialHiddenWithAmbiguousThresholdShows) { 179 MockTopControlsManagerClient client(0.25f, 0.25f); 180 TopControlsManager* manager = client.manager(); 181 182 manager->ScrollBegin(); 183 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()); 187 188 manager->ScrollEnd(); 189 EXPECT_TRUE(manager->animation()); 190 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(); 198 } 199 EXPECT_FALSE(manager->animation()); 200 EXPECT_EQ(0.f, manager->controls_top_offset()); 201 EXPECT_EQ(100.f, manager->content_top_offset()); 202 } 203 204 TEST(TopControlsManagerTest, PartialHiddenWithAmbiguousThresholdHides) { 205 MockTopControlsManagerClient client(0.25f, 0.25f); 206 TopControlsManager* manager = client.manager(); 207 208 manager->ScrollBegin(); 209 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()); 213 214 manager->ScrollEnd(); 215 EXPECT_TRUE(manager->animation()); 216 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(); 224 } 225 EXPECT_FALSE(manager->animation()); 226 EXPECT_EQ(-100.f, manager->controls_top_offset()); 227 EXPECT_EQ(0.f, manager->content_top_offset()); 228 } 229 230 TEST(TopControlsManagerTest, PartialShownWithAmbiguousThresholdHides) { 231 MockTopControlsManagerClient client(0.25f, 0.25f); 232 TopControlsManager* manager = client.manager(); 233 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()); 237 238 manager->ScrollBegin(); 239 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()); 243 244 manager->ScrollEnd(); 245 EXPECT_TRUE(manager->animation()); 246 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(); 254 } 255 EXPECT_FALSE(manager->animation()); 256 EXPECT_EQ(-100.f, manager->controls_top_offset()); 257 EXPECT_EQ(0.f, manager->content_top_offset()); 258 } 259 260 TEST(TopControlsManagerTest, PartialShownWithAmbiguousThresholdShows) { 261 MockTopControlsManagerClient client(0.25f, 0.25f); 262 TopControlsManager* manager = client.manager(); 263 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()); 267 268 manager->ScrollBegin(); 269 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()); 273 274 manager->ScrollEnd(); 275 EXPECT_TRUE(manager->animation()); 276 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(); 284 } 285 EXPECT_FALSE(manager->animation()); 286 EXPECT_EQ(0.f, manager->controls_top_offset()); 287 EXPECT_EQ(100.f, manager->content_top_offset()); 288 } 289 290 TEST(TopControlsManagerTest, PinchIgnoresScroll) { 291 MockTopControlsManagerClient client(0.5f, 0.5f); 292 TopControlsManager* manager = client.manager(); 293 294 // Hide the controls. 295 manager->ScrollBegin(); 296 EXPECT_EQ(0.f, manager->controls_top_offset()); 297 298 manager->ScrollBy(gfx::Vector2dF(0.f, 300.f)); 299 EXPECT_EQ(-100.f, manager->controls_top_offset()); 300 301 manager->PinchBegin(); 302 EXPECT_EQ(-100.f, manager->controls_top_offset()); 303 304 // Scrolls are ignored during pinch. 305 manager->ScrollBy(gfx::Vector2dF(0.f, -15.f)); 306 EXPECT_EQ(-100.f, manager->controls_top_offset()); 307 manager->PinchEnd(); 308 EXPECT_EQ(-100.f, manager->controls_top_offset()); 309 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(); 315 316 EXPECT_TRUE(manager->animation()); 317 } 318 319 TEST(TopControlsManagerTest, PinchBeginStartsAnimationIfNecessary) { 320 MockTopControlsManagerClient client(0.5f, 0.5f); 321 TopControlsManager* manager = client.manager(); 322 323 manager->ScrollBegin(); 324 manager->ScrollBy(gfx::Vector2dF(0.f, 300.f)); 325 EXPECT_EQ(-100.f, manager->controls_top_offset()); 326 327 manager->PinchBegin(); 328 EXPECT_FALSE(manager->animation()); 329 330 manager->PinchEnd(); 331 EXPECT_FALSE(manager->animation()); 332 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()); 336 337 manager->PinchBegin(); 338 EXPECT_TRUE(manager->animation()); 339 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(); 347 } 348 EXPECT_FALSE(manager->animation()); 349 350 manager->PinchEnd(); 351 EXPECT_FALSE(manager->animation()); 352 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()); 357 358 manager->ScrollEnd(); 359 EXPECT_TRUE(manager->animation()); 360 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(); 368 } 369 EXPECT_FALSE(manager->animation()); 370 EXPECT_EQ(0.f, manager->controls_top_offset()); 371 } 372 373 } // namespace 374 } // namespace cc 375