Home | History | Annotate | Download | only in input
      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