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/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