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 "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"
28 typedef InProcessBrowserTest BrowserNonClientFrameViewAshTest;
30 IN_PROC_BROWSER_TEST_F(BrowserNonClientFrameViewAshTest, NonClientHitTest) {
31 BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser());
32 Widget* widget = browser_view->GetWidget();
33 // We know we're using Ash, so static cast.
34 BrowserNonClientFrameViewAsh* frame_view =
35 static_cast<BrowserNonClientFrameViewAsh*>(
36 widget->non_client_view()->frame_view());
38 // Click on the top edge of a restored window hits the top edge resize handle.
39 const int kWindowWidth = 300;
40 const int kWindowHeight = 290;
41 widget->SetBounds(gfx::Rect(10, 10, kWindowWidth, kWindowHeight));
42 gfx::Point top_edge(kWindowWidth / 2, 0);
43 EXPECT_EQ(HTTOP, frame_view->NonClientHitTest(top_edge));
45 // Click just below the resize handle hits the caption.
46 gfx::Point below_resize(kWindowWidth / 2, ash::kResizeInsideBoundsSize);
47 EXPECT_EQ(HTCAPTION, frame_view->NonClientHitTest(below_resize));
49 // Click in the top edge of a maximized window now hits the client area,
50 // because we want it to fall through to the tab strip and select a tab.
52 EXPECT_EQ(HTCLIENT, frame_view->NonClientHitTest(top_edge));
55 // Test that the frame view does not do any painting in non-immersive
57 IN_PROC_BROWSER_TEST_F(BrowserNonClientFrameViewAshTest,
58 NonImmersiveFullscreen) {
59 BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser());
60 content::WebContents* web_contents = browser_view->GetActiveWebContents();
61 Widget* widget = browser_view->GetWidget();
62 // We know we're using Ash, so static cast.
63 BrowserNonClientFrameViewAsh* frame_view =
64 static_cast<BrowserNonClientFrameViewAsh*>(
65 widget->non_client_view()->frame_view());
67 // Frame paints by default.
68 EXPECT_TRUE(frame_view->ShouldPaint());
70 // No painting should occur in non-immersive fullscreen. (We enter into tab
71 // fullscreen here because tab fullscreen is non-immersive even on ChromeOS).
73 // NOTIFICATION_FULLSCREEN_CHANGED is sent asynchronously.
74 scoped_ptr<FullscreenNotificationObserver> waiter(
75 new FullscreenNotificationObserver());
76 browser()->fullscreen_controller()->ToggleFullscreenModeForTab(
80 EXPECT_FALSE(browser_view->immersive_mode_controller()->IsEnabled());
81 EXPECT_FALSE(frame_view->ShouldPaint());
83 // The client view abuts top of the window.
84 EXPECT_EQ(0, frame_view->GetBoundsForClientView().y());
86 // The frame should be painted again when fullscreen is exited and the caption
87 // buttons should be visible.
89 scoped_ptr<FullscreenNotificationObserver> waiter(
90 new FullscreenNotificationObserver());
91 chrome::ToggleFullscreenMode(browser());
94 EXPECT_TRUE(frame_view->ShouldPaint());
95 EXPECT_TRUE(frame_view->caption_button_container_->visible());
98 // TODO(zturner): Change this to USE_ASH after fixing the test on Windows.
99 #if defined(OS_CHROMEOS)
100 IN_PROC_BROWSER_TEST_F(BrowserNonClientFrameViewAshTest, ImmersiveFullscreen) {
101 BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser());
102 content::WebContents* web_contents = browser_view->GetActiveWebContents();
103 Widget* widget = browser_view->GetWidget();
104 // We know we're using Ash, so static cast.
105 BrowserNonClientFrameViewAsh* frame_view =
106 static_cast<BrowserNonClientFrameViewAsh*>(
107 widget->non_client_view()->frame_view());
109 ImmersiveModeController* immersive_mode_controller =
110 browser_view->immersive_mode_controller();
111 immersive_mode_controller->SetupForTest();
113 // Immersive fullscreen starts disabled.
114 ASSERT_FALSE(widget->IsFullscreen());
115 EXPECT_FALSE(immersive_mode_controller->IsEnabled());
117 // Frame paints by default.
118 EXPECT_TRUE(frame_view->ShouldPaint());
119 EXPECT_LT(Tab::GetImmersiveHeight(),
120 frame_view->header_painter_->GetHeaderHeightForPainting());
122 // Enter both browser fullscreen and tab fullscreen. Entering browser
123 // fullscreen should enable immersive fullscreen.
125 // NOTIFICATION_FULLSCREEN_CHANGED is sent asynchronously.
126 scoped_ptr<FullscreenNotificationObserver> waiter(
127 new FullscreenNotificationObserver());
128 chrome::ToggleFullscreenMode(browser());
132 scoped_ptr<FullscreenNotificationObserver> waiter(
133 new FullscreenNotificationObserver());
134 browser()->fullscreen_controller()->ToggleFullscreenModeForTab(
138 EXPECT_TRUE(immersive_mode_controller->IsEnabled());
140 // An immersive reveal shows the buttons and the top of the frame.
141 scoped_ptr<ImmersiveRevealedLock> revealed_lock(
142 immersive_mode_controller->GetRevealedLock(
143 ImmersiveModeController::ANIMATE_REVEAL_NO));
144 EXPECT_TRUE(immersive_mode_controller->IsRevealed());
145 EXPECT_TRUE(frame_view->ShouldPaint());
146 EXPECT_TRUE(frame_view->caption_button_container_->visible());
147 EXPECT_FALSE(frame_view->UseImmersiveLightbarHeaderStyle());
149 // End the reveal. When in both immersive browser fullscreen and tab
150 // fullscreen, the tab lightbars should not be painted.
151 revealed_lock.reset();
152 EXPECT_FALSE(immersive_mode_controller->IsRevealed());
153 EXPECT_FALSE(frame_view->ShouldPaint());
154 EXPECT_EQ(0, frame_view->header_painter_->GetHeaderHeightForPainting());
156 // Repeat test but without tab fullscreen. The tab lightbars should now show
157 // when the top-of-window views are not revealed.
159 scoped_ptr<FullscreenNotificationObserver> waiter(
160 new FullscreenNotificationObserver());
161 browser()->fullscreen_controller()->ToggleFullscreenModeForTab(
162 web_contents, false);
166 // Immersive reveal should have same behavior as before.
167 revealed_lock.reset(immersive_mode_controller->GetRevealedLock(
168 ImmersiveModeController::ANIMATE_REVEAL_NO));
169 EXPECT_TRUE(immersive_mode_controller->IsRevealed());
170 EXPECT_TRUE(frame_view->ShouldPaint());
171 EXPECT_TRUE(frame_view->caption_button_container_->visible());
172 EXPECT_FALSE(frame_view->UseImmersiveLightbarHeaderStyle());
173 EXPECT_LT(Tab::GetImmersiveHeight(),
174 frame_view->header_painter_->GetHeaderHeightForPainting());
176 // Ending the reveal should hide the caption buttons and the header should
177 // be in the lightbar style.
178 revealed_lock.reset();
179 EXPECT_TRUE(frame_view->ShouldPaint());
180 EXPECT_FALSE(frame_view->caption_button_container_->visible());
181 EXPECT_TRUE(frame_view->UseImmersiveLightbarHeaderStyle());
182 EXPECT_EQ(Tab::GetImmersiveHeight(),
183 frame_view->header_painter_->GetHeaderHeightForPainting());
185 // Exiting immersive fullscreen should make the caption buttons and the frame
188 scoped_ptr<FullscreenNotificationObserver> waiter(
189 new FullscreenNotificationObserver());
190 browser_view->ExitFullscreen();
193 EXPECT_FALSE(immersive_mode_controller->IsEnabled());
194 EXPECT_TRUE(frame_view->ShouldPaint());
195 EXPECT_TRUE(frame_view->caption_button_container_->visible());
196 EXPECT_FALSE(frame_view->UseImmersiveLightbarHeaderStyle());
197 EXPECT_LT(Tab::GetImmersiveHeight(),
198 frame_view->header_painter_->GetHeaderHeightForPainting());
200 #endif // defined(OS_CHROMEOS)
202 // Tests that FrameCaptionButtonContainer has been relaid out in response to
203 // maximize mode being toggled.
204 IN_PROC_BROWSER_TEST_F(BrowserNonClientFrameViewAshTest,
205 ToggleMaximizeModeRelayout) {
206 BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser());
207 Widget* widget = browser_view->GetWidget();
208 // We know we're using Ash, so static cast.
209 BrowserNonClientFrameViewAsh* frame_view =
210 static_cast<BrowserNonClientFrameViewAsh*>(
211 widget->non_client_view()->frame_view());
213 const gfx::Rect initial = frame_view->caption_button_container_->bounds();
214 ash::Shell::GetInstance()->maximize_mode_controller()->
215 EnableMaximizeModeWindowManager(true);
216 ash::FrameCaptionButtonContainerView::TestApi test(frame_view->
217 caption_button_container_);
218 test.EndAnimations();
219 const gfx::Rect during_maximize = frame_view->caption_button_container_->
221 EXPECT_GT(initial.width(), during_maximize.width());
222 ash::Shell::GetInstance()->maximize_mode_controller()->
223 EnableMaximizeModeWindowManager(false);
224 test.EndAnimations();
225 const gfx::Rect after_restore = frame_view->caption_button_container_->
227 EXPECT_EQ(initial, after_restore);