Home | History | Annotate | Download | only in frame
      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 "chrome/browser/ui/views/frame/browser_view_layout.h"
      6 
      7 #include "chrome/browser/ui/views/frame/browser_view.h"
      8 #include "chrome/browser/ui/views/frame/browser_view_layout_delegate.h"
      9 #include "chrome/browser/ui/views/frame/contents_layout_manager.h"
     10 #include "chrome/browser/ui/views/frame/immersive_mode_controller.h"
     11 #include "chrome/browser/ui/views/infobars/infobar_container_view.h"
     12 #include "chrome/browser/ui/views/tabs/tab_strip.h"
     13 #include "chrome/test/base/browser_with_test_window_test.h"
     14 #include "testing/gtest/include/gtest/gtest.h"
     15 
     16 class MockBrowserViewLayoutDelegate : public BrowserViewLayoutDelegate {
     17  public:
     18   explicit MockBrowserViewLayoutDelegate(views::View* contents_web_view)
     19       : contents_web_view_(contents_web_view),
     20         tab_strip_visible_(true),
     21         toolbar_visible_(true),
     22         bookmark_bar_visible_(true),
     23         download_shelf_needs_layout_(false) {
     24   }
     25   virtual ~MockBrowserViewLayoutDelegate() {}
     26 
     27   void set_download_shelf_needs_layout(bool layout) {
     28     download_shelf_needs_layout_ = layout;
     29   }
     30   void set_tab_strip_visible(bool visible) {
     31     tab_strip_visible_ = visible;
     32   }
     33   void set_toolbar_visible(bool visible) {
     34     toolbar_visible_ = visible;
     35   }
     36   void set_bookmark_bar_visible(bool visible) {
     37     bookmark_bar_visible_ = visible;
     38   }
     39 
     40   // BrowserViewLayout::Delegate overrides:
     41   virtual views::View* GetContentsWebView() const OVERRIDE {
     42     return contents_web_view_;
     43   }
     44   virtual bool IsTabStripVisible() const OVERRIDE {
     45     return tab_strip_visible_;
     46   }
     47   virtual gfx::Rect GetBoundsForTabStripInBrowserView() const OVERRIDE {
     48     return gfx::Rect();
     49   }
     50   virtual int GetTopInsetInBrowserView() const OVERRIDE {
     51     return 0;
     52   }
     53   virtual int GetThemeBackgroundXInset() const OVERRIDE {
     54     return 0;
     55   }
     56   virtual bool IsToolbarVisible() const OVERRIDE {
     57     return toolbar_visible_;
     58   }
     59   virtual bool IsBookmarkBarVisible() const OVERRIDE {
     60     return bookmark_bar_visible_;
     61   }
     62   virtual bool DownloadShelfNeedsLayout() const OVERRIDE {
     63     return download_shelf_needs_layout_;
     64   }
     65 
     66   virtual FullscreenExitBubbleViews* GetFullscreenExitBubble() const OVERRIDE {
     67     return NULL;
     68   }
     69 
     70  private:
     71   views::View* contents_web_view_;
     72   bool tab_strip_visible_;
     73   bool toolbar_visible_;
     74   bool bookmark_bar_visible_;
     75   bool download_shelf_needs_layout_;
     76 
     77   DISALLOW_COPY_AND_ASSIGN(MockBrowserViewLayoutDelegate);
     78 };
     79 
     80 ///////////////////////////////////////////////////////////////////////////////
     81 
     82 // A simple view that prefers an initial size.
     83 class MockView : public views::View {
     84  public:
     85   explicit MockView(gfx::Size initial_size)
     86       : size_(initial_size) {
     87     SetBoundsRect(gfx::Rect(gfx::Point(), size_));
     88   }
     89   virtual ~MockView() {}
     90 
     91   // views::View overrides:
     92   virtual gfx::Size GetPreferredSize() const OVERRIDE {
     93     return size_;
     94   }
     95 
     96  private:
     97   gfx::Size size_;
     98 
     99   DISALLOW_COPY_AND_ASSIGN(MockView);
    100 };
    101 
    102 ///////////////////////////////////////////////////////////////////////////////
    103 
    104 class MockImmersiveModeController : public ImmersiveModeController {
    105  public:
    106   MockImmersiveModeController() {}
    107   virtual ~MockImmersiveModeController() {}
    108 
    109   // ImmersiveModeController overrides:
    110   virtual void Init(BrowserView* browser_view) OVERRIDE {}
    111   virtual void SetEnabled(bool enabled) OVERRIDE {}
    112   virtual bool IsEnabled() const OVERRIDE { return false; }
    113   virtual bool ShouldHideTabIndicators() const OVERRIDE { return false; }
    114   virtual bool ShouldHideTopViews() const OVERRIDE { return false; }
    115   virtual bool IsRevealed() const OVERRIDE { return false; }
    116   virtual int GetTopContainerVerticalOffset(
    117       const gfx::Size& top_container_size) const OVERRIDE { return 0; }
    118   virtual ImmersiveRevealedLock* GetRevealedLock(
    119       AnimateReveal animate_reveal) OVERRIDE WARN_UNUSED_RESULT { return NULL; }
    120   virtual void OnFindBarVisibleBoundsChanged(
    121       const gfx::Rect& new_visible_bounds) OVERRIDE {}
    122   virtual void SetupForTest() OVERRIDE {}
    123 
    124  private:
    125   DISALLOW_COPY_AND_ASSIGN(MockImmersiveModeController);
    126 };
    127 
    128 ///////////////////////////////////////////////////////////////////////////////
    129 // Tests of BrowserViewLayout. Runs tests without constructing a BrowserView.
    130 class BrowserViewLayoutTest : public BrowserWithTestWindowTest {
    131  public:
    132   BrowserViewLayoutTest()
    133       : delegate_(NULL),
    134         top_container_(NULL),
    135         tab_strip_(NULL),
    136         toolbar_(NULL),
    137         infobar_container_(NULL),
    138         contents_container_(NULL),
    139         contents_web_view_(NULL),
    140         devtools_web_view_(NULL) {}
    141   virtual ~BrowserViewLayoutTest() {}
    142 
    143   BrowserViewLayout* layout() { return layout_.get(); }
    144   MockBrowserViewLayoutDelegate* delegate() { return delegate_; }
    145   MockView* root_view() { return root_view_.get(); }
    146   MockView* top_container() { return top_container_; }
    147   TabStrip* tab_strip() { return tab_strip_; }
    148   MockView* toolbar() { return toolbar_; }
    149   InfoBarContainerView* infobar_container() { return infobar_container_; }
    150   MockView* contents_container() { return contents_container_; }
    151 
    152   // BrowserWithTestWindowTest overrides:
    153   virtual void SetUp() OVERRIDE {
    154     BrowserWithTestWindowTest::SetUp();
    155 
    156     root_view_.reset(new MockView(gfx::Size(800, 600)));
    157 
    158     immersive_mode_controller_.reset(new MockImmersiveModeController);
    159 
    160     top_container_ = new MockView(gfx::Size(800, 60));
    161     tab_strip_ = new TabStrip(NULL);
    162     top_container_->AddChildView(tab_strip_);
    163     toolbar_ = new MockView(gfx::Size(800, 30));
    164     top_container_->AddChildView(toolbar_);
    165     root_view_->AddChildView(top_container_);
    166 
    167     infobar_container_ = new InfoBarContainerView(NULL);
    168     root_view_->AddChildView(infobar_container_);
    169 
    170     contents_web_view_ = new MockView(gfx::Size(800, 600));
    171     devtools_web_view_ = new MockView(gfx::Size(800, 600));
    172     devtools_web_view_->SetVisible(false);
    173 
    174     contents_container_ = new MockView(gfx::Size(800, 600));
    175     contents_container_->AddChildView(devtools_web_view_);
    176     contents_container_->AddChildView(contents_web_view_);
    177     ContentsLayoutManager* contents_layout_manager =
    178         new ContentsLayoutManager(devtools_web_view_, contents_web_view_);
    179     contents_container_->SetLayoutManager(contents_layout_manager);
    180 
    181     root_view_->AddChildView(contents_container_);
    182 
    183     // TODO(jamescook): Attach |layout_| to |root_view_|?
    184     layout_.reset(new BrowserViewLayout);
    185     delegate_ = new MockBrowserViewLayoutDelegate(contents_web_view_);
    186     layout_->Init(delegate_,
    187                   browser(),
    188                   NULL,  // BrowserView.
    189                   top_container_,
    190                   tab_strip_,
    191                   toolbar_,
    192                   infobar_container_,
    193                   contents_container_,
    194                   contents_layout_manager,
    195                   immersive_mode_controller_.get());
    196   }
    197 
    198  private:
    199   scoped_ptr<BrowserViewLayout> layout_;
    200   MockBrowserViewLayoutDelegate* delegate_;  // Owned by |layout_|.
    201   scoped_ptr<MockView> root_view_;
    202 
    203   // Views owned by |root_view_|.
    204   MockView* top_container_;
    205   TabStrip* tab_strip_;
    206   MockView* toolbar_;
    207   InfoBarContainerView* infobar_container_;
    208   MockView* contents_container_;
    209   MockView* contents_web_view_;
    210   MockView* devtools_web_view_;
    211 
    212   scoped_ptr<MockImmersiveModeController> immersive_mode_controller_;
    213 
    214   DISALLOW_COPY_AND_ASSIGN(BrowserViewLayoutTest);
    215 };
    216 
    217 // Test basic construction and initialization.
    218 TEST_F(BrowserViewLayoutTest, BrowserViewLayout) {
    219   EXPECT_TRUE(layout()->browser());
    220   EXPECT_TRUE(layout()->GetWebContentsModalDialogHost());
    221   EXPECT_FALSE(layout()->InfobarVisible());
    222 }
    223 
    224 // Test the core layout functions.
    225 TEST_F(BrowserViewLayoutTest, Layout) {
    226   // Simulate a window with no interesting UI.
    227   delegate()->set_tab_strip_visible(false);
    228   delegate()->set_toolbar_visible(false);
    229   delegate()->set_bookmark_bar_visible(false);
    230   layout()->Layout(root_view());
    231 
    232   // Top views are zero-height.
    233   EXPECT_EQ("0,0 0x0", tab_strip()->bounds().ToString());
    234   EXPECT_EQ("0,0 800x0", toolbar()->bounds().ToString());
    235   EXPECT_EQ("0,0 800x0", infobar_container()->bounds().ToString());
    236   // Contents split fills the window.
    237   EXPECT_EQ("0,0 800x600", contents_container()->bounds().ToString());
    238 
    239   // Turn on the toolbar, like in a pop-up window.
    240   delegate()->set_toolbar_visible(true);
    241   layout()->Layout(root_view());
    242 
    243   // Now the toolbar has bounds and other views shift down.
    244   EXPECT_EQ("0,0 0x0", tab_strip()->bounds().ToString());
    245   EXPECT_EQ("0,0 800x30", toolbar()->bounds().ToString());
    246   EXPECT_EQ("0,30 800x0", infobar_container()->bounds().ToString());
    247   EXPECT_EQ("0,30 800x570", contents_container()->bounds().ToString());
    248 
    249   // TODO(jamescook): Tab strip and bookmark bar.
    250 }
    251 
    252 TEST_F(BrowserViewLayoutTest, LayoutDownloadShelf) {
    253   scoped_ptr<MockView> download_shelf(new MockView(gfx::Size(800, 50)));
    254   layout()->set_download_shelf(download_shelf.get());
    255 
    256   // If download shelf doesn't need layout, it doesn't move the bottom edge.
    257   delegate()->set_download_shelf_needs_layout(false);
    258   const int kBottom = 500;
    259   EXPECT_EQ(kBottom, layout()->LayoutDownloadShelf(kBottom));
    260 
    261   // Download shelf layout moves up the bottom edge and sets visibility.
    262   delegate()->set_download_shelf_needs_layout(true);
    263   download_shelf->SetVisible(false);
    264   EXPECT_EQ(450, layout()->LayoutDownloadShelf(kBottom));
    265   EXPECT_TRUE(download_shelf->visible());
    266   EXPECT_EQ("0,450 0x50", download_shelf->bounds().ToString());
    267 }
    268