1 // Copyright 2014 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 "ash/frame/custom_frame_view_ash.h"
7 #include "ash/frame/caption_buttons/frame_caption_button.h"
8 #include "ash/frame/caption_buttons/frame_caption_button_container_view.h"
10 #include "ash/test/ash_test_base.h"
11 #include "ash/test/test_session_state_delegate.h"
12 #include "ash/wm/maximize_mode/maximize_mode_controller.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "grit/ash_resources.h"
15 #include "ui/base/resource/resource_bundle.h"
16 #include "ui/gfx/geometry/rect.h"
17 #include "ui/gfx/image/image_skia.h"
18 #include "ui/views/widget/widget.h"
19 #include "ui/views/widget/widget_delegate.h"
23 // A views::WidgetDelegate which uses a CustomFrameViewAsh.
24 class TestWidgetDelegate
: public views::WidgetDelegateView
{
26 TestWidgetDelegate() {}
27 ~TestWidgetDelegate() override
{}
29 views::NonClientFrameView
* CreateNonClientFrameView(
30 views::Widget
* widget
) override
{
31 custom_frame_view_
= new CustomFrameViewAsh(widget
);
32 return custom_frame_view_
;
35 CustomFrameViewAsh
* custom_frame_view() const {
36 return custom_frame_view_
;
41 CustomFrameViewAsh
* custom_frame_view_
;
43 DISALLOW_COPY_AND_ASSIGN(TestWidgetDelegate
);
46 class TestWidgetConstraintsDelegate
: public TestWidgetDelegate
{
48 TestWidgetConstraintsDelegate() {}
49 ~TestWidgetConstraintsDelegate() override
{}
52 gfx::Size
GetMinimumSize() const override
{ return minimum_size_
; }
54 gfx::Size
GetMaximumSize() const override
{ return maximum_size_
; }
56 views::View
* GetContentsView() override
{
57 // Set this instance as the contents view so that the maximum and minimum
58 // size constraints will be used.
62 // views::WidgetDelegate:
63 bool CanMaximize() const override
{ return true; }
65 bool CanMinimize() const override
{ return true; }
67 void set_minimum_size(const gfx::Size
& min_size
) {
68 minimum_size_
= min_size
;
71 void set_maximum_size(const gfx::Size
& max_size
) {
72 maximum_size_
= max_size
;
75 const gfx::Rect
& GetFrameCaptionButtonContainerViewBounds() {
76 return custom_frame_view()->GetFrameCaptionButtonContainerViewForTest()->
80 void EndFrameCaptionButtonContainerViewAnimations() {
81 FrameCaptionButtonContainerView::TestApi
test(custom_frame_view()->
82 GetFrameCaptionButtonContainerViewForTest());
86 int GetTitleBarHeight() const {
87 return custom_frame_view()->NonClientTopBorderHeight();
91 gfx::Size minimum_size_
;
92 gfx::Size maximum_size_
;
94 DISALLOW_COPY_AND_ASSIGN(TestWidgetConstraintsDelegate
);
97 class CustomFrameViewAshTest
: public test::AshTestBase
{
99 CustomFrameViewAshTest() {}
100 ~CustomFrameViewAshTest() override
{}
103 scoped_ptr
<views::Widget
> CreateWidget(TestWidgetDelegate
* delegate
) {
104 scoped_ptr
<views::Widget
> widget(new views::Widget
);
105 views::Widget::InitParams params
;
106 params
.delegate
= delegate
;
107 params
.ownership
= views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET
;
108 params
.bounds
= gfx::Rect(0, 0, 100, 100);
109 params
.context
= CurrentContext();
110 widget
->Init(params
);
111 return widget
.Pass();
114 test::TestSessionStateDelegate
* GetTestSessionStateDelegate() {
115 return static_cast<ash::test::TestSessionStateDelegate
*>(
116 Shell::GetInstance()->session_state_delegate());
120 DISALLOW_COPY_AND_ASSIGN(CustomFrameViewAshTest
);
123 // Test that the height of the header is correct upon initially displaying
125 TEST_F(CustomFrameViewAshTest
, HeaderHeight
) {
126 TestWidgetDelegate
* delegate
= new TestWidgetDelegate
;
128 scoped_ptr
<views::Widget
> widget(CreateWidget(delegate
));
131 ui::ResourceBundle
& rb
= ui::ResourceBundle::GetSharedInstance();
132 gfx::ImageSkia
* close_button
=
133 rb
.GetImageSkiaNamed(IDR_AURA_WINDOW_CONTROL_BACKGROUND_H
);
135 // The header should have enough room for the window controls. The
136 // header/content separator line overlays the window controls.
137 EXPECT_EQ(close_button
->height(),
138 delegate
->custom_frame_view()->GetHeaderView()->height());
141 // Verify that CustomFrameViewAsh returns the correct minimum and maximum frame
142 // sizes when the client view does not specify any size constraints.
143 TEST_F(CustomFrameViewAshTest
, NoSizeConstraints
) {
144 TestWidgetConstraintsDelegate
* delegate
= new TestWidgetConstraintsDelegate
;
145 scoped_ptr
<views::Widget
> widget(CreateWidget(delegate
));
147 CustomFrameViewAsh
* custom_frame_view
= delegate
->custom_frame_view();
148 gfx::Size min_frame_size
= custom_frame_view
->GetMinimumSize();
149 gfx::Size max_frame_size
= custom_frame_view
->GetMaximumSize();
151 EXPECT_EQ(delegate
->GetTitleBarHeight(), min_frame_size
.height());
153 // A width and height constraint of 0 denotes unbounded.
154 EXPECT_EQ(0, max_frame_size
.width());
155 EXPECT_EQ(0, max_frame_size
.height());
158 // Verify that CustomFrameViewAsh returns the correct minimum and maximum frame
159 // sizes when the client view specifies size constraints.
160 TEST_F(CustomFrameViewAshTest
, MinimumAndMaximumSize
) {
161 gfx::Size
min_client_size(500, 500);
162 gfx::Size
max_client_size(800, 800);
163 TestWidgetConstraintsDelegate
* delegate
= new TestWidgetConstraintsDelegate
;
164 delegate
->set_minimum_size(min_client_size
);
165 delegate
->set_maximum_size(max_client_size
);
166 scoped_ptr
<views::Widget
> widget(CreateWidget(delegate
));
168 CustomFrameViewAsh
* custom_frame_view
= delegate
->custom_frame_view();
169 gfx::Size min_frame_size
= custom_frame_view
->GetMinimumSize();
170 gfx::Size max_frame_size
= custom_frame_view
->GetMaximumSize();
172 EXPECT_EQ(min_client_size
.width(), min_frame_size
.width());
173 EXPECT_EQ(max_client_size
.width(), max_frame_size
.width());
174 EXPECT_EQ(min_client_size
.height() + delegate
->GetTitleBarHeight(),
175 min_frame_size
.height());
176 EXPECT_EQ(max_client_size
.height() + delegate
->GetTitleBarHeight(),
177 max_frame_size
.height());
180 // Verify that CustomFrameViewAsh updates the avatar icon based on the
181 // state of the SessionStateDelegate after visibility change.
182 TEST_F(CustomFrameViewAshTest
, AvatarIcon
) {
183 TestWidgetConstraintsDelegate
* delegate
= new TestWidgetConstraintsDelegate
;
184 scoped_ptr
<views::Widget
> widget(CreateWidget(delegate
));
186 CustomFrameViewAsh
* custom_frame_view
= delegate
->custom_frame_view();
187 EXPECT_FALSE(custom_frame_view
->GetAvatarIconViewForTest());
189 // Avatar image becomes available.
190 const gfx::ImageSkia user_image
=
191 *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
192 IDR_AURA_UBER_TRAY_GUEST_ICON
);
193 GetTestSessionStateDelegate()->SetUserImage(user_image
);
196 EXPECT_TRUE(custom_frame_view
->GetAvatarIconViewForTest());
198 // Avatar image is gone; the ImageView for the avatar icon should be
200 GetTestSessionStateDelegate()->SetUserImage(gfx::ImageSkia());
203 EXPECT_FALSE(custom_frame_view
->GetAvatarIconViewForTest());
206 // The visibility of the size button is updated when maximize mode is toggled.
207 // Verify that the layout of the HeaderView is updated for the size button's
209 TEST_F(CustomFrameViewAshTest
, HeaderViewNotifiedOfChildSizeChange
) {
210 TestWidgetConstraintsDelegate
* delegate
= new TestWidgetConstraintsDelegate
;
211 scoped_ptr
<views::Widget
> widget(CreateWidget(delegate
));
213 const gfx::Rect initial
= delegate
->
214 GetFrameCaptionButtonContainerViewBounds();
215 Shell::GetInstance()->maximize_mode_controller()->
216 EnableMaximizeModeWindowManager(true);
217 delegate
->EndFrameCaptionButtonContainerViewAnimations();
218 const gfx::Rect maximize_mode_bounds
= delegate
->
219 GetFrameCaptionButtonContainerViewBounds();
220 EXPECT_GT(initial
.width(), maximize_mode_bounds
.width());
221 Shell::GetInstance()->maximize_mode_controller()->
222 EnableMaximizeModeWindowManager(false);
223 delegate
->EndFrameCaptionButtonContainerViewAnimations();
224 const gfx::Rect after_restore
= delegate
->
225 GetFrameCaptionButtonContainerViewBounds();
226 EXPECT_EQ(initial
, after_restore
);