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.
5 #include "chrome/browser/ui/views/frame/browser_view_layout.h"
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"
16 class MockBrowserViewLayoutDelegate
: public BrowserViewLayoutDelegate
{
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) {
25 ~MockBrowserViewLayoutDelegate() override
{}
27 void set_download_shelf_needs_layout(bool layout
) {
28 download_shelf_needs_layout_
= layout
;
30 void set_tab_strip_visible(bool visible
) {
31 tab_strip_visible_
= visible
;
33 void set_toolbar_visible(bool visible
) {
34 toolbar_visible_
= visible
;
36 void set_bookmark_bar_visible(bool visible
) {
37 bookmark_bar_visible_
= visible
;
40 // BrowserViewLayout::Delegate overrides:
41 views::View
* GetContentsWebView() const override
{
42 return contents_web_view_
;
44 bool IsTabStripVisible() const override
{ return tab_strip_visible_
; }
45 gfx::Rect
GetBoundsForTabStripInBrowserView() const override
{
48 int GetTopInsetInBrowserView() const override
{ return 0; }
49 int GetThemeBackgroundXInset() const override
{ return 0; }
50 bool IsToolbarVisible() const override
{ return toolbar_visible_
; }
51 bool IsBookmarkBarVisible() const override
{ return bookmark_bar_visible_
; }
52 bool DownloadShelfNeedsLayout() const override
{
53 return download_shelf_needs_layout_
;
56 ExclusiveAccessBubbleViews
* GetExclusiveAccessBubble() const override
{
61 views::View
* contents_web_view_
;
62 bool tab_strip_visible_
;
63 bool toolbar_visible_
;
64 bool bookmark_bar_visible_
;
65 bool download_shelf_needs_layout_
;
67 DISALLOW_COPY_AND_ASSIGN(MockBrowserViewLayoutDelegate
);
70 ///////////////////////////////////////////////////////////////////////////////
72 // A simple view that prefers an initial size.
73 class MockView
: public views::View
{
75 explicit MockView(gfx::Size initial_size
)
76 : size_(initial_size
) {
77 SetBoundsRect(gfx::Rect(gfx::Point(), size_
));
79 ~MockView() override
{}
81 // views::View overrides:
82 gfx::Size
GetPreferredSize() const override
{ return size_
; }
87 DISALLOW_COPY_AND_ASSIGN(MockView
);
90 ///////////////////////////////////////////////////////////////////////////////
92 class MockImmersiveModeController
: public ImmersiveModeController
{
94 MockImmersiveModeController() {}
95 ~MockImmersiveModeController() override
{}
97 // ImmersiveModeController overrides:
98 void Init(BrowserView
* browser_view
) override
{}
99 void SetEnabled(bool enabled
) override
{}
100 bool IsEnabled() const override
{ return false; }
101 bool ShouldHideTabIndicators() const override
{ return false; }
102 bool ShouldHideTopViews() const override
{ return false; }
103 bool IsRevealed() const override
{ return false; }
104 int GetTopContainerVerticalOffset(
105 const gfx::Size
& top_container_size
) const override
{
108 ImmersiveRevealedLock
* GetRevealedLock(AnimateReveal animate_reveal
) override
112 void OnFindBarVisibleBoundsChanged(
113 const gfx::Rect
& new_visible_bounds
) override
{}
114 void SetupForTest() override
{}
117 DISALLOW_COPY_AND_ASSIGN(MockImmersiveModeController
);
120 ///////////////////////////////////////////////////////////////////////////////
121 // Tests of BrowserViewLayout. Runs tests without constructing a BrowserView.
122 class BrowserViewLayoutTest
: public BrowserWithTestWindowTest
{
124 BrowserViewLayoutTest()
125 : delegate_(nullptr),
126 top_container_(nullptr),
129 infobar_container_(nullptr),
130 contents_container_(nullptr),
131 contents_web_view_(nullptr),
132 devtools_web_view_(nullptr) {}
133 ~BrowserViewLayoutTest() override
{}
135 BrowserViewLayout
* layout() { return layout_
.get(); }
136 MockBrowserViewLayoutDelegate
* delegate() { return delegate_
; }
137 MockView
* root_view() { return root_view_
.get(); }
138 MockView
* top_container() { return top_container_
; }
139 TabStrip
* tab_strip() { return tab_strip_
; }
140 MockView
* toolbar() { return toolbar_
; }
141 InfoBarContainerView
* infobar_container() { return infobar_container_
; }
142 MockView
* contents_container() { return contents_container_
; }
144 // BrowserWithTestWindowTest overrides:
145 void SetUp() override
{
146 BrowserWithTestWindowTest::SetUp();
148 root_view_
.reset(new MockView(gfx::Size(800, 600)));
150 immersive_mode_controller_
.reset(new MockImmersiveModeController
);
152 top_container_
= new MockView(gfx::Size(800, 60));
153 tab_strip_
= new TabStrip(nullptr);
154 top_container_
->AddChildView(tab_strip_
);
155 toolbar_
= new MockView(gfx::Size(800, 30));
156 top_container_
->AddChildView(toolbar_
);
157 root_view_
->AddChildView(top_container_
);
159 infobar_container_
= new InfoBarContainerView(nullptr);
160 root_view_
->AddChildView(infobar_container_
);
162 contents_web_view_
= new MockView(gfx::Size(800, 600));
163 devtools_web_view_
= new MockView(gfx::Size(800, 600));
164 devtools_web_view_
->SetVisible(false);
166 contents_container_
= new MockView(gfx::Size(800, 600));
167 contents_container_
->AddChildView(devtools_web_view_
);
168 contents_container_
->AddChildView(contents_web_view_
);
169 ContentsLayoutManager
* contents_layout_manager
=
170 new ContentsLayoutManager(devtools_web_view_
, contents_web_view_
);
171 contents_container_
->SetLayoutManager(contents_layout_manager
);
173 root_view_
->AddChildView(contents_container_
);
175 // TODO(jamescook): Attach |layout_| to |root_view_|?
176 layout_
.reset(new BrowserViewLayout
);
177 delegate_
= new MockBrowserViewLayoutDelegate(contents_web_view_
);
178 layout_
->Init(delegate_
,
180 nullptr, // BrowserView.
186 contents_layout_manager
,
187 immersive_mode_controller_
.get());
191 scoped_ptr
<BrowserViewLayout
> layout_
;
192 MockBrowserViewLayoutDelegate
* delegate_
; // Owned by |layout_|.
193 scoped_ptr
<MockView
> root_view_
;
195 // Views owned by |root_view_|.
196 MockView
* top_container_
;
197 TabStrip
* tab_strip_
;
199 InfoBarContainerView
* infobar_container_
;
200 MockView
* contents_container_
;
201 MockView
* contents_web_view_
;
202 MockView
* devtools_web_view_
;
204 scoped_ptr
<MockImmersiveModeController
> immersive_mode_controller_
;
206 DISALLOW_COPY_AND_ASSIGN(BrowserViewLayoutTest
);
209 // Test basic construction and initialization.
210 TEST_F(BrowserViewLayoutTest
, BrowserViewLayout
) {
211 EXPECT_TRUE(layout()->browser());
212 EXPECT_TRUE(layout()->GetWebContentsModalDialogHost());
213 EXPECT_FALSE(layout()->InfobarVisible());
216 // Test the core layout functions.
217 TEST_F(BrowserViewLayoutTest
, Layout
) {
218 // Simulate a window with no interesting UI.
219 delegate()->set_tab_strip_visible(false);
220 delegate()->set_toolbar_visible(false);
221 delegate()->set_bookmark_bar_visible(false);
222 layout()->Layout(root_view());
224 // Top views are zero-height.
225 EXPECT_EQ("0,0 0x0", tab_strip()->bounds().ToString());
226 EXPECT_EQ("0,0 800x0", toolbar()->bounds().ToString());
227 EXPECT_EQ("0,0 800x0", infobar_container()->bounds().ToString());
228 // Contents split fills the window.
229 EXPECT_EQ("0,0 800x600", contents_container()->bounds().ToString());
231 // Turn on the toolbar, like in a pop-up window.
232 delegate()->set_toolbar_visible(true);
233 layout()->Layout(root_view());
235 // Now the toolbar has bounds and other views shift down.
236 EXPECT_EQ("0,0 0x0", tab_strip()->bounds().ToString());
237 EXPECT_EQ("0,0 800x30", toolbar()->bounds().ToString());
238 EXPECT_EQ("0,30 800x0", infobar_container()->bounds().ToString());
239 EXPECT_EQ("0,30 800x570", contents_container()->bounds().ToString());
241 // TODO(jamescook): Tab strip and bookmark bar.
244 TEST_F(BrowserViewLayoutTest
, LayoutDownloadShelf
) {
245 scoped_ptr
<MockView
> download_shelf(new MockView(gfx::Size(800, 50)));
246 layout()->set_download_shelf(download_shelf
.get());
248 // If download shelf doesn't need layout, it doesn't move the bottom edge.
249 delegate()->set_download_shelf_needs_layout(false);
250 const int kBottom
= 500;
251 EXPECT_EQ(kBottom
, layout()->LayoutDownloadShelf(kBottom
));
253 // Download shelf layout moves up the bottom edge and sets visibility.
254 delegate()->set_download_shelf_needs_layout(true);
255 download_shelf
->SetVisible(false);
256 EXPECT_EQ(450, layout()->LayoutDownloadShelf(kBottom
));
257 EXPECT_TRUE(download_shelf
->visible());
258 EXPECT_EQ("0,450 0x50", download_shelf
->bounds().ToString());