browser_non_client_frame_view_ash_browsertest.cc revision 1e9bf3e0803691d0a228da41fc608347b6db4340
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/wm/caption_buttons/frame_caption_button_container_view.h"
10#include "base/command_line.h"
11#include "chrome/browser/ui/browser.h"
12#include "chrome/browser/ui/browser_commands.h"
13#include "chrome/browser/ui/fullscreen/fullscreen_controller.h"
14#include "chrome/browser/ui/fullscreen/fullscreen_controller_test.h"
15#include "chrome/browser/ui/views/frame/browser_view.h"
16#include "chrome/browser/ui/views/frame/immersive_mode_controller.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/widget/widget.h"
21
22using views::Widget;
23
24typedef InProcessBrowserTest BrowserNonClientFrameViewAshTest;
25
26IN_PROC_BROWSER_TEST_F(BrowserNonClientFrameViewAshTest, WindowHeader) {
27  // We know we're using Views, so static cast.
28  BrowserView* browser_view = static_cast<BrowserView*>(browser()->window());
29  Widget* widget = browser_view->GetWidget();
30  // We know we're using Ash, so static cast.
31  BrowserNonClientFrameViewAsh* frame_view =
32      static_cast<BrowserNonClientFrameViewAsh*>(
33          widget->non_client_view()->frame_view());
34
35  // Restored window uses tall header.
36  const int kWindowWidth = 300;
37  const int kWindowHeight = 290;
38  widget->SetBounds(gfx::Rect(10, 10, kWindowWidth, kWindowHeight));
39  EXPECT_FALSE(frame_view->UseShortHeader());
40
41  // Click on the top edge of a window hits the top edge resize handle.
42  gfx::Point top_edge(kWindowWidth / 2, 0);
43  EXPECT_EQ(HTTOP, frame_view->NonClientHitTest(top_edge));
44
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));
48
49  // Window at top of screen uses normal header.
50  widget->SetBounds(gfx::Rect(10, 0, kWindowWidth, kWindowHeight));
51  EXPECT_FALSE(frame_view->UseShortHeader());
52
53  // Maximized window uses short header.
54  widget->Maximize();
55  EXPECT_TRUE(frame_view->UseShortHeader());
56
57  // Click in the top edge of a maximized window now hits the client area,
58  // because we want it to fall through to the tab strip and select a tab.
59  EXPECT_EQ(HTCLIENT, frame_view->NonClientHitTest(top_edge));
60
61  // Popups tall header.
62  Browser* popup = CreateBrowserForPopup(browser()->profile());
63  Widget* popup_widget =
64      static_cast<BrowserView*>(popup->window())->GetWidget();
65  BrowserNonClientFrameViewAsh* popup_frame_view =
66      static_cast<BrowserNonClientFrameViewAsh*>(
67          popup_widget->non_client_view()->frame_view());
68  popup_widget->SetBounds(gfx::Rect(5, 5, 200, 200));
69  EXPECT_FALSE(popup_frame_view->UseShortHeader());
70
71  // Apps use tall header.
72  Browser* app = CreateBrowserForApp("name", browser()->profile());
73  Widget* app_widget =
74      static_cast<BrowserView*>(app->window())->GetWidget();
75  BrowserNonClientFrameViewAsh* app_frame_view =
76      static_cast<BrowserNonClientFrameViewAsh*>(
77          app_widget->non_client_view()->frame_view());
78  app_widget->SetBounds(gfx::Rect(15, 15, 250, 250));
79  EXPECT_FALSE(app_frame_view->UseShortHeader());
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  // We know we're using Views, so static cast.
87  BrowserView* browser_view = static_cast<BrowserView*>(browser()->window());
88  content::WebContents* web_contents = browser_view->GetActiveWebContents();
89  Widget* widget = browser_view->GetWidget();
90  // We know we're using Ash, so static cast.
91  BrowserNonClientFrameViewAsh* frame_view =
92      static_cast<BrowserNonClientFrameViewAsh*>(
93          widget->non_client_view()->frame_view());
94
95  // Frame paints by default.
96  EXPECT_TRUE(frame_view->ShouldPaint());
97
98  // No painting should occur in non-immersive fullscreen. (We enter into tab
99  // fullscreen here because tab fullscreen is non-immersive even on ChromeOS).
100  {
101    // NOTIFICATION_FULLSCREEN_CHANGED is sent asynchronously.
102    scoped_ptr<FullscreenNotificationObserver> waiter(
103        new FullscreenNotificationObserver());
104    browser()->fullscreen_controller()->ToggleFullscreenModeForTab(
105        web_contents, true);
106    waiter->Wait();
107  }
108  EXPECT_FALSE(browser_view->immersive_mode_controller()->IsEnabled());
109  EXPECT_FALSE(frame_view->ShouldPaint());
110
111  // The client view abuts top of the window.
112  EXPECT_EQ(0, frame_view->NonClientTopBorderHeight());
113
114  // The frame should be painted again when fullscreen is exited and the caption
115  // buttons should be visible.
116  {
117    scoped_ptr<FullscreenNotificationObserver> waiter(
118        new FullscreenNotificationObserver());
119    chrome::ToggleFullscreenMode(browser());
120    waiter->Wait();
121  }
122  EXPECT_TRUE(frame_view->ShouldPaint());
123  EXPECT_TRUE(frame_view->caption_button_container_->visible());
124}
125
126IN_PROC_BROWSER_TEST_F(BrowserNonClientFrameViewAshTest, ImmersiveFullscreen) {
127  // We know we're using Views, so static cast.
128  BrowserView* browser_view = static_cast<BrowserView*>(browser()->window());
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 mode 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
147  // Enter both browser fullscreen and tab fullscreen. Entering browser
148  // fullscreen should enable immersive fullscreen.
149  {
150    // NOTIFICATION_FULLSCREEN_CHANGED is sent asynchronously.
151    scoped_ptr<FullscreenNotificationObserver> waiter(
152        new FullscreenNotificationObserver());
153    chrome::ToggleFullscreenMode(browser());
154    waiter->Wait();
155  }
156  {
157    scoped_ptr<FullscreenNotificationObserver> waiter(
158        new FullscreenNotificationObserver());
159    browser()->fullscreen_controller()->ToggleFullscreenModeForTab(
160        web_contents, true);
161    waiter->Wait();
162  }
163  EXPECT_TRUE(immersive_mode_controller->IsEnabled());
164
165  // An immersive reveal shows the buttons and the top of the frame.
166  scoped_ptr<ImmersiveRevealedLock> revealed_lock(
167      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_TRUE(frame_view->UseShortHeader());
173  EXPECT_FALSE(frame_view->UseImmersiveLightbarHeaderStyle());
174
175  // End the reveal. When in both immersive browser fullscreen and tab
176  // fullscreen, the tab lightbars should not be painted.
177  revealed_lock.reset();
178  EXPECT_FALSE(immersive_mode_controller->IsRevealed());
179  EXPECT_FALSE(frame_view->ShouldPaint());
180
181  // Repeat test but without tab fullscreen. The tab lightbars should now show
182  // when the top-of-window views are not revealed.
183  {
184    scoped_ptr<FullscreenNotificationObserver> waiter(
185        new FullscreenNotificationObserver());
186    browser()->fullscreen_controller()->ToggleFullscreenModeForTab(
187        web_contents, false);
188    waiter->Wait();
189  }
190
191  // Immersive reveal should have same behavior as before.
192  revealed_lock.reset(immersive_mode_controller->GetRevealedLock(
193      ImmersiveModeController::ANIMATE_REVEAL_NO));
194  EXPECT_TRUE(immersive_mode_controller->IsRevealed());
195  EXPECT_TRUE(frame_view->ShouldPaint());
196  EXPECT_TRUE(frame_view->caption_button_container_->visible());
197  EXPECT_TRUE(frame_view->UseShortHeader());
198  EXPECT_FALSE(frame_view->UseImmersiveLightbarHeaderStyle());
199
200  // Ending the reveal should hide the caption buttons and the header should
201  // be in the lightbar style.
202  revealed_lock.reset();
203  EXPECT_TRUE(frame_view->ShouldPaint());
204  EXPECT_FALSE(frame_view->caption_button_container_->visible());
205  EXPECT_TRUE(frame_view->UseShortHeader());
206  EXPECT_TRUE(frame_view->UseImmersiveLightbarHeaderStyle());
207
208  // Exiting immersive fullscreen should make the caption buttons and the frame
209  // visible again.
210  {
211    scoped_ptr<FullscreenNotificationObserver> waiter(
212        new FullscreenNotificationObserver());
213    browser_view->ExitFullscreen();
214    waiter->Wait();
215  }
216  EXPECT_FALSE(immersive_mode_controller->IsEnabled());
217  EXPECT_TRUE(frame_view->ShouldPaint());
218  EXPECT_TRUE(frame_view->caption_button_container_->visible());
219  EXPECT_FALSE(frame_view->UseImmersiveLightbarHeaderStyle());
220}
221