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/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/vector2d_f.h" 18 19 namespace cc { 20 namespace { 21 22 static const float kTopControlsHeight = 100; 23 24 class MockTopControlsManagerClient : public TopControlsManagerClient { 25 public: 26 MockTopControlsManagerClient(float top_controls_show_threshold, 27 float top_controls_hide_threshold) 28 : host_impl_(&proxy_, &shared_bitmap_manager_), 29 redraw_needed_(false), 30 update_draw_properties_needed_(false), 31 top_controls_top_offset_(0.f), 32 top_controls_show_threshold_(top_controls_show_threshold), 33 top_controls_hide_threshold_(top_controls_hide_threshold) { 34 active_tree_ = LayerTreeImpl::create(&host_impl_); 35 root_scroll_layer_ = LayerImpl::Create(active_tree_.get(), 1); 36 } 37 38 virtual ~MockTopControlsManagerClient() {} 39 40 virtual void DidChangeTopControlsPosition() OVERRIDE { 41 redraw_needed_ = true; 42 update_draw_properties_needed_ = true; 43 } 44 45 virtual bool HaveRootScrollLayer() const OVERRIDE { 46 return true; 47 } 48 49 virtual void SetControlsTopOffset(float offset) OVERRIDE { 50 top_controls_top_offset_ = offset; 51 } 52 53 virtual float ControlsTopOffset() const OVERRIDE { 54 return top_controls_top_offset_; 55 } 56 57 LayerImpl* rootScrollLayer() { 58 return root_scroll_layer_.get(); 59 } 60 61 TopControlsManager* manager() { 62 if (!manager_) { 63 manager_ = TopControlsManager::Create(this, 64 kTopControlsHeight, 65 top_controls_show_threshold_, 66 top_controls_hide_threshold_); 67 } 68 return manager_.get(); 69 } 70 71 private: 72 FakeImplProxy proxy_; 73 TestSharedBitmapManager shared_bitmap_manager_; 74 FakeLayerTreeHostImpl host_impl_; 75 scoped_ptr<LayerTreeImpl> active_tree_; 76 scoped_ptr<LayerImpl> root_scroll_layer_; 77 scoped_ptr<TopControlsManager> manager_; 78 bool redraw_needed_; 79 bool update_draw_properties_needed_; 80 81 float top_controls_top_offset_; 82 float top_controls_show_threshold_; 83 float top_controls_hide_threshold_; 84 }; 85 86 TEST(TopControlsManagerTest, EnsureScrollThresholdApplied) { 87 MockTopControlsManagerClient client(0.5f, 0.5f); 88 TopControlsManager* manager = client.manager(); 89 90 manager->ScrollBegin(); 91 92 // Scroll down to hide the controls entirely. 93 manager->ScrollBy(gfx::Vector2dF(0.f, 30.f)); 94 EXPECT_EQ(-30.f, manager->ControlsTopOffset()); 95 96 manager->ScrollBy(gfx::Vector2dF(0.f, 30.f)); 97 EXPECT_EQ(-60.f, manager->ControlsTopOffset()); 98 99 manager->ScrollBy(gfx::Vector2dF(0.f, 100.f)); 100 EXPECT_EQ(-100.f, manager->ControlsTopOffset()); 101 102 // Scroll back up a bit and ensure the controls don't move until we cross 103 // the threshold. 104 manager->ScrollBy(gfx::Vector2dF(0.f, -10.f)); 105 EXPECT_EQ(-100.f, manager->ControlsTopOffset()); 106 107 manager->ScrollBy(gfx::Vector2dF(0.f, -50.f)); 108 EXPECT_EQ(-100.f, manager->ControlsTopOffset()); 109 110 // After hitting the threshold, further scrolling up should result in the top 111 // controls showing. 112 manager->ScrollBy(gfx::Vector2dF(0.f, -10.f)); 113 EXPECT_EQ(-90.f, manager->ControlsTopOffset()); 114 115 manager->ScrollBy(gfx::Vector2dF(0.f, -50.f)); 116 EXPECT_EQ(-40.f, manager->ControlsTopOffset()); 117 118 // Reset the scroll threshold by going further up the page than the initial 119 // threshold. 120 manager->ScrollBy(gfx::Vector2dF(0.f, -100.f)); 121 EXPECT_EQ(0.f, manager->ControlsTopOffset()); 122 123 // See that scrolling down the page now will result in the controls hiding. 124 manager->ScrollBy(gfx::Vector2dF(0.f, 20.f)); 125 EXPECT_EQ(-20.f, manager->ControlsTopOffset()); 126 127 manager->ScrollEnd(); 128 } 129 130 TEST(TopControlsManagerTest, PartialShownHideAnimation) { 131 MockTopControlsManagerClient client(0.5f, 0.5f); 132 TopControlsManager* manager = client.manager(); 133 manager->ScrollBegin(); 134 manager->ScrollBy(gfx::Vector2dF(0.f, 300.f)); 135 EXPECT_EQ(-100.f, manager->ControlsTopOffset()); 136 EXPECT_EQ(0.f, manager->ContentTopOffset()); 137 manager->ScrollEnd(); 138 139 manager->ScrollBegin(); 140 manager->ScrollBy(gfx::Vector2dF(0.f, -15.f)); 141 EXPECT_EQ(-85.f, manager->ControlsTopOffset()); 142 EXPECT_EQ(15.f, manager->ContentTopOffset()); 143 manager->ScrollEnd(); 144 145 EXPECT_TRUE(manager->animation()); 146 147 base::TimeTicks time = gfx::FrameTime::Now(); 148 float previous_offset = manager->ControlsTopOffset(); 149 while (manager->animation()) { 150 time = base::TimeDelta::FromMicroseconds(100) + time; 151 manager->Animate(time); 152 EXPECT_LT(manager->ControlsTopOffset(), previous_offset); 153 previous_offset = manager->ControlsTopOffset(); 154 } 155 EXPECT_FALSE(manager->animation()); 156 EXPECT_EQ(-100.f, manager->ControlsTopOffset()); 157 EXPECT_EQ(0.f, manager->ContentTopOffset()); 158 } 159 160 TEST(TopControlsManagerTest, PartialShownShowAnimation) { 161 MockTopControlsManagerClient client(0.5f, 0.5f); 162 TopControlsManager* manager = client.manager(); 163 manager->ScrollBegin(); 164 manager->ScrollBy(gfx::Vector2dF(0.f, 300.f)); 165 EXPECT_EQ(-100.f, manager->ControlsTopOffset()); 166 EXPECT_EQ(0.f, manager->ContentTopOffset()); 167 manager->ScrollEnd(); 168 169 manager->ScrollBegin(); 170 manager->ScrollBy(gfx::Vector2dF(0.f, -70.f)); 171 EXPECT_EQ(-30.f, manager->ControlsTopOffset()); 172 EXPECT_EQ(70.f, manager->ContentTopOffset()); 173 manager->ScrollEnd(); 174 175 EXPECT_TRUE(manager->animation()); 176 177 base::TimeTicks time = gfx::FrameTime::Now(); 178 float previous_offset = manager->ControlsTopOffset(); 179 while (manager->animation()) { 180 time = base::TimeDelta::FromMicroseconds(100) + time; 181 manager->Animate(time); 182 EXPECT_GT(manager->ControlsTopOffset(), previous_offset); 183 previous_offset = manager->ControlsTopOffset(); 184 } 185 EXPECT_FALSE(manager->animation()); 186 EXPECT_EQ(0.f, manager->ControlsTopOffset()); 187 EXPECT_EQ(100.f, manager->ContentTopOffset()); 188 } 189 190 TEST(TopControlsManagerTest, PartialHiddenWithAmbiguousThresholdShows) { 191 MockTopControlsManagerClient client(0.25f, 0.25f); 192 TopControlsManager* manager = client.manager(); 193 194 manager->ScrollBegin(); 195 196 manager->ScrollBy(gfx::Vector2dF(0.f, 20.f)); 197 EXPECT_EQ(-20.f, manager->ControlsTopOffset()); 198 EXPECT_EQ(80.f, manager->ContentTopOffset()); 199 200 manager->ScrollEnd(); 201 EXPECT_TRUE(manager->animation()); 202 203 base::TimeTicks time = gfx::FrameTime::Now(); 204 float previous_offset = manager->ControlsTopOffset(); 205 while (manager->animation()) { 206 time = base::TimeDelta::FromMicroseconds(100) + time; 207 manager->Animate(time); 208 EXPECT_GT(manager->ControlsTopOffset(), previous_offset); 209 previous_offset = manager->ControlsTopOffset(); 210 } 211 EXPECT_FALSE(manager->animation()); 212 EXPECT_EQ(0.f, manager->ControlsTopOffset()); 213 EXPECT_EQ(100.f, manager->ContentTopOffset()); 214 } 215 216 TEST(TopControlsManagerTest, PartialHiddenWithAmbiguousThresholdHides) { 217 MockTopControlsManagerClient client(0.25f, 0.25f); 218 TopControlsManager* manager = client.manager(); 219 220 manager->ScrollBegin(); 221 222 manager->ScrollBy(gfx::Vector2dF(0.f, 30.f)); 223 EXPECT_EQ(-30.f, manager->ControlsTopOffset()); 224 EXPECT_EQ(70.f, manager->ContentTopOffset()); 225 226 manager->ScrollEnd(); 227 EXPECT_TRUE(manager->animation()); 228 229 base::TimeTicks time = gfx::FrameTime::Now(); 230 float previous_offset = manager->ControlsTopOffset(); 231 while (manager->animation()) { 232 time = base::TimeDelta::FromMicroseconds(100) + time; 233 manager->Animate(time); 234 EXPECT_LT(manager->ControlsTopOffset(), previous_offset); 235 previous_offset = manager->ControlsTopOffset(); 236 } 237 EXPECT_FALSE(manager->animation()); 238 EXPECT_EQ(-100.f, manager->ControlsTopOffset()); 239 EXPECT_EQ(0.f, manager->ContentTopOffset()); 240 } 241 242 TEST(TopControlsManagerTest, PartialShownWithAmbiguousThresholdHides) { 243 MockTopControlsManagerClient client(0.25f, 0.25f); 244 TopControlsManager* manager = client.manager(); 245 246 manager->ScrollBy(gfx::Vector2dF(0.f, 200.f)); 247 EXPECT_EQ(-100.f, manager->ControlsTopOffset()); 248 EXPECT_EQ(0.f, manager->ContentTopOffset()); 249 250 manager->ScrollBegin(); 251 252 manager->ScrollBy(gfx::Vector2dF(0.f, -20.f)); 253 EXPECT_EQ(-80.f, manager->ControlsTopOffset()); 254 EXPECT_EQ(20.f, manager->ContentTopOffset()); 255 256 manager->ScrollEnd(); 257 EXPECT_TRUE(manager->animation()); 258 259 base::TimeTicks time = gfx::FrameTime::Now(); 260 float previous_offset = manager->ControlsTopOffset(); 261 while (manager->animation()) { 262 time = base::TimeDelta::FromMicroseconds(100) + time; 263 manager->Animate(time); 264 EXPECT_LT(manager->ControlsTopOffset(), previous_offset); 265 previous_offset = manager->ControlsTopOffset(); 266 } 267 EXPECT_FALSE(manager->animation()); 268 EXPECT_EQ(-100.f, manager->ControlsTopOffset()); 269 EXPECT_EQ(0.f, manager->ContentTopOffset()); 270 } 271 272 TEST(TopControlsManagerTest, PartialShownWithAmbiguousThresholdShows) { 273 MockTopControlsManagerClient client(0.25f, 0.25f); 274 TopControlsManager* manager = client.manager(); 275 276 manager->ScrollBy(gfx::Vector2dF(0.f, 200.f)); 277 EXPECT_EQ(-100.f, manager->ControlsTopOffset()); 278 EXPECT_EQ(0.f, manager->ContentTopOffset()); 279 280 manager->ScrollBegin(); 281 282 manager->ScrollBy(gfx::Vector2dF(0.f, -30.f)); 283 EXPECT_EQ(-70.f, manager->ControlsTopOffset()); 284 EXPECT_EQ(30.f, manager->ContentTopOffset()); 285 286 manager->ScrollEnd(); 287 EXPECT_TRUE(manager->animation()); 288 289 base::TimeTicks time = gfx::FrameTime::Now(); 290 float previous_offset = manager->ControlsTopOffset(); 291 while (manager->animation()) { 292 time = base::TimeDelta::FromMicroseconds(100) + time; 293 manager->Animate(time); 294 EXPECT_GT(manager->ControlsTopOffset(), previous_offset); 295 previous_offset = manager->ControlsTopOffset(); 296 } 297 EXPECT_FALSE(manager->animation()); 298 EXPECT_EQ(0.f, manager->ControlsTopOffset()); 299 EXPECT_EQ(100.f, manager->ContentTopOffset()); 300 } 301 302 TEST(TopControlsManagerTest, PinchIgnoresScroll) { 303 MockTopControlsManagerClient client(0.5f, 0.5f); 304 TopControlsManager* manager = client.manager(); 305 306 // Hide the controls. 307 manager->ScrollBegin(); 308 EXPECT_EQ(0.f, manager->ControlsTopOffset()); 309 310 manager->ScrollBy(gfx::Vector2dF(0.f, 300.f)); 311 EXPECT_EQ(-100.f, manager->ControlsTopOffset()); 312 313 manager->PinchBegin(); 314 EXPECT_EQ(-100.f, manager->ControlsTopOffset()); 315 316 // Scrolls are ignored during pinch. 317 manager->ScrollBy(gfx::Vector2dF(0.f, -15.f)); 318 EXPECT_EQ(-100.f, manager->ControlsTopOffset()); 319 manager->PinchEnd(); 320 EXPECT_EQ(-100.f, manager->ControlsTopOffset()); 321 322 // Scrolls should no long be ignored. 323 manager->ScrollBy(gfx::Vector2dF(0.f, -15.f)); 324 EXPECT_EQ(-85.f, manager->ControlsTopOffset()); 325 EXPECT_EQ(15.f, manager->ContentTopOffset()); 326 manager->ScrollEnd(); 327 328 EXPECT_TRUE(manager->animation()); 329 } 330 331 TEST(TopControlsManagerTest, PinchBeginStartsAnimationIfNecessary) { 332 MockTopControlsManagerClient client(0.5f, 0.5f); 333 TopControlsManager* manager = client.manager(); 334 335 manager->ScrollBegin(); 336 manager->ScrollBy(gfx::Vector2dF(0.f, 300.f)); 337 EXPECT_EQ(-100.f, manager->ControlsTopOffset()); 338 339 manager->PinchBegin(); 340 EXPECT_FALSE(manager->animation()); 341 342 manager->PinchEnd(); 343 EXPECT_FALSE(manager->animation()); 344 345 manager->ScrollBy(gfx::Vector2dF(0.f, -15.f)); 346 EXPECT_EQ(-85.f, manager->ControlsTopOffset()); 347 EXPECT_EQ(15.f, manager->ContentTopOffset()); 348 349 manager->PinchBegin(); 350 EXPECT_TRUE(manager->animation()); 351 352 base::TimeTicks time = base::TimeTicks::Now(); 353 float previous_offset = manager->ControlsTopOffset(); 354 while (manager->animation()) { 355 time = base::TimeDelta::FromMicroseconds(100) + time; 356 manager->Animate(time); 357 EXPECT_LT(manager->ControlsTopOffset(), previous_offset); 358 previous_offset = manager->ControlsTopOffset(); 359 } 360 EXPECT_FALSE(manager->animation()); 361 362 manager->PinchEnd(); 363 EXPECT_FALSE(manager->animation()); 364 365 manager->ScrollBy(gfx::Vector2dF(0.f, -55.f)); 366 EXPECT_EQ(-45.f, manager->ControlsTopOffset()); 367 EXPECT_EQ(55.f, manager->ContentTopOffset()); 368 EXPECT_FALSE(manager->animation()); 369 370 manager->ScrollEnd(); 371 EXPECT_TRUE(manager->animation()); 372 373 time = base::TimeTicks::Now(); 374 previous_offset = manager->ControlsTopOffset(); 375 while (manager->animation()) { 376 time = base::TimeDelta::FromMicroseconds(100) + time; 377 manager->Animate(time); 378 EXPECT_GT(manager->ControlsTopOffset(), previous_offset); 379 previous_offset = manager->ControlsTopOffset(); 380 } 381 EXPECT_FALSE(manager->animation()); 382 EXPECT_EQ(0.f, manager->ControlsTopOffset()); 383 } 384 385 } // namespace 386 } // namespace cc 387