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 "ash/accelerators/accelerator_commands.h" 6 7 #include "apps/app_window.h" 8 #include "apps/ui/native_app_window.h" 9 #include "ash/ash_switches.h" 10 #include "ash/shell.h" 11 #include "ash/wm/window_state.h" 12 #include "base/command_line.h" 13 #include "chrome/browser/apps/app_browsertest_util.h" 14 #include "chrome/browser/ui/browser.h" 15 #include "chrome/browser/ui/browser_commands.h" 16 #include "chrome/browser/ui/browser_finder.h" 17 #include "chrome/browser/ui/browser_window.h" 18 #include "chrome/common/chrome_switches.h" 19 #include "chrome/test/base/in_process_browser_test.h" 20 #include "chrome/test/base/test_switches.h" 21 #include "ui/aura/client/aura_constants.h" 22 #include "ui/views/widget/widget.h" 23 #include "ui/views/widget/widget_delegate.h" 24 25 using testing::Combine; 26 using testing::Values; 27 using testing::WithParamInterface; 28 29 namespace { 30 31 // WidgetDelegateView which allows the widget to be maximized. 32 class MaximizableWidgetDelegate : public views::WidgetDelegateView { 33 public: 34 MaximizableWidgetDelegate() { 35 } 36 virtual ~MaximizableWidgetDelegate() { 37 } 38 39 virtual bool CanMaximize() const OVERRIDE { 40 return true; 41 } 42 43 private: 44 DISALLOW_COPY_AND_ASSIGN(MaximizableWidgetDelegate); 45 }; 46 47 // Returns true if |window_state|'s window is in immersive fullscreen. Infer 48 // whether the window is in immersive fullscreen based on whether the shelf is 49 // hidden when the window is fullscreen. (This is not quite right because the 50 // shelf is hidden if a window is in both immersive fullscreen and tab 51 // fullscreen.) 52 bool IsInImmersiveFullscreen(ash::wm::WindowState* window_state) { 53 return window_state->IsFullscreen() && 54 !window_state->hide_shelf_when_fullscreen(); 55 } 56 57 } // namespace 58 59 typedef InProcessBrowserTest AcceleratorCommandsBrowserTest; 60 61 // Confirm that toggling window miximized works properly 62 IN_PROC_BROWSER_TEST_F(AcceleratorCommandsBrowserTest, ToggleMaximized) { 63 #if defined(OS_WIN) 64 // Run the test on Win Ash only. 65 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 66 return; 67 #endif 68 69 ASSERT_TRUE(ash::Shell::HasInstance()) << "No Instance"; 70 ash::wm::WindowState* window_state = ash::wm::GetActiveWindowState(); 71 ASSERT_TRUE(window_state); 72 73 // When not in fullscreen, accelerators::ToggleMaximized toggles Maximized. 74 EXPECT_FALSE(window_state->IsMaximized()); 75 ash::accelerators::ToggleMaximized(); 76 EXPECT_TRUE(window_state->IsMaximized()); 77 ash::accelerators::ToggleMaximized(); 78 EXPECT_FALSE(window_state->IsMaximized()); 79 80 // When in fullscreen accelerators::ToggleMaximized gets out of fullscreen. 81 EXPECT_FALSE(window_state->IsFullscreen()); 82 Browser* browser = chrome::FindBrowserWithWindow(window_state->window()); 83 ASSERT_TRUE(browser); 84 chrome::ToggleFullscreenMode(browser); 85 EXPECT_TRUE(window_state->IsFullscreen()); 86 ash::accelerators::ToggleMaximized(); 87 EXPECT_FALSE(window_state->IsFullscreen()); 88 EXPECT_FALSE(window_state->IsMaximized()); 89 ash::accelerators::ToggleMaximized(); 90 EXPECT_FALSE(window_state->IsFullscreen()); 91 EXPECT_TRUE(window_state->IsMaximized()); 92 } 93 94 class AcceleratorCommandsFullscreenBrowserTest 95 : public WithParamInterface<ui::WindowShowState>, 96 public InProcessBrowserTest { 97 public: 98 AcceleratorCommandsFullscreenBrowserTest() 99 : initial_show_state_(GetParam()) { 100 } 101 virtual ~AcceleratorCommandsFullscreenBrowserTest() { 102 } 103 104 // Sets |window_state|'s show state to |initial_show_state_|. 105 void SetToInitialShowState(ash::wm::WindowState* window_state) { 106 if (initial_show_state_ == ui::SHOW_STATE_MAXIMIZED) 107 window_state->Maximize(); 108 else 109 window_state->Restore(); 110 } 111 112 // Returns true if |window_state|'s show state is |initial_show_state_|. 113 bool IsInitialShowState(const ash::wm::WindowState* window_state) const { 114 if (initial_show_state_ == ui::SHOW_STATE_MAXIMIZED) 115 return window_state->IsMaximized(); 116 else 117 return window_state->IsNormalStateType(); 118 } 119 120 private: 121 ui::WindowShowState initial_show_state_; 122 123 DISALLOW_COPY_AND_ASSIGN(AcceleratorCommandsFullscreenBrowserTest); 124 }; 125 126 // Test that toggling window fullscreen works properly. 127 IN_PROC_BROWSER_TEST_P(AcceleratorCommandsFullscreenBrowserTest, 128 ToggleFullscreen) { 129 #if defined(OS_WIN) 130 // Run the test on Win Ash only. 131 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 132 return; 133 #endif 134 135 ASSERT_TRUE(ash::Shell::HasInstance()) << "No Instance"; 136 137 // 1) Browser windows. 138 ASSERT_TRUE(browser()->is_type_tabbed()); 139 ash::wm::WindowState* window_state = 140 ash::wm::GetWindowState(browser()->window()->GetNativeWindow()); 141 ASSERT_TRUE(window_state->IsActive()); 142 SetToInitialShowState(window_state); 143 EXPECT_TRUE(IsInitialShowState(window_state)); 144 145 ash::accelerators::ToggleFullscreen(); 146 EXPECT_TRUE(window_state->IsFullscreen()); 147 EXPECT_TRUE(IsInImmersiveFullscreen(window_state)); 148 149 ash::accelerators::ToggleFullscreen(); 150 EXPECT_TRUE(IsInitialShowState(window_state)); 151 152 // 2) ToggleFullscreen() should have no effect on windows which cannot be 153 // maximized. 154 window_state->window()->SetProperty(aura::client::kCanMaximizeKey, false); 155 ash::accelerators::ToggleFullscreen(); 156 EXPECT_TRUE(IsInitialShowState(window_state)); 157 158 // 3) Hosted apps. 159 Browser::CreateParams browser_create_params( 160 Browser::CreateParams::CreateForApp("Test", 161 true /* trusted_source */, 162 gfx::Rect(), 163 browser()->profile(), 164 chrome::HOST_DESKTOP_TYPE_ASH)); 165 166 Browser* app_host_browser = new Browser(browser_create_params); 167 ASSERT_TRUE(app_host_browser->is_app()); 168 AddBlankTabAndShow(app_host_browser); 169 window_state = 170 ash::wm::GetWindowState(app_host_browser->window()->GetNativeWindow()); 171 ASSERT_TRUE(window_state->IsActive()); 172 SetToInitialShowState(window_state); 173 EXPECT_TRUE(IsInitialShowState(window_state)); 174 175 ash::accelerators::ToggleFullscreen(); 176 EXPECT_TRUE(window_state->IsFullscreen()); 177 EXPECT_TRUE(IsInImmersiveFullscreen(window_state)); 178 179 ash::accelerators::ToggleFullscreen(); 180 EXPECT_TRUE(IsInitialShowState(window_state)); 181 182 // 4) Popup browser windows. 183 browser_create_params = Browser::CreateParams( 184 Browser::TYPE_POPUP, browser()->profile(), chrome::HOST_DESKTOP_TYPE_ASH); 185 Browser* popup_browser = new Browser(browser_create_params); 186 ASSERT_TRUE(popup_browser->is_type_popup()); 187 ASSERT_FALSE(popup_browser->is_app()); 188 AddBlankTabAndShow(popup_browser); 189 window_state = 190 ash::wm::GetWindowState(popup_browser->window()->GetNativeWindow()); 191 ASSERT_TRUE(window_state->IsActive()); 192 SetToInitialShowState(window_state); 193 EXPECT_TRUE(IsInitialShowState(window_state)); 194 195 ash::accelerators::ToggleFullscreen(); 196 EXPECT_TRUE(window_state->IsFullscreen()); 197 EXPECT_TRUE(IsInImmersiveFullscreen(window_state)); 198 199 ash::accelerators::ToggleFullscreen(); 200 EXPECT_TRUE(IsInitialShowState(window_state)); 201 202 // 5) Miscellaneous windows (e.g. task manager). 203 views::Widget::InitParams params; 204 params.delegate = new MaximizableWidgetDelegate(); 205 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 206 scoped_ptr<views::Widget> widget(new views::Widget); 207 widget->Init(params); 208 widget->Show(); 209 210 window_state = ash::wm::GetWindowState(widget->GetNativeWindow()); 211 ASSERT_TRUE(window_state->IsActive()); 212 SetToInitialShowState(window_state); 213 EXPECT_TRUE(IsInitialShowState(window_state)); 214 215 ash::accelerators::ToggleFullscreen(); 216 EXPECT_TRUE(window_state->IsFullscreen()); 217 EXPECT_TRUE(IsInImmersiveFullscreen(window_state)); 218 219 // TODO(pkotwicz|oshima): Make toggling fullscreen restore the window to its 220 // show state prior to entering fullscreen. 221 ash::accelerators::ToggleFullscreen(); 222 EXPECT_FALSE(window_state->IsFullscreen()); 223 } 224 225 INSTANTIATE_TEST_CASE_P(InitiallyRestored, 226 AcceleratorCommandsFullscreenBrowserTest, 227 Values(ui::SHOW_STATE_NORMAL)); 228 INSTANTIATE_TEST_CASE_P(InitiallyMaximized, 229 AcceleratorCommandsFullscreenBrowserTest, 230 Values(ui::SHOW_STATE_MAXIMIZED)); 231 232 class AcceleratorCommandsPlatformAppFullscreenBrowserTest 233 : public WithParamInterface<ui::WindowShowState>, 234 public extensions::PlatformAppBrowserTest { 235 public: 236 AcceleratorCommandsPlatformAppFullscreenBrowserTest() 237 : initial_show_state_(GetParam()) { 238 } 239 virtual ~AcceleratorCommandsPlatformAppFullscreenBrowserTest() { 240 } 241 242 // Sets |app_window|'s show state to |initial_show_state_|. 243 void SetToInitialShowState(apps::AppWindow* app_window) { 244 if (initial_show_state_ == ui::SHOW_STATE_MAXIMIZED) 245 app_window->Maximize(); 246 else 247 app_window->Restore(); 248 } 249 250 // Returns true if |app_window|'s show state is |initial_show_state_|. 251 bool IsInitialShowState(apps::AppWindow* app_window) const { 252 if (initial_show_state_ == ui::SHOW_STATE_MAXIMIZED) 253 return app_window->GetBaseWindow()->IsMaximized(); 254 else 255 return ui::BaseWindow::IsRestored(*app_window->GetBaseWindow()); 256 } 257 258 private: 259 ui::WindowShowState initial_show_state_; 260 261 DISALLOW_COPY_AND_ASSIGN(AcceleratorCommandsPlatformAppFullscreenBrowserTest); 262 }; 263 264 // Test the behavior of platform apps when ToggleFullscreen() is called. 265 IN_PROC_BROWSER_TEST_P(AcceleratorCommandsPlatformAppFullscreenBrowserTest, 266 ToggleFullscreen) { 267 #if defined(OS_WIN) 268 // Run the test on Win Ash only. 269 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 270 return; 271 #endif 272 273 ASSERT_TRUE(ash::Shell::HasInstance()) << "No Instance"; 274 const extensions::Extension* extension = LoadAndLaunchPlatformApp("minimal", 275 "Launched"); 276 277 { 278 // Test that ToggleFullscreen() toggles a platform's app's fullscreen 279 // state and that it additionally puts the app into immersive fullscreen 280 // if put_all_windows_in_immersive() returns true. 281 apps::AppWindow::CreateParams params; 282 params.frame = apps::AppWindow::FRAME_CHROME; 283 apps::AppWindow* app_window = CreateAppWindowFromParams(extension, params); 284 apps::NativeAppWindow* native_app_window = app_window->GetBaseWindow(); 285 SetToInitialShowState(app_window); 286 ASSERT_TRUE(app_window->GetBaseWindow()->IsActive()); 287 EXPECT_TRUE(IsInitialShowState(app_window)); 288 289 ash::accelerators::ToggleFullscreen(); 290 EXPECT_TRUE(native_app_window->IsFullscreen()); 291 ash::wm::WindowState* window_state = 292 ash::wm::GetWindowState(native_app_window->GetNativeWindow()); 293 EXPECT_TRUE(IsInImmersiveFullscreen(window_state)); 294 295 ash::accelerators::ToggleFullscreen(); 296 EXPECT_TRUE(IsInitialShowState(app_window)); 297 298 CloseAppWindow(app_window); 299 } 300 301 { 302 // Repeat the test, but make sure that frameless platform apps are never put 303 // into immersive fullscreen. 304 apps::AppWindow::CreateParams params; 305 params.frame = apps::AppWindow::FRAME_NONE; 306 apps::AppWindow* app_window = CreateAppWindowFromParams(extension, params); 307 apps::NativeAppWindow* native_app_window = app_window->GetBaseWindow(); 308 ASSERT_TRUE(app_window->GetBaseWindow()->IsActive()); 309 SetToInitialShowState(app_window); 310 EXPECT_TRUE(IsInitialShowState(app_window)); 311 312 ash::accelerators::ToggleFullscreen(); 313 EXPECT_TRUE(native_app_window->IsFullscreen()); 314 ash::wm::WindowState* window_state = 315 ash::wm::GetWindowState(native_app_window->GetNativeWindow()); 316 EXPECT_FALSE(IsInImmersiveFullscreen(window_state)); 317 318 ash::accelerators::ToggleFullscreen(); 319 EXPECT_TRUE(IsInitialShowState(app_window)); 320 321 CloseAppWindow(app_window); 322 } 323 } 324 325 INSTANTIATE_TEST_CASE_P(InitiallyRestored, 326 AcceleratorCommandsPlatformAppFullscreenBrowserTest, 327 Values(ui::SHOW_STATE_NORMAL)); 328 INSTANTIATE_TEST_CASE_P(InitiallyMaximized, 329 AcceleratorCommandsPlatformAppFullscreenBrowserTest, 330 Values(ui::SHOW_STATE_MAXIMIZED)); 331