Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / views / frame / immersive_mode_controller_ash_unittest.cc
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/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/fullscreen/fullscreen_controller.h"
17 #include "chrome/browser/ui/fullscreen/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"
25
26 class ImmersiveModeControllerAshTest : public TestWithBrowserView {
27  public:
28   ImmersiveModeControllerAshTest()
29       : TestWithBrowserView(Browser::TYPE_TABBED,
30                             chrome::HOST_DESKTOP_TYPE_ASH,
31                             false) {
32   }
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) {
40   }
41   virtual ~ImmersiveModeControllerAshTest() {}
42
43   // TestWithBrowserView override:
44   virtual void SetUp() OVERRIDE {
45     TestWithBrowserView::SetUp();
46
47     browser()->window()->Show();
48
49     controller_ = browser_view()->immersive_mode_controller();
50     controller_->SetupForTest();
51   }
52
53   // Returns the bounds of |view| in widget coordinates.
54   gfx::Rect GetBoundsInWidget(views::View* view) {
55     return view->ConvertRectToWidget(view->GetLocalBounds());
56   }
57
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();
68   }
69
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     browser()->fullscreen_controller()->ToggleFullscreenModeForTab(
77         web_contents, tab_fullscreen);
78     waiter->Wait();
79   }
80
81   // Attempt revealing the top-of-window views.
82   void AttemptReveal() {
83     if (!revealed_lock_.get()) {
84       revealed_lock_.reset(controller_->GetRevealedLock(
85           ImmersiveModeControllerAsh::ANIMATE_REVEAL_NO));
86     }
87   }
88
89   // Attempt unrevealing the top-of-window views.
90   void AttemptUnreveal() {
91     revealed_lock_.reset();
92   }
93
94   ImmersiveModeController* controller() { return controller_; }
95
96  private:
97   // Not owned.
98   ImmersiveModeController* controller_;
99
100   scoped_ptr<ImmersiveRevealedLock> revealed_lock_;
101
102   DISALLOW_COPY_AND_ASSIGN(ImmersiveModeControllerAshTest);
103 };
104
105 // Test the layout and visibility of the tabstrip, toolbar and TopContainerView
106 // in immersive fullscreen.
107 TEST_F(ImmersiveModeControllerAshTest, Layout) {
108   AddTab(browser(), GURL("about:blank"));
109
110   TabStrip* tabstrip = browser_view()->tabstrip();
111   ToolbarView* toolbar = browser_view()->toolbar();
112   views::WebView* contents_web_view =
113       browser_view()->GetContentsWebViewForTest();
114
115   // Immersive fullscreen starts out disabled.
116   ASSERT_FALSE(browser_view()->GetWidget()->IsFullscreen());
117   ASSERT_FALSE(controller()->IsEnabled());
118
119   // By default, the tabstrip and toolbar should be visible.
120   EXPECT_TRUE(tabstrip->visible());
121   EXPECT_TRUE(toolbar->visible());
122
123   ToggleFullscreen();
124   EXPECT_TRUE(browser_view()->GetWidget()->IsFullscreen());
125   EXPECT_TRUE(controller()->IsEnabled());
126   EXPECT_FALSE(controller()->IsRevealed());
127
128   // Entering immersive fullscreen should make the tab strip use the immersive
129   // style and hide the toolbar.
130   EXPECT_TRUE(tabstrip->visible());
131   EXPECT_TRUE(tabstrip->IsImmersiveStyle());
132   EXPECT_FALSE(toolbar->visible());
133
134   // The tab indicators should be flush with the top of the widget.
135   EXPECT_EQ(0, GetBoundsInWidget(tabstrip).y());
136
137   // The web contents should be immediately below the tab indicators.
138   EXPECT_EQ(Tab::GetImmersiveHeight(),
139             GetBoundsInWidget(contents_web_view).y());
140
141   // Revealing the top-of-window views should set the tab strip back to the
142   // normal style and show the toolbar.
143   AttemptReveal();
144   EXPECT_TRUE(controller()->IsRevealed());
145   EXPECT_TRUE(tabstrip->visible());
146   EXPECT_FALSE(tabstrip->IsImmersiveStyle());
147   EXPECT_TRUE(toolbar->visible());
148
149   // The TopContainerView should be flush with the top edge of the widget. If
150   // it is not flush with the top edge the immersive reveal animation looks
151   // wonky.
152   EXPECT_EQ(0, GetBoundsInWidget(browser_view()->top_container()).y());
153
154   // The web contents should be at the same y position as they were when the
155   // top-of-window views were hidden.
156   EXPECT_EQ(Tab::GetImmersiveHeight(),
157             GetBoundsInWidget(contents_web_view).y());
158
159   // Repeat the test for when in both immersive fullscreen and tab fullscreen.
160   SetTabFullscreen(true);
161   // Hide and reveal the top-of-window views so that they get relain out.
162   AttemptUnreveal();
163   AttemptReveal();
164
165   // The tab strip and toolbar should still be visible and the TopContainerView
166   // should still be flush with the top edge of the widget.
167   EXPECT_TRUE(controller()->IsRevealed());
168   EXPECT_TRUE(tabstrip->visible());
169   EXPECT_FALSE(tabstrip->IsImmersiveStyle());
170   EXPECT_TRUE(toolbar->visible());
171   EXPECT_EQ(0, GetBoundsInWidget(browser_view()->top_container()).y());
172
173   // The web contents should be flush with the top edge of the widget when in
174   // both immersive and tab fullscreen.
175   EXPECT_EQ(0, GetBoundsInWidget(contents_web_view).y());
176
177   // Hide the top-of-window views. Both the tab strip and the toolbar should
178   // hide when in both immersive and tab fullscreen.
179   AttemptUnreveal();
180   EXPECT_FALSE(controller()->IsRevealed());
181   EXPECT_FALSE(tabstrip->visible());
182   EXPECT_FALSE(toolbar->visible());
183
184   // The web contents should still be flush with the edge of the widget.
185   EXPECT_EQ(0, GetBoundsInWidget(contents_web_view).y());
186
187   // Exiting both immersive and tab fullscreen should show the tab strip and
188   // toolbar.
189   ToggleFullscreen();
190   EXPECT_FALSE(browser_view()->GetWidget()->IsFullscreen());
191   EXPECT_FALSE(controller()->IsEnabled());
192   EXPECT_FALSE(controller()->IsRevealed());
193   EXPECT_TRUE(tabstrip->visible());
194   EXPECT_FALSE(tabstrip->IsImmersiveStyle());
195   EXPECT_TRUE(toolbar->visible());
196 }
197
198 // Test that the browser commands which are usually disabled in fullscreen are
199 // are enabled in immersive fullscreen.
200 TEST_F(ImmersiveModeControllerAshTest, EnabledCommands) {
201   ASSERT_FALSE(controller()->IsEnabled());
202   EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_OPEN_CURRENT_URL));
203   EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ABOUT));
204   EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_FOCUS_LOCATION));
205
206   ToggleFullscreen();
207   EXPECT_TRUE(controller()->IsEnabled());
208   EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_OPEN_CURRENT_URL));
209   EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ABOUT));
210   EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_FOCUS_LOCATION));
211 }
212
213 // Test that restoring a window properly exits immersive fullscreen.
214 TEST_F(ImmersiveModeControllerAshTest, ExitUponRestore) {
215   ASSERT_FALSE(controller()->IsEnabled());
216   ToggleFullscreen();
217   AttemptReveal();
218   ASSERT_TRUE(controller()->IsEnabled());
219   ASSERT_TRUE(controller()->IsRevealed());
220   ASSERT_TRUE(browser_view()->GetWidget()->IsFullscreen());
221
222   browser_view()->GetWidget()->Restore();
223   EXPECT_FALSE(controller()->IsEnabled());
224 }
225
226 // Test how being simultaneously in tab fullscreen and immersive fullscreen
227 // affects the shelf visibility and whether the tab indicators are hidden.
228 TEST_F(ImmersiveModeControllerAshTest, TabAndBrowserFullscreen) {
229   AddTab(browser(), GURL("about:blank"));
230
231   // The shelf should start out as visible.
232   ash::internal::ShelfLayoutManager* shelf =
233       ash::Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager();
234   ASSERT_EQ(ash::SHELF_VISIBLE, shelf->visibility_state());
235
236   // 1) Test that entering tab fullscreen from immersive fullscreen hides the
237   // tab indicators and the shelf.
238   ToggleFullscreen();
239   ASSERT_TRUE(controller()->IsEnabled());
240   EXPECT_EQ(ash::SHELF_AUTO_HIDE, shelf->visibility_state());
241   EXPECT_FALSE(controller()->ShouldHideTabIndicators());
242
243   SetTabFullscreen(true);
244   ASSERT_TRUE(controller()->IsEnabled());
245   EXPECT_EQ(ash::SHELF_HIDDEN, shelf->visibility_state());
246   EXPECT_TRUE(controller()->ShouldHideTabIndicators());
247
248   // 2) Test that exiting tab fullscreen shows the tab indicators and autohides
249   // the shelf.
250   SetTabFullscreen(false);
251   ASSERT_TRUE(controller()->IsEnabled());
252   EXPECT_EQ(ash::SHELF_AUTO_HIDE, shelf->visibility_state());
253   EXPECT_FALSE(controller()->ShouldHideTabIndicators());
254
255   // 3) Test that exiting tab fullscreen and immersive fullscreen
256   // simultaneously correctly updates the shelf visibility and whether the tab
257   // indicators should be hidden.
258   SetTabFullscreen(true);
259   ToggleFullscreen();
260   ASSERT_FALSE(controller()->IsEnabled());
261   EXPECT_EQ(ash::SHELF_VISIBLE, shelf->visibility_state());
262   EXPECT_TRUE(controller()->ShouldHideTabIndicators());
263 }
264
265 class ImmersiveModeControllerAshTestHostedApp
266     : public ImmersiveModeControllerAshTest {
267  public:
268   ImmersiveModeControllerAshTestHostedApp()
269       : ImmersiveModeControllerAshTest(Browser::TYPE_POPUP,
270                                        chrome::HOST_DESKTOP_TYPE_ASH,
271                                        true) {
272   }
273   virtual ~ImmersiveModeControllerAshTestHostedApp() {}
274
275   // ImmersiveModeControllerAshTest override:
276   virtual void SetUp() OVERRIDE {
277     CommandLine::ForCurrentProcess()->AppendSwitch(
278         ash::switches::kAshEnableImmersiveFullscreenForAllWindows);
279     ImmersiveModeControllerAshTest::SetUp();
280   }
281
282  private:
283   DISALLOW_COPY_AND_ASSIGN(ImmersiveModeControllerAshTestHostedApp);
284 };
285
286 // Test the layout and visibility of the TopContainerView and web contents when
287 // a hosted app is put into immersive fullscreen.
288 TEST_F(ImmersiveModeControllerAshTestHostedApp, Layout) {
289   // Add a tab because the browser starts out without any tabs at all.
290   AddTab(browser(), GURL("about:blank"));
291
292   TabStrip* tabstrip = browser_view()->tabstrip();
293   ToolbarView* toolbar = browser_view()->toolbar();
294   views::WebView* contents_web_view =
295       browser_view()->GetContentsWebViewForTest();
296   views::View* top_container = browser_view()->top_container();
297
298   // Immersive fullscreen starts out disabled.
299   ASSERT_FALSE(browser_view()->GetWidget()->IsFullscreen());
300   ASSERT_FALSE(controller()->IsEnabled());
301
302   // The tabstrip and toolbar are not visible for hosted apps.
303   EXPECT_FALSE(tabstrip->visible());
304   EXPECT_FALSE(toolbar->visible());
305
306   // The window header should be above the web contents.
307   int header_height = GetBoundsInWidget(contents_web_view).y();
308
309   ToggleFullscreen();
310   EXPECT_TRUE(browser_view()->GetWidget()->IsFullscreen());
311   EXPECT_TRUE(controller()->IsEnabled());
312   EXPECT_FALSE(controller()->IsRevealed());
313
314   // Entering immersive fullscreen should make the web contents flush with the
315   // top of the widget.
316   EXPECT_FALSE(tabstrip->visible());
317   EXPECT_FALSE(toolbar->visible());
318   EXPECT_TRUE(top_container->GetVisibleBounds().IsEmpty());
319   EXPECT_EQ(0, GetBoundsInWidget(contents_web_view).y());
320
321   // Reveal the window header.
322   AttemptReveal();
323
324   // The tabstrip and toolbar should still be hidden and the web contents should
325   // still be flush with the top of the screen.
326   EXPECT_FALSE(tabstrip->visible());
327   EXPECT_FALSE(toolbar->visible());
328   EXPECT_EQ(0, GetBoundsInWidget(contents_web_view).y());
329
330   // During an immersive reveal, the window header should be painted to the
331   // TopContainerView. The TopContainerView should be flush with the top of the
332   // widget and have |header_height|.
333   gfx::Rect top_container_bounds_in_widget(GetBoundsInWidget(top_container));
334   EXPECT_EQ(0, top_container_bounds_in_widget.y());
335   EXPECT_EQ(header_height, top_container_bounds_in_widget.height());
336
337   // Exit immersive fullscreen. The web contents should be back below the window
338   // header.
339   ToggleFullscreen();
340   EXPECT_FALSE(browser_view()->GetWidget()->IsFullscreen());
341   EXPECT_FALSE(controller()->IsEnabled());
342   EXPECT_FALSE(tabstrip->visible());
343   EXPECT_FALSE(toolbar->visible());
344   EXPECT_EQ(header_height, GetBoundsInWidget(contents_web_view).y());
345 }