Home | History | Annotate | Download | only in frame
      1 // Copyright (c) 2012 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/browser_non_client_frame_view_ash.h"
      6 
      7 #include "ash/ash_constants.h"
      8 #include "ash/ash_switches.h"
      9 #include "base/command_line.h"
     10 #include "chrome/browser/ui/browser.h"
     11 #include "chrome/browser/ui/browser_commands.h"
     12 #include "chrome/browser/ui/fullscreen/fullscreen_controller.h"
     13 #include "chrome/browser/ui/fullscreen/fullscreen_controller_test.h"
     14 #include "chrome/browser/ui/immersive_fullscreen_configuration.h"
     15 #include "chrome/browser/ui/views/frame/browser_view.h"
     16 #include "chrome/browser/ui/views/frame/immersive_mode_controller_ash.h"
     17 #include "chrome/test/base/in_process_browser_test.h"
     18 #include "ui/base/hit_test.h"
     19 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
     20 #include "ui/views/controls/button/image_button.h"
     21 #include "ui/views/widget/widget.h"
     22 
     23 using views::Widget;
     24 
     25 typedef InProcessBrowserTest BrowserNonClientFrameViewAshTest;
     26 
     27 IN_PROC_BROWSER_TEST_F(BrowserNonClientFrameViewAshTest, WindowHeader) {
     28   // We know we're using Views, so static cast.
     29   BrowserView* browser_view = static_cast<BrowserView*>(browser()->window());
     30   Widget* widget = browser_view->GetWidget();
     31   // We know we're using Ash, so static cast.
     32   BrowserNonClientFrameViewAsh* frame_view =
     33       static_cast<BrowserNonClientFrameViewAsh*>(
     34           widget->non_client_view()->frame_view());
     35 
     36   // Restored window uses tall header.
     37   const int kWindowWidth = 300;
     38   const int kWindowHeight = 290;
     39   widget->SetBounds(gfx::Rect(10, 10, kWindowWidth, kWindowHeight));
     40   EXPECT_FALSE(frame_view->UseShortHeader());
     41 
     42   // Click on the top edge of a window hits the top edge resize handle.
     43   gfx::Point top_edge(kWindowWidth / 2, 0);
     44   EXPECT_EQ(HTTOP, frame_view->NonClientHitTest(top_edge));
     45 
     46   // Click just below the resize handle hits the caption.
     47   gfx::Point below_resize(kWindowWidth / 2, ash::kResizeInsideBoundsSize);
     48   EXPECT_EQ(HTCAPTION, frame_view->NonClientHitTest(below_resize));
     49 
     50   // Window at top of screen uses normal header.
     51   widget->SetBounds(gfx::Rect(10, 0, kWindowWidth, kWindowHeight));
     52   EXPECT_FALSE(frame_view->UseShortHeader());
     53 
     54   // Maximized window uses short header.
     55   widget->Maximize();
     56   EXPECT_TRUE(frame_view->UseShortHeader());
     57 
     58   // Click in the top edge of a maximized window now hits the client area,
     59   // because we want it to fall through to the tab strip and select a tab.
     60   EXPECT_EQ(HTCLIENT, frame_view->NonClientHitTest(top_edge));
     61 
     62   // Popups tall header.
     63   Browser* popup = CreateBrowserForPopup(browser()->profile());
     64   Widget* popup_widget =
     65       static_cast<BrowserView*>(popup->window())->GetWidget();
     66   BrowserNonClientFrameViewAsh* popup_frame_view =
     67       static_cast<BrowserNonClientFrameViewAsh*>(
     68           popup_widget->non_client_view()->frame_view());
     69   popup_widget->SetBounds(gfx::Rect(5, 5, 200, 200));
     70   EXPECT_FALSE(popup_frame_view->UseShortHeader());
     71 
     72   // Apps use tall header.
     73   Browser* app = CreateBrowserForApp("name", browser()->profile());
     74   Widget* app_widget =
     75       static_cast<BrowserView*>(app->window())->GetWidget();
     76   BrowserNonClientFrameViewAsh* app_frame_view =
     77       static_cast<BrowserNonClientFrameViewAsh*>(
     78           app_widget->non_client_view()->frame_view());
     79   app_widget->SetBounds(gfx::Rect(15, 15, 250, 250));
     80   EXPECT_FALSE(app_frame_view->UseShortHeader());
     81 }
     82 
     83 // Test that the frame view does not do any painting in non-immersive
     84 // fullscreen.
     85 IN_PROC_BROWSER_TEST_F(BrowserNonClientFrameViewAshTest,
     86                        NonImmersiveFullscreen) {
     87   // We know we're using Views, so static cast.
     88   BrowserView* browser_view = static_cast<BrowserView*>(browser()->window());
     89   content::WebContents* web_contents = browser_view->GetActiveWebContents();
     90   Widget* widget = browser_view->GetWidget();
     91   // We know we're using Ash, so static cast.
     92   BrowserNonClientFrameViewAsh* frame_view =
     93       static_cast<BrowserNonClientFrameViewAsh*>(
     94           widget->non_client_view()->frame_view());
     95 
     96   // Frame paints by default.
     97   EXPECT_TRUE(frame_view->ShouldPaint());
     98 
     99   // No painting should occur in non-immersive fullscreen. (We enter into tab
    100   // fullscreen here because tab fullscreen is non-immersive even when
    101   // ImmersiveFullscreenConfiguration::UseImmersiveFullscreen()) returns
    102   // true.
    103   {
    104     // NOTIFICATION_FULLSCREEN_CHANGED is sent asynchronously.
    105     scoped_ptr<FullscreenNotificationObserver> waiter(
    106         new FullscreenNotificationObserver());
    107     browser()->fullscreen_controller()->ToggleFullscreenModeForTab(
    108         web_contents, true);
    109     waiter->Wait();
    110   }
    111   EXPECT_FALSE(browser_view->immersive_mode_controller()->IsEnabled());
    112   EXPECT_FALSE(frame_view->ShouldPaint());
    113 
    114   // Frame abuts top of window.
    115   EXPECT_EQ(0, frame_view->NonClientTopBorderHeight(false));
    116 
    117   // The frame should be painted again when fullscreen is exited and the caption
    118   // buttons should be visible.
    119   {
    120     scoped_ptr<FullscreenNotificationObserver> waiter(
    121         new FullscreenNotificationObserver());
    122     chrome::ToggleFullscreenMode(browser());
    123     waiter->Wait();
    124   }
    125   EXPECT_TRUE(frame_view->ShouldPaint());
    126   EXPECT_TRUE(frame_view->size_button_->visible());
    127   EXPECT_TRUE(frame_view->close_button_->visible());
    128 }
    129 
    130 IN_PROC_BROWSER_TEST_F(BrowserNonClientFrameViewAshTest, ImmersiveFullscreen) {
    131   if (!ImmersiveFullscreenConfiguration::UseImmersiveFullscreen())
    132     return;
    133 
    134   // We know we're using Views, so static cast.
    135   BrowserView* browser_view = static_cast<BrowserView*>(browser()->window());
    136   Widget* widget = browser_view->GetWidget();
    137   // We know we're using Ash, so static cast.
    138   BrowserNonClientFrameViewAsh* frame_view =
    139       static_cast<BrowserNonClientFrameViewAsh*>(
    140           widget->non_client_view()->frame_view());
    141 
    142   ImmersiveModeControllerAsh* immersive_mode_controller =
    143       static_cast<ImmersiveModeControllerAsh*>(
    144           browser_view->immersive_mode_controller());
    145   immersive_mode_controller->DisableAnimationsForTest();
    146   immersive_mode_controller->SetForceHideTabIndicatorsForTest(true);
    147 
    148   // Immersive mode starts disabled.
    149   ASSERT_FALSE(widget->IsFullscreen());
    150   EXPECT_FALSE(immersive_mode_controller->IsEnabled());
    151 
    152   // Frame paints by default.
    153   EXPECT_TRUE(frame_view->ShouldPaint());
    154 
    155   // Going fullscreen enables immersive mode.
    156   chrome::ToggleFullscreenMode(browser());
    157   EXPECT_TRUE(immersive_mode_controller->IsEnabled());
    158 
    159   // An immersive reveal shows the buttons and the top of the frame.
    160   immersive_mode_controller->StartRevealForTest(true);
    161   EXPECT_TRUE(immersive_mode_controller->IsRevealed());
    162   EXPECT_TRUE(frame_view->ShouldPaint());
    163   EXPECT_TRUE(frame_view->size_button_->visible());
    164   EXPECT_TRUE(frame_view->close_button_->visible());
    165   EXPECT_TRUE(frame_view->UseShortHeader());
    166   EXPECT_FALSE(frame_view->UseImmersiveLightbarHeaderStyle());
    167 
    168   // End the reveal. As the header does not paint a light bar when the
    169   // top-of-window views are not revealed, nothing should be painted.
    170   immersive_mode_controller->SetMouseHoveredForTest(false);
    171   EXPECT_FALSE(immersive_mode_controller->IsRevealed());
    172   EXPECT_FALSE(frame_view->ShouldPaint());
    173 
    174   // Frame abuts top of window.
    175   EXPECT_EQ(0, frame_view->NonClientTopBorderHeight(false));
    176 
    177   // Repeat test but with the tab light bar visible when the top-of-window views
    178   // are not revealed.
    179   immersive_mode_controller->SetForceHideTabIndicatorsForTest(false);
    180 
    181   // Immersive reveal should have same behavior as before.
    182   immersive_mode_controller->StartRevealForTest(true);
    183   EXPECT_TRUE(immersive_mode_controller->IsRevealed());
    184   EXPECT_TRUE(frame_view->ShouldPaint());
    185   EXPECT_TRUE(frame_view->size_button_->visible());
    186   EXPECT_TRUE(frame_view->close_button_->visible());
    187   EXPECT_TRUE(frame_view->UseShortHeader());
    188   EXPECT_FALSE(frame_view->UseImmersiveLightbarHeaderStyle());
    189 
    190   // Ending the reveal should hide the caption buttons and the header should
    191   // be in the lightbar style.
    192   immersive_mode_controller->SetMouseHoveredForTest(false);
    193   EXPECT_TRUE(frame_view->ShouldPaint());
    194   EXPECT_FALSE(frame_view->size_button_->visible());
    195   EXPECT_FALSE(frame_view->close_button_->visible());
    196   EXPECT_TRUE(frame_view->UseShortHeader());
    197   EXPECT_TRUE(frame_view->UseImmersiveLightbarHeaderStyle());
    198 
    199   // Exiting fullscreen exits immersive mode.
    200   browser_view->ExitFullscreen();
    201   EXPECT_FALSE(immersive_mode_controller->IsEnabled());
    202 
    203   // Exiting immersive mode makes controls and frame visible again.
    204   EXPECT_TRUE(frame_view->ShouldPaint());
    205   EXPECT_TRUE(frame_view->size_button_->visible());
    206   EXPECT_TRUE(frame_view->close_button_->visible());
    207   EXPECT_FALSE(frame_view->UseImmersiveLightbarHeaderStyle());
    208 }
    209