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