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.
5 #include "chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h"
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 "base/command_line.h"
13 #include "chrome/browser/ui/browser.h"
14 #include "chrome/browser/ui/browser_commands.h"
15 #include "chrome/browser/ui/fullscreen/fullscreen_controller.h"
16 #include "chrome/browser/ui/fullscreen/fullscreen_controller_test.h"
17 #include "chrome/browser/ui/views/frame/browser_view.h"
18 #include "chrome/browser/ui/views/frame/immersive_mode_controller.h"
19 #include "chrome/browser/ui/views/tabs/tab.h"
20 #include "chrome/test/base/in_process_browser_test.h"
21 #include "ui/base/hit_test.h"
22 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
23 #include "ui/views/widget/widget.h"
27 typedef InProcessBrowserTest BrowserNonClientFrameViewAshTest;
29 IN_PROC_BROWSER_TEST_F(BrowserNonClientFrameViewAshTest, NonClientHitTest) {
30 BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser());
31 Widget* widget = browser_view->GetWidget();
32 // We know we're using Ash, so static cast.
33 BrowserNonClientFrameViewAsh* frame_view =
34 static_cast<BrowserNonClientFrameViewAsh*>(
35 widget->non_client_view()->frame_view());
37 // Click on the top edge of a restored window hits the top edge resize handle.
38 const int kWindowWidth = 300;
39 const int kWindowHeight = 290;
40 widget->SetBounds(gfx::Rect(10, 10, kWindowWidth, kWindowHeight));
41 gfx::Point top_edge(kWindowWidth / 2, 0);
42 EXPECT_EQ(HTTOP, frame_view->NonClientHitTest(top_edge));
44 // Click just below the resize handle hits the caption.
45 gfx::Point below_resize(kWindowWidth / 2, ash::kResizeInsideBoundsSize);
46 EXPECT_EQ(HTCAPTION, frame_view->NonClientHitTest(below_resize));
48 // Click in the top edge of a maximized window now hits the client area,
49 // because we want it to fall through to the tab strip and select a tab.
51 EXPECT_EQ(HTCLIENT, frame_view->NonClientHitTest(top_edge));
54 // Test that the frame view does not do any painting in non-immersive
56 IN_PROC_BROWSER_TEST_F(BrowserNonClientFrameViewAshTest,
57 NonImmersiveFullscreen) {
58 BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser());
59 content::WebContents* web_contents = browser_view->GetActiveWebContents();
60 Widget* widget = browser_view->GetWidget();
61 // We know we're using Ash, so static cast.
62 BrowserNonClientFrameViewAsh* frame_view =
63 static_cast<BrowserNonClientFrameViewAsh*>(
64 widget->non_client_view()->frame_view());
66 // Frame paints by default.
67 EXPECT_TRUE(frame_view->ShouldPaint());
69 // No painting should occur in non-immersive fullscreen. (We enter into tab
70 // fullscreen here because tab fullscreen is non-immersive even on ChromeOS).
72 // NOTIFICATION_FULLSCREEN_CHANGED is sent asynchronously.
73 scoped_ptr<FullscreenNotificationObserver> waiter(
74 new FullscreenNotificationObserver());
75 browser()->fullscreen_controller()->ToggleFullscreenModeForTab(
79 EXPECT_FALSE(browser_view->immersive_mode_controller()->IsEnabled());
80 EXPECT_FALSE(frame_view->ShouldPaint());
82 // The client view abuts top of the window.
83 EXPECT_EQ(0, frame_view->GetBoundsForClientView().y());
85 // The frame should be painted again when fullscreen is exited and the caption
86 // buttons should be visible.
88 scoped_ptr<FullscreenNotificationObserver> waiter(
89 new FullscreenNotificationObserver());
90 chrome::ToggleFullscreenMode(browser());
93 EXPECT_TRUE(frame_view->ShouldPaint());
94 EXPECT_TRUE(frame_view->caption_button_container_->visible());
97 // TODO(zturner): Change this to USE_ASH after fixing the test on Windows.
98 #if defined(OS_CHROMEOS)
99 IN_PROC_BROWSER_TEST_F(BrowserNonClientFrameViewAshTest, ImmersiveFullscreen) {
100 BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser());
101 content::WebContents* web_contents = browser_view->GetActiveWebContents();
102 Widget* widget = browser_view->GetWidget();
103 // We know we're using Ash, so static cast.
104 BrowserNonClientFrameViewAsh* frame_view =
105 static_cast<BrowserNonClientFrameViewAsh*>(
106 widget->non_client_view()->frame_view());
108 ImmersiveModeController* immersive_mode_controller =
109 browser_view->immersive_mode_controller();
110 immersive_mode_controller->SetupForTest();
112 // Immersive fullscreen starts disabled.
113 ASSERT_FALSE(widget->IsFullscreen());
114 EXPECT_FALSE(immersive_mode_controller->IsEnabled());
116 // Frame paints by default.
117 EXPECT_TRUE(frame_view->ShouldPaint());
118 EXPECT_LT(Tab::GetImmersiveHeight(),
119 frame_view->header_painter_->GetHeaderHeightForPainting());
121 // Enter both browser fullscreen and tab fullscreen. Entering browser
122 // fullscreen should enable immersive fullscreen.
124 // NOTIFICATION_FULLSCREEN_CHANGED is sent asynchronously.
125 scoped_ptr<FullscreenNotificationObserver> waiter(
126 new FullscreenNotificationObserver());
127 chrome::ToggleFullscreenMode(browser());
131 scoped_ptr<FullscreenNotificationObserver> waiter(
132 new FullscreenNotificationObserver());
133 browser()->fullscreen_controller()->ToggleFullscreenModeForTab(
137 EXPECT_TRUE(immersive_mode_controller->IsEnabled());
139 // An immersive reveal shows the buttons and the top of the frame.
140 scoped_ptr<ImmersiveRevealedLock> revealed_lock(
141 immersive_mode_controller->GetRevealedLock(
142 ImmersiveModeController::ANIMATE_REVEAL_NO));
143 EXPECT_TRUE(immersive_mode_controller->IsRevealed());
144 EXPECT_TRUE(frame_view->ShouldPaint());
145 EXPECT_TRUE(frame_view->caption_button_container_->visible());
146 EXPECT_FALSE(frame_view->UseImmersiveLightbarHeaderStyle());
148 // End the reveal. When in both immersive browser fullscreen and tab
149 // fullscreen, the tab lightbars should not be painted.
150 revealed_lock.reset();
151 EXPECT_FALSE(immersive_mode_controller->IsRevealed());
152 EXPECT_FALSE(frame_view->ShouldPaint());
153 EXPECT_EQ(0, frame_view->header_painter_->GetHeaderHeightForPainting());
155 // Repeat test but without tab fullscreen. The tab lightbars should now show
156 // when the top-of-window views are not revealed.
158 scoped_ptr<FullscreenNotificationObserver> waiter(
159 new FullscreenNotificationObserver());
160 browser()->fullscreen_controller()->ToggleFullscreenModeForTab(
161 web_contents, false);
165 // Immersive reveal should have same behavior as before.
166 revealed_lock.reset(immersive_mode_controller->GetRevealedLock(
167 ImmersiveModeController::ANIMATE_REVEAL_NO));
168 EXPECT_TRUE(immersive_mode_controller->IsRevealed());
169 EXPECT_TRUE(frame_view->ShouldPaint());
170 EXPECT_TRUE(frame_view->caption_button_container_->visible());
171 EXPECT_FALSE(frame_view->UseImmersiveLightbarHeaderStyle());
172 EXPECT_LT(Tab::GetImmersiveHeight(),
173 frame_view->header_painter_->GetHeaderHeightForPainting());
175 // Ending the reveal should hide the caption buttons and the header should
176 // be in the lightbar style.
177 revealed_lock.reset();
178 EXPECT_TRUE(frame_view->ShouldPaint());
179 EXPECT_FALSE(frame_view->caption_button_container_->visible());
180 EXPECT_TRUE(frame_view->UseImmersiveLightbarHeaderStyle());
181 EXPECT_EQ(Tab::GetImmersiveHeight(),
182 frame_view->header_painter_->GetHeaderHeightForPainting());
184 // Exiting immersive fullscreen should make the caption buttons and the frame
187 scoped_ptr<FullscreenNotificationObserver> waiter(
188 new FullscreenNotificationObserver());
189 browser_view->ExitFullscreen();
192 EXPECT_FALSE(immersive_mode_controller->IsEnabled());
193 EXPECT_TRUE(frame_view->ShouldPaint());
194 EXPECT_TRUE(frame_view->caption_button_container_->visible());
195 EXPECT_FALSE(frame_view->UseImmersiveLightbarHeaderStyle());
196 EXPECT_LT(Tab::GetImmersiveHeight(),
197 frame_view->header_painter_->GetHeaderHeightForPainting());
199 #endif // defined(OS_CHROMEOS)
201 // Tests that FrameCaptionButtonContainer has been relaid out in response to
202 // maximize mode being toggled.
203 IN_PROC_BROWSER_TEST_F(BrowserNonClientFrameViewAshTest,
204 ToggleMaximizeModeRelayout) {
205 BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser());
206 Widget* widget = browser_view->GetWidget();
207 // We know we're using Ash, so static cast.
208 BrowserNonClientFrameViewAsh* frame_view =
209 static_cast<BrowserNonClientFrameViewAsh*>(
210 widget->non_client_view()->frame_view());
212 const gfx::Rect initial = frame_view->caption_button_container_->bounds();
213 ash::Shell::GetInstance()->EnableMaximizeModeWindowManager(true);
214 const gfx::Rect during_maximize = frame_view->caption_button_container_->
216 EXPECT_GT(initial.width(), during_maximize.width());
217 ash::Shell::GetInstance()->EnableMaximizeModeWindowManager(false);
218 const gfx::Rect after_restore = frame_view->caption_button_container_->
220 EXPECT_EQ(initial, after_restore);