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