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