Home | History | Annotate | Download | only in ash
      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