browser_non_client_frame_view_ash_browsertest.cc revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
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 "ash/frame/caption_buttons/frame_caption_button_container_view.h" 10#include "ash/frame/header_painter.h" 11#include "ash/shell.h" 12#include "ash/wm/maximize_mode/maximize_mode_controller.h" 13#include "base/command_line.h" 14#include "chrome/browser/ui/browser.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/immersive_mode_controller.h" 20#include "chrome/browser/ui/views/tabs/tab.h" 21#include "chrome/test/base/in_process_browser_test.h" 22#include "ui/base/hit_test.h" 23#include "ui/compositor/scoped_animation_duration_scale_mode.h" 24#include "ui/views/widget/widget.h" 25 26using views::Widget; 27 28namespace { 29 30class BrowserNonClientFrameViewAshTest : public InProcessBrowserTest { 31 public: 32 BrowserNonClientFrameViewAshTest() {} 33 virtual ~BrowserNonClientFrameViewAshTest() {} 34 35 // InProcessBrowserTest: 36 virtual void SetUp() OVERRIDE; 37 virtual void TearDown() OVERRIDE; 38 39 private: 40 scoped_ptr<ui::ScopedAnimationDurationScaleMode> zero_duration_mode_; 41 DISALLOW_COPY_AND_ASSIGN(BrowserNonClientFrameViewAshTest); 42}; 43 44void BrowserNonClientFrameViewAshTest::SetUp() { 45 zero_duration_mode_.reset(new ui::ScopedAnimationDurationScaleMode( 46 ui::ScopedAnimationDurationScaleMode::ZERO_DURATION)); 47 InProcessBrowserTest::SetUp(); 48} 49 50void BrowserNonClientFrameViewAshTest::TearDown() { 51 zero_duration_mode_.reset(); 52 InProcessBrowserTest::TearDown(); 53} 54 55} // namespace 56 57IN_PROC_BROWSER_TEST_F(BrowserNonClientFrameViewAshTest, NonClientHitTest) { 58 BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); 59 Widget* widget = browser_view->GetWidget(); 60 // We know we're using Ash, so static cast. 61 BrowserNonClientFrameViewAsh* frame_view = 62 static_cast<BrowserNonClientFrameViewAsh*>( 63 widget->non_client_view()->frame_view()); 64 65 // Click on the top edge of a restored window hits the top edge resize handle. 66 const int kWindowWidth = 300; 67 const int kWindowHeight = 290; 68 widget->SetBounds(gfx::Rect(10, 10, kWindowWidth, kWindowHeight)); 69 gfx::Point top_edge(kWindowWidth / 2, 0); 70 EXPECT_EQ(HTTOP, frame_view->NonClientHitTest(top_edge)); 71 72 // Click just below the resize handle hits the caption. 73 gfx::Point below_resize(kWindowWidth / 2, ash::kResizeInsideBoundsSize); 74 EXPECT_EQ(HTCAPTION, frame_view->NonClientHitTest(below_resize)); 75 76 // Click in the top edge of a maximized window now hits the client area, 77 // because we want it to fall through to the tab strip and select a tab. 78 widget->Maximize(); 79 EXPECT_EQ(HTCLIENT, frame_view->NonClientHitTest(top_edge)); 80} 81 82// Test that the frame view does not do any painting in non-immersive 83// fullscreen. 84IN_PROC_BROWSER_TEST_F(BrowserNonClientFrameViewAshTest, 85 NonImmersiveFullscreen) { 86 BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); 87 content::WebContents* web_contents = browser_view->GetActiveWebContents(); 88 Widget* widget = browser_view->GetWidget(); 89 // We know we're using Ash, so static cast. 90 BrowserNonClientFrameViewAsh* frame_view = 91 static_cast<BrowserNonClientFrameViewAsh*>( 92 widget->non_client_view()->frame_view()); 93 94 // Frame paints by default. 95 EXPECT_TRUE(frame_view->ShouldPaint()); 96 97 // No painting should occur in non-immersive fullscreen. (We enter into tab 98 // fullscreen here because tab fullscreen is non-immersive even on ChromeOS). 99 { 100 // NOTIFICATION_FULLSCREEN_CHANGED is sent asynchronously. 101 scoped_ptr<FullscreenNotificationObserver> waiter( 102 new FullscreenNotificationObserver()); 103 browser()->fullscreen_controller()->ToggleFullscreenModeForTab( 104 web_contents, true); 105 waiter->Wait(); 106 } 107 EXPECT_FALSE(browser_view->immersive_mode_controller()->IsEnabled()); 108 EXPECT_FALSE(frame_view->ShouldPaint()); 109 110 // The client view abuts top of the window. 111 EXPECT_EQ(0, frame_view->GetBoundsForClientView().y()); 112 113 // The frame should be painted again when fullscreen is exited and the caption 114 // buttons should be visible. 115 { 116 scoped_ptr<FullscreenNotificationObserver> waiter( 117 new FullscreenNotificationObserver()); 118 chrome::ToggleFullscreenMode(browser()); 119 waiter->Wait(); 120 } 121 EXPECT_TRUE(frame_view->ShouldPaint()); 122 EXPECT_TRUE(frame_view->caption_button_container_->visible()); 123} 124 125// TODO(zturner): Change this to USE_ASH after fixing the test on Windows. 126#if defined(OS_CHROMEOS) 127IN_PROC_BROWSER_TEST_F(BrowserNonClientFrameViewAshTest, ImmersiveFullscreen) { 128 BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); 129 content::WebContents* web_contents = browser_view->GetActiveWebContents(); 130 Widget* widget = browser_view->GetWidget(); 131 // We know we're using Ash, so static cast. 132 BrowserNonClientFrameViewAsh* frame_view = 133 static_cast<BrowserNonClientFrameViewAsh*>( 134 widget->non_client_view()->frame_view()); 135 136 ImmersiveModeController* immersive_mode_controller = 137 browser_view->immersive_mode_controller(); 138 immersive_mode_controller->SetupForTest(); 139 140 // Immersive fullscreen starts disabled. 141 ASSERT_FALSE(widget->IsFullscreen()); 142 EXPECT_FALSE(immersive_mode_controller->IsEnabled()); 143 144 // Frame paints by default. 145 EXPECT_TRUE(frame_view->ShouldPaint()); 146 EXPECT_LT(Tab::GetImmersiveHeight(), 147 frame_view->header_painter_->GetHeaderHeightForPainting()); 148 149 // Enter both browser fullscreen and tab fullscreen. Entering browser 150 // fullscreen should enable immersive fullscreen. 151 { 152 // NOTIFICATION_FULLSCREEN_CHANGED is sent asynchronously. 153 scoped_ptr<FullscreenNotificationObserver> waiter( 154 new FullscreenNotificationObserver()); 155 chrome::ToggleFullscreenMode(browser()); 156 waiter->Wait(); 157 } 158 { 159 scoped_ptr<FullscreenNotificationObserver> waiter( 160 new FullscreenNotificationObserver()); 161 browser()->fullscreen_controller()->ToggleFullscreenModeForTab( 162 web_contents, true); 163 waiter->Wait(); 164 } 165 EXPECT_TRUE(immersive_mode_controller->IsEnabled()); 166 167 // An immersive reveal shows the buttons and the top of the frame. 168 scoped_ptr<ImmersiveRevealedLock> revealed_lock( 169 immersive_mode_controller->GetRevealedLock( 170 ImmersiveModeController::ANIMATE_REVEAL_NO)); 171 EXPECT_TRUE(immersive_mode_controller->IsRevealed()); 172 EXPECT_TRUE(frame_view->ShouldPaint()); 173 EXPECT_TRUE(frame_view->caption_button_container_->visible()); 174 EXPECT_FALSE(frame_view->UseImmersiveLightbarHeaderStyle()); 175 176 // End the reveal. When in both immersive browser fullscreen and tab 177 // fullscreen, the tab lightbars should not be painted. 178 revealed_lock.reset(); 179 EXPECT_FALSE(immersive_mode_controller->IsRevealed()); 180 EXPECT_FALSE(frame_view->ShouldPaint()); 181 EXPECT_EQ(0, frame_view->header_painter_->GetHeaderHeightForPainting()); 182 183 // Repeat test but without tab fullscreen. The tab lightbars should now show 184 // when the top-of-window views are not revealed. 185 { 186 scoped_ptr<FullscreenNotificationObserver> waiter( 187 new FullscreenNotificationObserver()); 188 browser()->fullscreen_controller()->ToggleFullscreenModeForTab( 189 web_contents, false); 190 waiter->Wait(); 191 } 192 193 // Immersive reveal should have same behavior as before. 194 revealed_lock.reset(immersive_mode_controller->GetRevealedLock( 195 ImmersiveModeController::ANIMATE_REVEAL_NO)); 196 EXPECT_TRUE(immersive_mode_controller->IsRevealed()); 197 EXPECT_TRUE(frame_view->ShouldPaint()); 198 EXPECT_TRUE(frame_view->caption_button_container_->visible()); 199 EXPECT_FALSE(frame_view->UseImmersiveLightbarHeaderStyle()); 200 EXPECT_LT(Tab::GetImmersiveHeight(), 201 frame_view->header_painter_->GetHeaderHeightForPainting()); 202 203 // Ending the reveal should hide the caption buttons and the header should 204 // be in the lightbar style. 205 revealed_lock.reset(); 206 EXPECT_TRUE(frame_view->ShouldPaint()); 207 EXPECT_FALSE(frame_view->caption_button_container_->visible()); 208 EXPECT_TRUE(frame_view->UseImmersiveLightbarHeaderStyle()); 209 EXPECT_EQ(Tab::GetImmersiveHeight(), 210 frame_view->header_painter_->GetHeaderHeightForPainting()); 211 212 // Exiting immersive fullscreen should make the caption buttons and the frame 213 // visible again. 214 { 215 scoped_ptr<FullscreenNotificationObserver> waiter( 216 new FullscreenNotificationObserver()); 217 browser_view->ExitFullscreen(); 218 waiter->Wait(); 219 } 220 EXPECT_FALSE(immersive_mode_controller->IsEnabled()); 221 EXPECT_TRUE(frame_view->ShouldPaint()); 222 EXPECT_TRUE(frame_view->caption_button_container_->visible()); 223 EXPECT_FALSE(frame_view->UseImmersiveLightbarHeaderStyle()); 224 EXPECT_LT(Tab::GetImmersiveHeight(), 225 frame_view->header_painter_->GetHeaderHeightForPainting()); 226} 227#endif // defined(OS_CHROMEOS) 228 229// Tests that FrameCaptionButtonContainer has been relaid out in response to 230// maximize mode being toggled. 231IN_PROC_BROWSER_TEST_F(BrowserNonClientFrameViewAshTest, 232 ToggleMaximizeModeRelayout) { 233 BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); 234 Widget* widget = browser_view->GetWidget(); 235 // We know we're using Ash, so static cast. 236 BrowserNonClientFrameViewAsh* frame_view = 237 static_cast<BrowserNonClientFrameViewAsh*>( 238 widget->non_client_view()->frame_view()); 239 240 const gfx::Rect initial = frame_view->caption_button_container_->bounds(); 241 ash::Shell::GetInstance()->maximize_mode_controller()-> 242 EnableMaximizeModeWindowManager(true); 243 const gfx::Rect during_maximize = frame_view->caption_button_container_-> 244 bounds(); 245 EXPECT_GT(initial.width(), during_maximize.width()); 246 ash::Shell::GetInstance()->maximize_mode_controller()-> 247 EnableMaximizeModeWindowManager(false); 248 const gfx::Rect after_restore = frame_view->caption_button_container_-> 249 bounds(); 250 EXPECT_EQ(initial, after_restore); 251} 252