browser_non_client_frame_view_ash_browsertest.cc revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
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 "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"
24
25using views::Widget;
26
27typedef InProcessBrowserTest BrowserNonClientFrameViewAshTest;
28
29IN_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());
36
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));
43
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));
47
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.
50  widget->Maximize();
51  EXPECT_EQ(HTCLIENT, frame_view->NonClientHitTest(top_edge));
52}
53
54// Test that the frame view does not do any painting in non-immersive
55// fullscreen.
56IN_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());
65
66  // Frame paints by default.
67  EXPECT_TRUE(frame_view->ShouldPaint());
68
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).
71  {
72    // NOTIFICATION_FULLSCREEN_CHANGED is sent asynchronously.
73    scoped_ptr<FullscreenNotificationObserver> waiter(
74        new FullscreenNotificationObserver());
75    browser()->fullscreen_controller()->ToggleFullscreenModeForTab(
76        web_contents, true);
77    waiter->Wait();
78  }
79  EXPECT_FALSE(browser_view->immersive_mode_controller()->IsEnabled());
80  EXPECT_FALSE(frame_view->ShouldPaint());
81
82  // The client view abuts top of the window.
83  EXPECT_EQ(0, frame_view->GetBoundsForClientView().y());
84
85  // The frame should be painted again when fullscreen is exited and the caption
86  // buttons should be visible.
87  {
88    scoped_ptr<FullscreenNotificationObserver> waiter(
89        new FullscreenNotificationObserver());
90    chrome::ToggleFullscreenMode(browser());
91    waiter->Wait();
92  }
93  EXPECT_TRUE(frame_view->ShouldPaint());
94  EXPECT_TRUE(frame_view->caption_button_container_->visible());
95}
96
97// Immersive fullscreen is CrOS only for now.
98#if defined(OS_CHROMEOS)
99IN_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());
107
108  ImmersiveModeController* immersive_mode_controller =
109      browser_view->immersive_mode_controller();
110  immersive_mode_controller->SetupForTest();
111
112  // Immersive fullscreen starts disabled.
113  ASSERT_FALSE(widget->IsFullscreen());
114  EXPECT_FALSE(immersive_mode_controller->IsEnabled());
115
116  // Frame paints by default.
117  EXPECT_TRUE(frame_view->ShouldPaint());
118  EXPECT_LT(Tab::GetImmersiveHeight(),
119            frame_view->header_painter_->GetHeaderHeightForPainting());
120
121  // Enter both browser fullscreen and tab fullscreen. Entering browser
122  // fullscreen should enable immersive fullscreen.
123  {
124    // NOTIFICATION_FULLSCREEN_CHANGED is sent asynchronously.
125    scoped_ptr<FullscreenNotificationObserver> waiter(
126        new FullscreenNotificationObserver());
127    chrome::ToggleFullscreenMode(browser());
128    waiter->Wait();
129  }
130  {
131    scoped_ptr<FullscreenNotificationObserver> waiter(
132        new FullscreenNotificationObserver());
133    browser()->fullscreen_controller()->ToggleFullscreenModeForTab(
134        web_contents, true);
135    waiter->Wait();
136  }
137  EXPECT_TRUE(immersive_mode_controller->IsEnabled());
138
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());
147
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());
154
155  // Repeat test but without tab fullscreen. The tab lightbars should now show
156  // when the top-of-window views are not revealed.
157  {
158    scoped_ptr<FullscreenNotificationObserver> waiter(
159        new FullscreenNotificationObserver());
160    browser()->fullscreen_controller()->ToggleFullscreenModeForTab(
161        web_contents, false);
162    waiter->Wait();
163  }
164
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());
174
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());
183
184  // Exiting immersive fullscreen should make the caption buttons and the frame
185  // visible again.
186  {
187    scoped_ptr<FullscreenNotificationObserver> waiter(
188        new FullscreenNotificationObserver());
189    browser_view->ExitFullscreen();
190    waiter->Wait();
191  }
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());
198}
199#endif  // defined(OS_CHROMEOS)
200
201// Tests that FrameCaptionButtonContainer has been relaid out in response to
202// maximize mode being toggled.
203IN_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());
211
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_->
215      bounds();
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_->
219      bounds();
220  EXPECT_EQ(initial, after_restore);
221}
222