Add new certificateProvider extension API.
[chromium-blink-merge.git] / chrome / browser / ui / views / frame / browser_non_client_frame_view.cc
blobc4d6a7ca719158b18466c7dcdf66705d39ce22b1
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.h"
7 #include "chrome/browser/browser_process.h"
8 #include "chrome/browser/profiles/avatar_menu.h"
9 #include "chrome/browser/profiles/profile.h"
10 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
11 #include "chrome/browser/profiles/profile_info_cache.h"
12 #include "chrome/browser/profiles/profile_manager.h"
13 #include "chrome/browser/profiles/profiles_state.h"
14 #include "chrome/browser/themes/theme_properties.h"
15 #include "chrome/browser/ui/view_ids.h"
16 #include "chrome/browser/ui/views/frame/browser_view.h"
17 #include "chrome/browser/ui/views/frame/taskbar_decorator.h"
18 #include "chrome/browser/ui/views/profiles/avatar_menu_button.h"
19 #include "chrome/browser/ui/views/profiles/new_avatar_button.h"
20 #include "chrome/browser/ui/views/tabs/tab_strip.h"
21 #include "chrome/browser/ui/views/theme_image_mapper.h"
22 #include "components/signin/core/common/profile_management_switches.h"
23 #include "grit/theme_resources.h"
24 #include "third_party/skia/include/core/SkColor.h"
25 #include "ui/base/resource/resource_bundle.h"
26 #include "ui/base/theme_provider.h"
27 #include "ui/gfx/image/image.h"
28 #include "ui/resources/grit/ui_resources.h"
29 #include "ui/views/background.h"
30 #include "ui/views/resources/grit/views_resources.h"
32 #if defined(ENABLE_SUPERVISED_USERS)
33 #include "chrome/browser/ui/views/profiles/supervised_user_avatar_label.h"
34 #endif
36 BrowserNonClientFrameView::BrowserNonClientFrameView(BrowserFrame* frame,
37 BrowserView* browser_view)
38 : frame_(frame),
39 browser_view_(browser_view),
40 #if defined(ENABLE_SUPERVISED_USERS)
41 supervised_user_avatar_label_(nullptr),
42 #endif
43 #if defined(FRAME_AVATAR_BUTTON)
44 new_avatar_button_(nullptr),
45 #endif
46 avatar_button_(nullptr) {
47 // The profile manager may by null in tests.
48 if (g_browser_process->profile_manager()) {
49 ProfileInfoCache& cache =
50 g_browser_process->profile_manager()->GetProfileInfoCache();
51 cache.AddObserver(this);
55 BrowserNonClientFrameView::~BrowserNonClientFrameView() {
56 // The profile manager may by null in tests.
57 if (g_browser_process->profile_manager()) {
58 ProfileInfoCache& cache =
59 g_browser_process->profile_manager()->GetProfileInfoCache();
60 cache.RemoveObserver(this);
64 void BrowserNonClientFrameView::UpdateToolbar() {
67 views::View* BrowserNonClientFrameView::GetLocationIconView() const {
68 return nullptr;
71 void BrowserNonClientFrameView::VisibilityChanged(views::View* starting_from,
72 bool is_visible) {
73 if (!is_visible)
74 return;
76 // The first time UpdateOldAvatarButton() is called the window is not visible
77 // so DrawTaskBarDecoration() has no effect. Therefore we need to call it
78 // again once the window is visible.
79 if (!browser_view_->IsRegularOrGuestSession() ||
80 !switches::IsNewAvatarMenu()) {
81 UpdateOldAvatarButton();
84 // Make sure the task bar icon is correctly updated call
85 // |OnProfileAvatarChanged()| in this case, but only for non guest profiles.
86 if (!browser_view_->IsGuestSession() || !switches::IsNewAvatarMenu())
87 OnProfileAvatarChanged(base::FilePath());
90 void BrowserNonClientFrameView::ChildPreferredSizeChanged(View* child) {
91 #if defined(FRAME_AVATAR_BUTTON)
92 // Only perform a re-layout if the avatar button has changed, since that
93 // can affect the size of the tabs.
94 if (child == new_avatar_button_) {
95 InvalidateLayout();
96 frame_->GetRootView()->Layout();
98 #endif
101 #if defined(ENABLE_SUPERVISED_USERS)
102 void BrowserNonClientFrameView::OnThemeChanged() {
103 if (supervised_user_avatar_label_)
104 supervised_user_avatar_label_->UpdateLabelStyle();
106 #endif
108 bool BrowserNonClientFrameView::ShouldPaintAsThemed() const {
109 return browser_view_->IsBrowserTypeNormal();
112 SkColor BrowserNonClientFrameView::GetFrameColor() const {
113 const bool incognito = browser_view_->IsOffTheRecord();
114 ThemeProperties::OverwritableByUserThemeProperty color_id;
115 if (ShouldPaintAsActive()) {
116 color_id = incognito ? ThemeProperties::COLOR_FRAME_INCOGNITO
117 : ThemeProperties::COLOR_FRAME;
118 } else {
119 color_id = incognito ? ThemeProperties::COLOR_FRAME_INCOGNITO_INACTIVE
120 : ThemeProperties::COLOR_FRAME_INACTIVE;
122 return ShouldPaintAsThemed() ? GetThemeProvider()->GetColor(color_id)
123 : ThemeProperties::GetDefaultColor(color_id);
126 gfx::ImageSkia* BrowserNonClientFrameView::GetFrameImage() const {
127 const bool incognito = browser_view_->IsOffTheRecord();
128 int resource_id;
129 if (browser_view_->IsBrowserTypeNormal()) {
130 if (ShouldPaintAsActive()) {
131 resource_id = incognito ? IDR_THEME_FRAME_INCOGNITO : IDR_THEME_FRAME;
132 } else {
133 resource_id = incognito ? IDR_THEME_FRAME_INCOGNITO_INACTIVE
134 : IDR_THEME_FRAME_INACTIVE;
136 return GetThemeProvider()->GetImageSkiaNamed(resource_id);
139 if (ShouldPaintAsActive()) {
140 resource_id = incognito ? IDR_THEME_FRAME_INCOGNITO : IDR_FRAME;
141 } else {
142 resource_id = incognito ? IDR_THEME_FRAME_INCOGNITO_INACTIVE
143 : IDR_THEME_FRAME_INACTIVE;
146 if (ShouldPaintAsThemed()) {
147 // On Linux, we want to use theme images provided by the system theme when
148 // enabled, even if we are an app or popup window.
149 return GetThemeProvider()->GetImageSkiaNamed(resource_id);
152 // Otherwise, never theme app and popup windows.
153 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
154 return rb.GetImageSkiaNamed(
155 chrome::MapThemeImage(chrome::GetHostDesktopTypeForNativeWindow(
156 browser_view_->GetNativeWindow()),
157 resource_id));
160 gfx::ImageSkia* BrowserNonClientFrameView::GetFrameOverlayImage() const {
161 ui::ThemeProvider* tp = GetThemeProvider();
162 if (tp->HasCustomImage(IDR_THEME_FRAME_OVERLAY) &&
163 browser_view_->IsBrowserTypeNormal() &&
164 !browser_view_->IsOffTheRecord()) {
165 return tp->GetImageSkiaNamed(ShouldPaintAsActive() ?
166 IDR_THEME_FRAME_OVERLAY : IDR_THEME_FRAME_OVERLAY_INACTIVE);
168 return nullptr;
171 int BrowserNonClientFrameView::GetTopAreaHeight() const {
172 gfx::ImageSkia* frame_image = GetFrameImage();
173 int top_area_height = frame_image->height();
174 if (browser_view_->IsTabStripVisible()) {
175 top_area_height = std::max(top_area_height,
176 GetBoundsForTabStrip(browser_view_->tabstrip()).bottom());
178 return top_area_height;
181 void BrowserNonClientFrameView::UpdateAvatar() {
182 if (browser_view()->IsRegularOrGuestSession() && switches::IsNewAvatarMenu())
183 UpdateNewAvatarButtonImpl();
184 else
185 UpdateOldAvatarButton();
188 void BrowserNonClientFrameView::UpdateOldAvatarButton() {
189 if (browser_view_->ShouldShowAvatar()) {
190 if (!avatar_button_) {
191 #if defined(ENABLE_SUPERVISED_USERS)
192 Profile* profile = browser_view_->browser()->profile();
193 if (profile->IsSupervised() && !supervised_user_avatar_label_) {
194 supervised_user_avatar_label_ =
195 new SupervisedUserAvatarLabel(browser_view_);
196 supervised_user_avatar_label_->set_id(
197 VIEW_ID_SUPERVISED_USER_AVATAR_LABEL);
198 AddChildView(supervised_user_avatar_label_);
200 #endif
201 avatar_button_ = new AvatarMenuButton(
202 browser_view_->browser(), !browser_view_->IsRegularOrGuestSession());
203 avatar_button_->set_id(VIEW_ID_AVATAR_BUTTON);
204 AddChildView(avatar_button_);
205 // Invalidate here because adding a child does not invalidate the layout.
206 InvalidateLayout();
207 frame_->GetRootView()->Layout();
209 } else if (avatar_button_) {
210 #if defined(ENABLE_SUPERVISED_USERS)
211 // The avatar label can just be there if there is also an avatar button.
212 if (supervised_user_avatar_label_) {
213 RemoveChildView(supervised_user_avatar_label_);
214 delete supervised_user_avatar_label_;
215 supervised_user_avatar_label_ = nullptr;
217 #endif
218 RemoveChildView(avatar_button_);
219 delete avatar_button_;
220 avatar_button_ = nullptr;
221 frame_->GetRootView()->Layout();
224 gfx::Image avatar;
225 gfx::Image taskbar_badge_avatar;
226 bool is_rectangle = false;
228 // Update the avatar button in the window frame and the taskbar overlay.
229 bool should_show_avatar_menu =
230 avatar_button_ || AvatarMenu::ShouldShowAvatarMenu();
232 if (!AvatarMenuButton::GetAvatarImages(
233 browser_view_->browser()->profile(), should_show_avatar_menu, &avatar,
234 &taskbar_badge_avatar, &is_rectangle)) {
235 return;
238 // Disable the menu when we should not show the menu.
239 if (avatar_button_ && !AvatarMenu::ShouldShowAvatarMenu())
240 avatar_button_->SetEnabled(false);
241 if (avatar_button_)
242 avatar_button_->SetAvatarIcon(avatar, is_rectangle);
245 #if defined(FRAME_AVATAR_BUTTON)
246 void BrowserNonClientFrameView::UpdateNewAvatarButton(
247 views::ButtonListener* listener,
248 const NewAvatarButton::AvatarButtonStyle style) {
249 DCHECK(switches::IsNewAvatarMenu());
250 // This should never be called in incognito mode.
251 DCHECK(browser_view_->IsRegularOrGuestSession());
253 if (browser_view_->ShouldShowAvatar()) {
254 if (!new_avatar_button_) {
255 new_avatar_button_ =
256 new NewAvatarButton(listener, style, browser_view_->browser());
257 new_avatar_button_->set_id(VIEW_ID_NEW_AVATAR_BUTTON);
258 AddChildView(new_avatar_button_);
259 frame_->GetRootView()->Layout();
261 } else if (new_avatar_button_) {
262 delete new_avatar_button_;
263 new_avatar_button_ = nullptr;
264 frame_->GetRootView()->Layout();
267 #endif
269 void BrowserNonClientFrameView::OnProfileAdded(
270 const base::FilePath& profile_path) {
271 UpdateTaskbarDecoration();
272 UpdateAvatar();
275 void BrowserNonClientFrameView::OnProfileWasRemoved(
276 const base::FilePath& profile_path,
277 const base::string16& profile_name) {
278 UpdateTaskbarDecoration();
279 UpdateAvatar();
282 void BrowserNonClientFrameView::OnProfileAvatarChanged(
283 const base::FilePath& profile_path) {
284 UpdateTaskbarDecoration();
285 // Profile avatars are only displayed in the old UI or incognito.
286 if ((!browser_view()->IsGuestSession() && browser_view()->IsOffTheRecord()) ||
287 !switches::IsNewAvatarMenu()) {
288 UpdateOldAvatarButton();
292 void BrowserNonClientFrameView::UpdateTaskbarDecoration() {
293 gfx::Image avatar;
294 gfx::Image taskbar_badge_avatar;
295 bool is_rectangle;
296 // Only need to update the taskbar overlay here. If GetAvatarImages()
297 // returns false, don't bother trying to update the taskbar decoration since
298 // the returned images are not initialized. This can happen if the user
299 // deletes the current profile.
300 if (AvatarMenuButton::GetAvatarImages(browser_view_->browser()->profile(),
301 AvatarMenu::ShouldShowAvatarMenu(),
302 &avatar, &taskbar_badge_avatar,
303 &is_rectangle)) {
304 // For popups and panels which don't have the avatar button, we still
305 // need to draw the taskbar decoration. Even though we have an icon on the
306 // window's relaunch details, we draw over it because the user may have
307 // pinned the badge-less Chrome shortcut which will cause windows to ignore
308 // the relaunch details.
309 // TODO(calamity): ideally this should not be necessary but due to issues
310 // with the default shortcut being pinned, we add the runtime badge for
311 // safety. See crbug.com/313800.
312 bool show_decoration = AvatarMenu::ShouldShowAvatarMenu() &&
313 !browser_view_->browser()->profile()->IsGuestSession();
314 // In tests, make sure that the browser process and profile manager are
315 // valid before using.
316 if (g_browser_process && g_browser_process->profile_manager()) {
317 const ProfileInfoCache& cache =
318 g_browser_process->profile_manager()->GetProfileInfoCache();
319 show_decoration = show_decoration && cache.GetNumberOfProfiles() > 1;
321 chrome::DrawTaskbarDecoration(frame_->GetNativeWindow(),
322 show_decoration
323 ? (taskbar_badge_avatar.IsEmpty() ? &avatar : &taskbar_badge_avatar)
324 : nullptr);