Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / ui / views / frame / immersive_mode_controller_ash_unittest.cc
blob2a276791eecda434ec99381e20a593a23a25f5c2
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/immersive_mode_controller_ash.h"
7 #include "ash/ash_switches.h"
8 #include "ash/root_window_controller.h"
9 #include "ash/shelf/shelf_layout_manager.h"
10 #include "ash/shelf/shelf_types.h"
11 #include "ash/shell.h"
12 #include "ash/test/ash_test_base.h"
13 #include "base/command_line.h"
14 #include "chrome/app/chrome_command_ids.h"
15 #include "chrome/browser/ui/browser_commands.h"
16 #include "chrome/browser/ui/exclusive_access/fullscreen_controller.h"
17 #include "chrome/browser/ui/exclusive_access/fullscreen_controller_test.h"
18 #include "chrome/browser/ui/views/frame/browser_view.h"
19 #include "chrome/browser/ui/views/frame/test_with_browser_view.h"
20 #include "chrome/browser/ui/views/frame/top_container_view.h"
21 #include "chrome/browser/ui/views/tabs/tab_strip.h"
22 #include "chrome/browser/ui/views/toolbar/toolbar_view.h"
23 #include "ui/aura/window.h"
24 #include "ui/views/controls/webview/webview.h"
26 class ImmersiveModeControllerAshTest : public TestWithBrowserView {
27 public:
28 ImmersiveModeControllerAshTest()
29 : TestWithBrowserView(Browser::TYPE_TABBED,
30 chrome::HOST_DESKTOP_TYPE_ASH,
31 false) {
33 ImmersiveModeControllerAshTest(
34 Browser::Type browser_type,
35 chrome::HostDesktopType host_desktop_type,
36 bool hosted_app)
37 : TestWithBrowserView(browser_type,
38 host_desktop_type,
39 hosted_app) {
41 ~ImmersiveModeControllerAshTest() override {}
43 // TestWithBrowserView override:
44 void SetUp() override {
45 TestWithBrowserView::SetUp();
47 browser()->window()->Show();
49 controller_ = browser_view()->immersive_mode_controller();
50 controller_->SetupForTest();
53 // Returns the bounds of |view| in widget coordinates.
54 gfx::Rect GetBoundsInWidget(views::View* view) {
55 return view->ConvertRectToWidget(view->GetLocalBounds());
58 // Toggle the browser's fullscreen state.
59 void ToggleFullscreen() {
60 // NOTIFICATION_FULLSCREEN_CHANGED is sent asynchronously. The notification
61 // is used to trigger changes in whether the shelf is auto hidden and
62 // whether a "light bar" version of the tab strip is used when the
63 // top-of-window views are hidden.
64 scoped_ptr<FullscreenNotificationObserver> waiter(
65 new FullscreenNotificationObserver());
66 chrome::ToggleFullscreenMode(browser());
67 waiter->Wait();
70 // Set whether the browser is in tab fullscreen.
71 void SetTabFullscreen(bool tab_fullscreen) {
72 content::WebContents* web_contents =
73 browser_view()->GetContentsWebViewForTest()->GetWebContents();
74 scoped_ptr<FullscreenNotificationObserver> waiter(
75 new FullscreenNotificationObserver());
76 if (tab_fullscreen) {
77 browser()
78 ->exclusive_access_manager()
79 ->fullscreen_controller()
80 ->EnterFullscreenModeForTab(web_contents, GURL());
81 } else {
82 browser()
83 ->exclusive_access_manager()
84 ->fullscreen_controller()
85 ->ExitFullscreenModeForTab(web_contents);
87 waiter->Wait();
90 // Attempt revealing the top-of-window views.
91 void AttemptReveal() {
92 if (!revealed_lock_.get()) {
93 revealed_lock_.reset(controller_->GetRevealedLock(
94 ImmersiveModeControllerAsh::ANIMATE_REVEAL_NO));
98 // Attempt unrevealing the top-of-window views.
99 void AttemptUnreveal() {
100 revealed_lock_.reset();
103 ImmersiveModeController* controller() { return controller_; }
105 private:
106 // Not owned.
107 ImmersiveModeController* controller_;
109 scoped_ptr<ImmersiveRevealedLock> revealed_lock_;
111 DISALLOW_COPY_AND_ASSIGN(ImmersiveModeControllerAshTest);
114 // Test the layout and visibility of the tabstrip, toolbar and TopContainerView
115 // in immersive fullscreen.
116 TEST_F(ImmersiveModeControllerAshTest, Layout) {
117 AddTab(browser(), GURL("about:blank"));
119 TabStrip* tabstrip = browser_view()->tabstrip();
120 ToolbarView* toolbar = browser_view()->toolbar();
121 views::WebView* contents_web_view =
122 browser_view()->GetContentsWebViewForTest();
124 // Immersive fullscreen starts out disabled.
125 ASSERT_FALSE(browser_view()->GetWidget()->IsFullscreen());
126 ASSERT_FALSE(controller()->IsEnabled());
128 // By default, the tabstrip and toolbar should be visible.
129 EXPECT_TRUE(tabstrip->visible());
130 EXPECT_TRUE(toolbar->visible());
132 ToggleFullscreen();
133 EXPECT_TRUE(browser_view()->GetWidget()->IsFullscreen());
134 EXPECT_TRUE(controller()->IsEnabled());
135 EXPECT_FALSE(controller()->IsRevealed());
137 // Entering immersive fullscreen should make the tab strip use the immersive
138 // style and hide the toolbar.
139 EXPECT_TRUE(tabstrip->visible());
140 EXPECT_TRUE(tabstrip->IsImmersiveStyle());
141 EXPECT_FALSE(toolbar->visible());
143 // The tab indicators should be flush with the top of the widget.
144 EXPECT_EQ(0, GetBoundsInWidget(tabstrip).y());
146 // The web contents should be immediately below the tab indicators.
147 EXPECT_EQ(Tab::GetImmersiveHeight(),
148 GetBoundsInWidget(contents_web_view).y());
150 // Revealing the top-of-window views should set the tab strip back to the
151 // normal style and show the toolbar.
152 AttemptReveal();
153 EXPECT_TRUE(controller()->IsRevealed());
154 EXPECT_TRUE(tabstrip->visible());
155 EXPECT_FALSE(tabstrip->IsImmersiveStyle());
156 EXPECT_TRUE(toolbar->visible());
158 // The TopContainerView should be flush with the top edge of the widget. If
159 // it is not flush with the top edge the immersive reveal animation looks
160 // wonky.
161 EXPECT_EQ(0, GetBoundsInWidget(browser_view()->top_container()).y());
163 // The web contents should be at the same y position as they were when the
164 // top-of-window views were hidden.
165 EXPECT_EQ(Tab::GetImmersiveHeight(),
166 GetBoundsInWidget(contents_web_view).y());
168 // Repeat the test for when in both immersive fullscreen and tab fullscreen.
169 SetTabFullscreen(true);
170 // Hide and reveal the top-of-window views so that they get relain out.
171 AttemptUnreveal();
172 AttemptReveal();
174 // The tab strip and toolbar should still be visible and the TopContainerView
175 // should still be flush with the top edge of the widget.
176 EXPECT_TRUE(controller()->IsRevealed());
177 EXPECT_TRUE(tabstrip->visible());
178 EXPECT_FALSE(tabstrip->IsImmersiveStyle());
179 EXPECT_TRUE(toolbar->visible());
180 EXPECT_EQ(0, GetBoundsInWidget(browser_view()->top_container()).y());
182 // The web contents should be flush with the top edge of the widget when in
183 // both immersive and tab fullscreen.
184 EXPECT_EQ(0, GetBoundsInWidget(contents_web_view).y());
186 // Hide the top-of-window views. Both the tab strip and the toolbar should
187 // hide when in both immersive and tab fullscreen.
188 AttemptUnreveal();
189 EXPECT_FALSE(controller()->IsRevealed());
190 EXPECT_FALSE(tabstrip->visible());
191 EXPECT_FALSE(toolbar->visible());
193 // The web contents should still be flush with the edge of the widget.
194 EXPECT_EQ(0, GetBoundsInWidget(contents_web_view).y());
196 // Exiting both immersive and tab fullscreen should show the tab strip and
197 // toolbar.
198 ToggleFullscreen();
199 EXPECT_FALSE(browser_view()->GetWidget()->IsFullscreen());
200 EXPECT_FALSE(controller()->IsEnabled());
201 EXPECT_FALSE(controller()->IsRevealed());
202 EXPECT_TRUE(tabstrip->visible());
203 EXPECT_FALSE(tabstrip->IsImmersiveStyle());
204 EXPECT_TRUE(toolbar->visible());
207 // Test that the browser commands which are usually disabled in fullscreen are
208 // are enabled in immersive fullscreen.
209 TEST_F(ImmersiveModeControllerAshTest, EnabledCommands) {
210 ASSERT_FALSE(controller()->IsEnabled());
211 EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_OPEN_CURRENT_URL));
212 EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ABOUT));
213 EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_FOCUS_LOCATION));
215 ToggleFullscreen();
216 EXPECT_TRUE(controller()->IsEnabled());
217 EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_OPEN_CURRENT_URL));
218 EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ABOUT));
219 EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_FOCUS_LOCATION));
222 // Test that restoring a window properly exits immersive fullscreen.
223 TEST_F(ImmersiveModeControllerAshTest, ExitUponRestore) {
224 ASSERT_FALSE(controller()->IsEnabled());
225 ToggleFullscreen();
226 AttemptReveal();
227 ASSERT_TRUE(controller()->IsEnabled());
228 ASSERT_TRUE(controller()->IsRevealed());
229 ASSERT_TRUE(browser_view()->GetWidget()->IsFullscreen());
231 browser_view()->GetWidget()->Restore();
232 EXPECT_FALSE(controller()->IsEnabled());
235 // Test how being simultaneously in tab fullscreen and immersive fullscreen
236 // affects the shelf visibility and whether the tab indicators are hidden.
237 TEST_F(ImmersiveModeControllerAshTest, TabAndBrowserFullscreen) {
238 AddTab(browser(), GURL("about:blank"));
240 // The shelf should start out as visible.
241 ash::ShelfLayoutManager* shelf =
242 ash::Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager();
243 ASSERT_EQ(ash::SHELF_VISIBLE, shelf->visibility_state());
245 // 1) Test that entering tab fullscreen from immersive fullscreen hides the
246 // tab indicators and the shelf.
247 ToggleFullscreen();
248 ASSERT_TRUE(controller()->IsEnabled());
249 EXPECT_EQ(ash::SHELF_AUTO_HIDE, shelf->visibility_state());
250 EXPECT_FALSE(controller()->ShouldHideTabIndicators());
252 SetTabFullscreen(true);
253 ASSERT_TRUE(controller()->IsEnabled());
254 EXPECT_EQ(ash::SHELF_HIDDEN, shelf->visibility_state());
255 EXPECT_TRUE(controller()->ShouldHideTabIndicators());
257 // 2) Test that exiting tab fullscreen shows the tab indicators and autohides
258 // the shelf.
259 SetTabFullscreen(false);
260 ASSERT_TRUE(controller()->IsEnabled());
261 EXPECT_EQ(ash::SHELF_AUTO_HIDE, shelf->visibility_state());
262 EXPECT_FALSE(controller()->ShouldHideTabIndicators());
264 // 3) Test that exiting tab fullscreen and immersive fullscreen
265 // simultaneously correctly updates the shelf visibility and whether the tab
266 // indicators should be hidden.
267 SetTabFullscreen(true);
268 ToggleFullscreen();
269 ASSERT_FALSE(controller()->IsEnabled());
270 EXPECT_EQ(ash::SHELF_VISIBLE, shelf->visibility_state());
271 EXPECT_TRUE(controller()->ShouldHideTabIndicators());
274 class ImmersiveModeControllerAshTestHostedApp
275 : public ImmersiveModeControllerAshTest {
276 public:
277 ImmersiveModeControllerAshTestHostedApp()
278 : ImmersiveModeControllerAshTest(Browser::TYPE_POPUP,
279 chrome::HOST_DESKTOP_TYPE_ASH,
280 true) {
282 ~ImmersiveModeControllerAshTestHostedApp() override {}
284 private:
285 DISALLOW_COPY_AND_ASSIGN(ImmersiveModeControllerAshTestHostedApp);
288 // Test the layout and visibility of the TopContainerView and web contents when
289 // a hosted app is put into immersive fullscreen.
290 TEST_F(ImmersiveModeControllerAshTestHostedApp, Layout) {
291 // Add a tab because the browser starts out without any tabs at all.
292 AddTab(browser(), GURL("about:blank"));
294 TabStrip* tabstrip = browser_view()->tabstrip();
295 ToolbarView* toolbar = browser_view()->toolbar();
296 views::WebView* contents_web_view =
297 browser_view()->GetContentsWebViewForTest();
298 views::View* top_container = browser_view()->top_container();
300 // Immersive fullscreen starts out disabled.
301 ASSERT_FALSE(browser_view()->GetWidget()->IsFullscreen());
302 ASSERT_FALSE(controller()->IsEnabled());
304 // The tabstrip and toolbar are not visible for hosted apps.
305 EXPECT_FALSE(tabstrip->visible());
306 EXPECT_FALSE(toolbar->visible());
308 // The window header should be above the web contents.
309 int header_height = GetBoundsInWidget(contents_web_view).y();
311 ToggleFullscreen();
312 EXPECT_TRUE(browser_view()->GetWidget()->IsFullscreen());
313 EXPECT_TRUE(controller()->IsEnabled());
314 EXPECT_FALSE(controller()->IsRevealed());
316 // Entering immersive fullscreen should make the web contents flush with the
317 // top of the widget.
318 EXPECT_FALSE(tabstrip->visible());
319 EXPECT_FALSE(toolbar->visible());
320 EXPECT_TRUE(top_container->GetVisibleBounds().IsEmpty());
321 EXPECT_EQ(0, GetBoundsInWidget(contents_web_view).y());
323 // Reveal the window header.
324 AttemptReveal();
326 // The tabstrip and toolbar should still be hidden and the web contents should
327 // still be flush with the top of the screen.
328 EXPECT_FALSE(tabstrip->visible());
329 EXPECT_FALSE(toolbar->visible());
330 EXPECT_EQ(0, GetBoundsInWidget(contents_web_view).y());
332 // During an immersive reveal, the window header should be painted to the
333 // TopContainerView. The TopContainerView should be flush with the top of the
334 // widget and have |header_height|.
335 gfx::Rect top_container_bounds_in_widget(GetBoundsInWidget(top_container));
336 EXPECT_EQ(0, top_container_bounds_in_widget.y());
337 EXPECT_EQ(header_height, top_container_bounds_in_widget.height());
339 // Exit immersive fullscreen. The web contents should be back below the window
340 // header.
341 ToggleFullscreen();
342 EXPECT_FALSE(browser_view()->GetWidget()->IsFullscreen());
343 EXPECT_FALSE(controller()->IsEnabled());
344 EXPECT_FALSE(tabstrip->visible());
345 EXPECT_FALSE(toolbar->visible());
346 EXPECT_EQ(header_height, GetBoundsInWidget(contents_web_view).y());