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/wm/caption_buttons/frame_caption_button_container_view.h"
10 #include "ash/wm/header_painter.h"
11 #include "base/command_line.h"
12 #include "chrome/browser/ui/browser.h"
13 #include "chrome/browser/ui/browser_commands.h"
14 #include "chrome/browser/ui/fullscreen/fullscreen_controller.h"
15 #include "chrome/browser/ui/fullscreen/fullscreen_controller_test.h"
16 #include "chrome/browser/ui/views/frame/browser_view.h"
17 #include "chrome/browser/ui/views/frame/immersive_mode_controller.h"
18 #include "chrome/browser/ui/views/tabs/tab.h"
19 #include "chrome/test/base/in_process_browser_test.h"
20 #include "ui/base/hit_test.h"
21 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
22 #include "ui/views/widget/widget.h"
26 typedef InProcessBrowserTest BrowserNonClientFrameViewAshTest;
28 IN_PROC_BROWSER_TEST_F(BrowserNonClientFrameViewAshTest, NonClientHitTest) {
29 // We know we're using Views, so static cast.
30 BrowserView* browser_view = static_cast<BrowserView*>(browser()->window());
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 // We know we're using Views, so static cast.
59 BrowserView* browser_view = static_cast<BrowserView*>(browser()->window());
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 // Immersive fullscreen is CrOS only for now.
99 #if defined(OS_CHROMEOS)
100 IN_PROC_BROWSER_TEST_F(BrowserNonClientFrameViewAshTest, ImmersiveFullscreen) {
101 // We know we're using Views, so static cast.
102 BrowserView* browser_view = static_cast<BrowserView*>(browser()->window());
103 content::WebContents* web_contents = browser_view->GetActiveWebContents();
104 Widget* widget = browser_view->GetWidget();
105 // We know we're using Ash, so static cast.
106 BrowserNonClientFrameViewAsh* frame_view =
107 static_cast<BrowserNonClientFrameViewAsh*>(
108 widget->non_client_view()->frame_view());
110 ImmersiveModeController* immersive_mode_controller =
111 browser_view->immersive_mode_controller();
112 immersive_mode_controller->SetupForTest();
114 // Immersive fullscreen starts disabled.
115 ASSERT_FALSE(widget->IsFullscreen());
116 EXPECT_FALSE(immersive_mode_controller->IsEnabled());
118 // Frame paints by default.
119 EXPECT_TRUE(frame_view->ShouldPaint());
120 EXPECT_LT(Tab::GetImmersiveHeight(),
121 frame_view->header_painter_->header_height());
123 // Enter both browser fullscreen and tab fullscreen. Entering browser
124 // fullscreen should enable immersive fullscreen.
126 // NOTIFICATION_FULLSCREEN_CHANGED is sent asynchronously.
127 scoped_ptr<FullscreenNotificationObserver> waiter(
128 new FullscreenNotificationObserver());
129 chrome::ToggleFullscreenMode(browser());
133 scoped_ptr<FullscreenNotificationObserver> waiter(
134 new FullscreenNotificationObserver());
135 browser()->fullscreen_controller()->ToggleFullscreenModeForTab(
139 EXPECT_TRUE(immersive_mode_controller->IsEnabled());
141 // An immersive reveal shows the buttons and the top of the frame.
142 scoped_ptr<ImmersiveRevealedLock> revealed_lock(
143 immersive_mode_controller->GetRevealedLock(
144 ImmersiveModeController::ANIMATE_REVEAL_NO));
145 EXPECT_TRUE(immersive_mode_controller->IsRevealed());
146 EXPECT_TRUE(frame_view->ShouldPaint());
147 EXPECT_TRUE(frame_view->caption_button_container_->visible());
148 EXPECT_FALSE(frame_view->UseImmersiveLightbarHeaderStyle());
150 // End the reveal. When in both immersive browser fullscreen and tab
151 // fullscreen, the tab lightbars should not be painted.
152 revealed_lock.reset();
153 EXPECT_FALSE(immersive_mode_controller->IsRevealed());
154 EXPECT_FALSE(frame_view->ShouldPaint());
155 EXPECT_EQ(0, frame_view->header_painter_->header_height());
157 // Repeat test but without tab fullscreen. The tab lightbars should now show
158 // when the top-of-window views are not revealed.
160 scoped_ptr<FullscreenNotificationObserver> waiter(
161 new FullscreenNotificationObserver());
162 browser()->fullscreen_controller()->ToggleFullscreenModeForTab(
163 web_contents, false);
167 // Immersive reveal should have same behavior as before.
168 revealed_lock.reset(immersive_mode_controller->GetRevealedLock(
169 ImmersiveModeController::ANIMATE_REVEAL_NO));
170 EXPECT_TRUE(immersive_mode_controller->IsRevealed());
171 EXPECT_TRUE(frame_view->ShouldPaint());
172 EXPECT_TRUE(frame_view->caption_button_container_->visible());
173 EXPECT_FALSE(frame_view->UseImmersiveLightbarHeaderStyle());
174 EXPECT_LT(Tab::GetImmersiveHeight(),
175 frame_view->header_painter_->header_height());
177 // Ending the reveal should hide the caption buttons and the header should
178 // be in the lightbar style.
179 revealed_lock.reset();
180 EXPECT_TRUE(frame_view->ShouldPaint());
181 EXPECT_FALSE(frame_view->caption_button_container_->visible());
182 EXPECT_TRUE(frame_view->UseImmersiveLightbarHeaderStyle());
183 EXPECT_EQ(Tab::GetImmersiveHeight(),
184 frame_view->header_painter_->header_height());
186 // Exiting immersive fullscreen should make the caption buttons and the frame
189 scoped_ptr<FullscreenNotificationObserver> waiter(
190 new FullscreenNotificationObserver());
191 browser_view->ExitFullscreen();
194 EXPECT_FALSE(immersive_mode_controller->IsEnabled());
195 EXPECT_TRUE(frame_view->ShouldPaint());
196 EXPECT_TRUE(frame_view->caption_button_container_->visible());
197 EXPECT_FALSE(frame_view->UseImmersiveLightbarHeaderStyle());
198 EXPECT_LT(Tab::GetImmersiveHeight(),
199 frame_view->header_painter_->header_height());
201 #endif // defined(OS_CHROMEOS)