immersive_mode_controller_ash_unittest.cc revision f2477e01787aa58f445919b809d89e252beef54f
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/immersive_mode_controller_ash.h"
6
7#include "ash/root_window_controller.h"
8#include "ash/shelf/shelf_layout_manager.h"
9#include "ash/shelf/shelf_types.h"
10#include "ash/shell.h"
11#include "ash/test/ash_test_base.h"
12#include "chrome/app/chrome_command_ids.h"
13#include "chrome/browser/ui/browser_commands.h"
14#include "chrome/browser/ui/fullscreen/fullscreen_controller.h"
15#include "chrome/browser/ui/fullscreen/fullscreen_controller_test.h"
16#include "chrome/browser/ui/views/frame/browser_view.h"
17#include "chrome/browser/ui/views/frame/test_with_browser_view.h"
18#include "chrome/browser/ui/views/frame/top_container_view.h"
19#include "chrome/browser/ui/views/tabs/tab_strip.h"
20#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
21#include "ui/aura/window.h"
22#include "ui/views/controls/webview/webview.h"
23
24// For now, immersive fullscreen is Chrome OS only.
25#if defined(OS_CHROMEOS)
26
27class ImmersiveModeControllerAshTest : public TestWithBrowserView {
28 public:
29  ImmersiveModeControllerAshTest() {}
30  virtual ~ImmersiveModeControllerAshTest() {}
31
32  // TestWithBrowserView override:
33  virtual void SetUp() OVERRIDE {
34    TestWithBrowserView::SetUp();
35
36    browser()->window()->Show();
37
38    controller_ = browser_view()->immersive_mode_controller();
39    controller_->SetupForTest();
40  }
41
42  // Returns the bounds of |view| in widget coordinates.
43  gfx::Rect GetBoundsInWidget(views::View* view) {
44    return view->ConvertRectToWidget(view->GetLocalBounds());
45  }
46
47  // Toggle the browser's fullscreen state.
48  void ToggleFullscreen() {
49    // NOTIFICATION_FULLSCREEN_CHANGED is sent asynchronously. The notification
50    // is used to trigger changes in whether the shelf is auto hidden and
51    // whether a "light bar" version of the tab strip is used when the
52    // top-of-window views are hidden.
53    scoped_ptr<FullscreenNotificationObserver> waiter(
54        new FullscreenNotificationObserver());
55    chrome::ToggleFullscreenMode(browser());
56    waiter->Wait();
57  }
58
59  // Set whether the browser is in tab fullscreen.
60  void SetTabFullscreen(bool tab_fullscreen) {
61    content::WebContents* web_contents =
62        browser_view()->GetContentsWebViewForTest()->GetWebContents();
63    scoped_ptr<FullscreenNotificationObserver> waiter(
64        new FullscreenNotificationObserver());
65    browser()->fullscreen_controller()->ToggleFullscreenModeForTab(
66        web_contents, tab_fullscreen);
67    waiter->Wait();
68  }
69
70  // Attempt revealing the top-of-window views.
71  void AttemptReveal() {
72    if (!revealed_lock_.get()) {
73      revealed_lock_.reset(controller_->GetRevealedLock(
74          ImmersiveModeControllerAsh::ANIMATE_REVEAL_NO));
75    }
76  }
77
78  // Attempt unrevealing the top-of-window views.
79  void AttemptUnreveal() {
80    revealed_lock_.reset();
81  }
82
83  ImmersiveModeController* controller() { return controller_; }
84
85 private:
86  // Not owned.
87  ImmersiveModeController* controller_;
88
89  scoped_ptr<ImmersiveRevealedLock> revealed_lock_;
90
91  DISALLOW_COPY_AND_ASSIGN(ImmersiveModeControllerAshTest);
92};
93
94// Test the layout and visibility of the tabstrip, toolbar and TopContainerView
95// in immersive fullscreen.
96TEST_F(ImmersiveModeControllerAshTest, Layout) {
97  AddTab(browser(), GURL("about:blank"));
98
99  TabStrip* tabstrip = browser_view()->tabstrip();
100  ToolbarView* toolbar = browser_view()->toolbar();
101  views::WebView* contents_web_view =
102      browser_view()->GetContentsWebViewForTest();
103
104  // Immersive fullscreen starts out disabled.
105  ASSERT_FALSE(browser_view()->GetWidget()->IsFullscreen());
106  ASSERT_FALSE(controller()->IsEnabled());
107
108  // By default, the tabstrip and toolbar should be visible.
109  EXPECT_TRUE(tabstrip->visible());
110  EXPECT_TRUE(toolbar->visible());
111
112  ToggleFullscreen();
113  EXPECT_TRUE(browser_view()->GetWidget()->IsFullscreen());
114  EXPECT_TRUE(controller()->IsEnabled());
115  EXPECT_FALSE(controller()->IsRevealed());
116
117  // Entering immersive fullscreen should make the tab strip use the immersive
118  // style and hide the toolbar.
119  EXPECT_TRUE(tabstrip->visible());
120  EXPECT_TRUE(tabstrip->IsImmersiveStyle());
121  EXPECT_FALSE(toolbar->visible());
122
123  // The tab indicators should be flush with the top of the widget.
124  EXPECT_EQ(0, GetBoundsInWidget(tabstrip).y());
125
126  // The web contents should be immediately below the tab indicators.
127  EXPECT_EQ(Tab::GetImmersiveHeight(),
128            GetBoundsInWidget(contents_web_view).y());
129
130  // Revealing the top-of-window views should set the tab strip back to the
131  // normal style and show the toolbar.
132  AttemptReveal();
133  EXPECT_TRUE(controller()->IsRevealed());
134  EXPECT_TRUE(tabstrip->visible());
135  EXPECT_FALSE(tabstrip->IsImmersiveStyle());
136  EXPECT_TRUE(toolbar->visible());
137
138  // The TopContainerView should be flush with the top edge of the widget. If
139  // it is not flush with the top edge the immersive reveal animation looks
140  // wonky.
141  EXPECT_EQ(0, GetBoundsInWidget(browser_view()->top_container()).y());
142
143  // The web contents should be at the same y position as they were when the
144  // top-of-window views were hidden.
145  EXPECT_EQ(Tab::GetImmersiveHeight(),
146            GetBoundsInWidget(contents_web_view).y());
147
148  // Repeat the test for when in both immersive fullscreen and tab fullscreen.
149  SetTabFullscreen(true);
150  // Hide and reveal the top-of-window views so that they get relain out.
151  AttemptUnreveal();
152  AttemptReveal();
153
154  // The tab strip and toolbar should still be visible and the TopContainerView
155  // should still be flush with the top edge of the widget.
156  EXPECT_TRUE(controller()->IsRevealed());
157  EXPECT_TRUE(tabstrip->visible());
158  EXPECT_FALSE(tabstrip->IsImmersiveStyle());
159  EXPECT_TRUE(toolbar->visible());
160  EXPECT_EQ(0, GetBoundsInWidget(browser_view()->top_container()).y());
161
162  // The web contents should be flush with the top edge of the widget when in
163  // both immersive and tab fullscreen.
164  EXPECT_EQ(0, GetBoundsInWidget(contents_web_view).y());
165
166  // Hide the top-of-window views. Both the tab strip and the toolbar should
167  // hide when in both immersive and tab fullscreen.
168  AttemptUnreveal();
169  EXPECT_FALSE(controller()->IsRevealed());
170  EXPECT_FALSE(tabstrip->visible());
171  EXPECT_FALSE(toolbar->visible());
172
173  // The web contents should still be flush with the edge of the widget.
174  EXPECT_EQ(0, GetBoundsInWidget(contents_web_view).y());
175
176  // Exiting both immersive and tab fullscreen should show the tab strip and
177  // toolbar.
178  ToggleFullscreen();
179  EXPECT_FALSE(browser_view()->GetWidget()->IsFullscreen());
180  EXPECT_FALSE(controller()->IsEnabled());
181  EXPECT_FALSE(controller()->IsRevealed());
182  EXPECT_TRUE(tabstrip->visible());
183  EXPECT_FALSE(tabstrip->IsImmersiveStyle());
184  EXPECT_TRUE(toolbar->visible());
185}
186
187// Test that the browser commands which are usually disabled in fullscreen are
188// are enabled in immersive fullscreen.
189TEST_F(ImmersiveModeControllerAshTest, EnabledCommands) {
190  ASSERT_FALSE(controller()->IsEnabled());
191  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_OPEN_CURRENT_URL));
192  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ABOUT));
193  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_FOCUS_LOCATION));
194
195  ToggleFullscreen();
196  EXPECT_TRUE(controller()->IsEnabled());
197  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_OPEN_CURRENT_URL));
198  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ABOUT));
199  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_FOCUS_LOCATION));
200}
201
202// Test that restoring a window properly exits immersive fullscreen.
203TEST_F(ImmersiveModeControllerAshTest, ExitUponRestore) {
204  ASSERT_FALSE(controller()->IsEnabled());
205  ToggleFullscreen();
206  AttemptReveal();
207  ASSERT_TRUE(controller()->IsEnabled());
208  ASSERT_TRUE(controller()->IsRevealed());
209  ASSERT_TRUE(browser_view()->GetWidget()->IsFullscreen());
210
211  browser_view()->GetWidget()->Restore();
212  EXPECT_FALSE(controller()->IsEnabled());
213}
214
215// Test how being simultaneously in tab fullscreen and immersive fullscreen
216// affects the shelf visibility and whether the tab indicators are hidden.
217TEST_F(ImmersiveModeControllerAshTest, TabAndBrowserFullscreen) {
218  AddTab(browser(), GURL("about:blank"));
219
220  // The shelf should start out as visible.
221  ash::internal::ShelfLayoutManager* shelf =
222      ash::Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager();
223  ASSERT_EQ(ash::SHELF_VISIBLE, shelf->visibility_state());
224
225  // 1) Test that entering tab fullscreen from immersive fullscreen hides the
226  // tab indicators and the shelf.
227  ToggleFullscreen();
228  ASSERT_TRUE(controller()->IsEnabled());
229  EXPECT_EQ(ash::SHELF_AUTO_HIDE, shelf->visibility_state());
230  EXPECT_FALSE(controller()->ShouldHideTabIndicators());
231
232  SetTabFullscreen(true);
233  ASSERT_TRUE(controller()->IsEnabled());
234  EXPECT_EQ(ash::SHELF_HIDDEN, shelf->visibility_state());
235  EXPECT_TRUE(controller()->ShouldHideTabIndicators());
236
237  // 2) Test that exiting tab fullscreen shows the tab indicators and autohides
238  // the shelf.
239  SetTabFullscreen(false);
240  ASSERT_TRUE(controller()->IsEnabled());
241  EXPECT_EQ(ash::SHELF_AUTO_HIDE, shelf->visibility_state());
242  EXPECT_FALSE(controller()->ShouldHideTabIndicators());
243
244  // 3) Test that exiting tab fullscreen and immersive fullscreen
245  // simultaneously correctly updates the shelf visibility and whether the tab
246  // indicators should be hidden.
247  SetTabFullscreen(true);
248  ToggleFullscreen();
249  ASSERT_FALSE(controller()->IsEnabled());
250  EXPECT_EQ(ash::SHELF_VISIBLE, shelf->visibility_state());
251  EXPECT_TRUE(controller()->ShouldHideTabIndicators());
252}
253
254#endif  // defined(OS_CHROMEOS)
255