Don't show supervised user as "already on this device" while they're being imported.
[chromium-blink-merge.git] / chrome / browser / ui / views / frame / browser_non_client_frame_view.cc
blobba42d91f72f012c7102190799b6d4e82fa791f75
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"
31 #if defined(ENABLE_SUPERVISED_USERS)
32 #include "chrome/browser/ui/views/profiles/supervised_user_avatar_label.h"
33 #endif
35 BrowserNonClientFrameView::BrowserNonClientFrameView(BrowserFrame* frame,
36 BrowserView* browser_view)
37 : frame_(frame),
38 browser_view_(browser_view),
39 avatar_button_(nullptr),
40 #if defined(ENABLE_SUPERVISED_USERS)
41 supervised_user_avatar_label_(nullptr),
42 #endif
43 new_avatar_button_(nullptr) {
44 // The profile manager may by null in tests.
45 if (g_browser_process->profile_manager()) {
46 ProfileInfoCache& cache =
47 g_browser_process->profile_manager()->GetProfileInfoCache();
48 cache.AddObserver(this);
52 BrowserNonClientFrameView::~BrowserNonClientFrameView() {
53 // The profile manager may by null in tests.
54 if (g_browser_process->profile_manager()) {
55 ProfileInfoCache& cache =
56 g_browser_process->profile_manager()->GetProfileInfoCache();
57 cache.RemoveObserver(this);
61 void BrowserNonClientFrameView::UpdateToolbar() {
64 views::View* BrowserNonClientFrameView::GetLocationIconView() const {
65 return nullptr;
68 void BrowserNonClientFrameView::VisibilityChanged(views::View* starting_from,
69 bool is_visible) {
70 if (!is_visible)
71 return;
73 // The first time UpdateOldAvatarButton() is called the window is not visible
74 // so DrawTaskBarDecoration() has no effect. Therefore we need to call it
75 // again once the window is visible.
76 if (!browser_view_->IsRegularOrGuestSession() ||
77 !switches::IsNewAvatarMenu()) {
78 UpdateOldAvatarButton();
81 // Make sure the task bar icon is correctly updated call
82 // |OnProfileAvatarChanged()| in this case, but only for non guest profiles.
83 if (!browser_view_->IsGuestSession() || !switches::IsNewAvatarMenu())
84 OnProfileAvatarChanged(base::FilePath());
87 void BrowserNonClientFrameView::ChildPreferredSizeChanged(View* child) {
88 // Only perform a re-layout if the avatar button has changed, since that
89 // can affect the size of the tabs.
90 if (child == new_avatar_button_) {
91 InvalidateLayout();
92 frame_->GetRootView()->Layout();
96 #if defined(ENABLE_SUPERVISED_USERS)
97 void BrowserNonClientFrameView::OnThemeChanged() {
98 if (supervised_user_avatar_label_)
99 supervised_user_avatar_label_->UpdateLabelStyle();
101 #endif
103 bool BrowserNonClientFrameView::ShouldPaintAsThemed() const {
104 return browser_view_->IsBrowserTypeNormal();
107 SkColor BrowserNonClientFrameView::GetFrameColor() const {
108 const bool incognito = browser_view_->IsOffTheRecord();
109 ThemeProperties::OverwritableByUserThemeProperty color_id;
110 if (ShouldPaintAsActive()) {
111 color_id = incognito ? ThemeProperties::COLOR_FRAME_INCOGNITO
112 : ThemeProperties::COLOR_FRAME;
113 } else {
114 color_id = incognito ? ThemeProperties::COLOR_FRAME_INCOGNITO_INACTIVE
115 : ThemeProperties::COLOR_FRAME_INACTIVE;
117 return ShouldPaintAsThemed() ? GetThemeProvider()->GetColor(color_id)
118 : ThemeProperties::GetDefaultColor(color_id);
121 gfx::ImageSkia* BrowserNonClientFrameView::GetFrameImage() const {
122 const bool incognito = browser_view_->IsOffTheRecord();
123 int resource_id;
124 if (browser_view_->IsBrowserTypeNormal()) {
125 if (ShouldPaintAsActive()) {
126 resource_id = incognito ? IDR_THEME_FRAME_INCOGNITO : IDR_THEME_FRAME;
127 } else {
128 resource_id = incognito ? IDR_THEME_FRAME_INCOGNITO_INACTIVE
129 : IDR_THEME_FRAME_INACTIVE;
131 return GetThemeProvider()->GetImageSkiaNamed(resource_id);
134 if (ShouldPaintAsActive()) {
135 resource_id = incognito ? IDR_THEME_FRAME_INCOGNITO : IDR_FRAME;
136 } else {
137 resource_id = incognito ? IDR_THEME_FRAME_INCOGNITO_INACTIVE
138 : IDR_THEME_FRAME_INACTIVE;
141 if (ShouldPaintAsThemed()) {
142 // On Linux, we want to use theme images provided by the system theme when
143 // enabled, even if we are an app or popup window.
144 return GetThemeProvider()->GetImageSkiaNamed(resource_id);
147 // Otherwise, never theme app and popup windows.
148 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
149 return rb.GetImageSkiaNamed(
150 chrome::MapThemeImage(chrome::GetHostDesktopTypeForNativeWindow(
151 browser_view_->GetNativeWindow()),
152 resource_id));
155 gfx::ImageSkia* BrowserNonClientFrameView::GetFrameOverlayImage() const {
156 ui::ThemeProvider* tp = GetThemeProvider();
157 if (tp->HasCustomImage(IDR_THEME_FRAME_OVERLAY) &&
158 browser_view_->IsBrowserTypeNormal() &&
159 !browser_view_->IsOffTheRecord()) {
160 return tp->GetImageSkiaNamed(ShouldPaintAsActive() ?
161 IDR_THEME_FRAME_OVERLAY : IDR_THEME_FRAME_OVERLAY_INACTIVE);
163 return nullptr;
166 int BrowserNonClientFrameView::GetTopAreaHeight() const {
167 gfx::ImageSkia* frame_image = GetFrameImage();
168 int top_area_height = frame_image->height();
169 if (browser_view_->IsTabStripVisible()) {
170 top_area_height = std::max(top_area_height,
171 GetBoundsForTabStrip(browser_view_->tabstrip()).bottom());
173 return top_area_height;
176 void BrowserNonClientFrameView::UpdateAvatar() {
177 if (browser_view()->IsRegularOrGuestSession() && switches::IsNewAvatarMenu())
178 UpdateNewAvatarButtonImpl();
179 else
180 UpdateOldAvatarButton();
183 void BrowserNonClientFrameView::UpdateOldAvatarButton() {
184 if (browser_view_->ShouldShowAvatar()) {
185 if (!avatar_button_) {
186 #if defined(ENABLE_SUPERVISED_USERS)
187 Profile* profile = browser_view_->browser()->profile();
188 if (profile->IsSupervised() && !supervised_user_avatar_label_) {
189 supervised_user_avatar_label_ =
190 new SupervisedUserAvatarLabel(browser_view_);
191 supervised_user_avatar_label_->set_id(
192 VIEW_ID_SUPERVISED_USER_AVATAR_LABEL);
193 AddChildView(supervised_user_avatar_label_);
195 #endif
196 avatar_button_ = new AvatarMenuButton(
197 browser_view_->browser(), !browser_view_->IsRegularOrGuestSession());
198 avatar_button_->set_id(VIEW_ID_AVATAR_BUTTON);
199 AddChildView(avatar_button_);
200 // Invalidate here because adding a child does not invalidate the layout.
201 InvalidateLayout();
202 frame_->GetRootView()->Layout();
204 } else if (avatar_button_) {
205 #if defined(ENABLE_SUPERVISED_USERS)
206 // The avatar label can just be there if there is also an avatar button.
207 if (supervised_user_avatar_label_) {
208 RemoveChildView(supervised_user_avatar_label_);
209 delete supervised_user_avatar_label_;
210 supervised_user_avatar_label_ = nullptr;
212 #endif
213 RemoveChildView(avatar_button_);
214 delete avatar_button_;
215 avatar_button_ = nullptr;
216 frame_->GetRootView()->Layout();
219 gfx::Image avatar;
220 gfx::Image taskbar_badge_avatar;
221 bool is_rectangle = false;
223 // Update the avatar button in the window frame and the taskbar overlay.
224 bool should_show_avatar_menu =
225 avatar_button_ || AvatarMenu::ShouldShowAvatarMenu();
227 if (!AvatarMenuButton::GetAvatarImages(
228 browser_view_->browser()->profile(), should_show_avatar_menu, &avatar,
229 &taskbar_badge_avatar, &is_rectangle)) {
230 return;
233 // Disable the menu when we should not show the menu.
234 if (avatar_button_ && !AvatarMenu::ShouldShowAvatarMenu())
235 avatar_button_->SetEnabled(false);
236 if (avatar_button_)
237 avatar_button_->SetAvatarIcon(avatar, is_rectangle);
240 void BrowserNonClientFrameView::UpdateNewAvatarButton(
241 views::ButtonListener* listener,
242 const NewAvatarButton::AvatarButtonStyle style) {
243 DCHECK(switches::IsNewAvatarMenu());
244 // This should never be called in incognito mode.
245 DCHECK(browser_view_->IsRegularOrGuestSession());
247 if (browser_view_->ShouldShowAvatar()) {
248 if (!new_avatar_button_) {
249 new_avatar_button_ =
250 new NewAvatarButton(listener, style, browser_view_->browser());
251 new_avatar_button_->set_id(VIEW_ID_NEW_AVATAR_BUTTON);
252 AddChildView(new_avatar_button_);
253 frame_->GetRootView()->Layout();
255 } else if (new_avatar_button_) {
256 delete new_avatar_button_;
257 new_avatar_button_ = nullptr;
258 frame_->GetRootView()->Layout();
262 void BrowserNonClientFrameView::OnProfileAdded(
263 const base::FilePath& profile_path) {
264 UpdateTaskbarDecoration();
265 UpdateAvatar();
268 void BrowserNonClientFrameView::OnProfileWasRemoved(
269 const base::FilePath& profile_path,
270 const base::string16& profile_name) {
271 UpdateTaskbarDecoration();
272 UpdateAvatar();
275 void BrowserNonClientFrameView::OnProfileAvatarChanged(
276 const base::FilePath& profile_path) {
277 UpdateTaskbarDecoration();
278 // Profile avatars are only displayed in the old UI or incognito.
279 if ((!browser_view()->IsGuestSession() && browser_view()->IsOffTheRecord()) ||
280 !switches::IsNewAvatarMenu()) {
281 UpdateOldAvatarButton();
285 void BrowserNonClientFrameView::UpdateTaskbarDecoration() {
286 gfx::Image avatar;
287 gfx::Image taskbar_badge_avatar;
288 bool is_rectangle;
289 // Only need to update the taskbar overlay here. If GetAvatarImages()
290 // returns false, don't bother trying to update the taskbar decoration since
291 // the returned images are not initialized. This can happen if the user
292 // deletes the current profile.
293 if (AvatarMenuButton::GetAvatarImages(browser_view_->browser()->profile(),
294 AvatarMenu::ShouldShowAvatarMenu(),
295 &avatar, &taskbar_badge_avatar,
296 &is_rectangle)) {
297 // For popups and panels which don't have the avatar button, we still
298 // need to draw the taskbar decoration. Even though we have an icon on the
299 // window's relaunch details, we draw over it because the user may have
300 // pinned the badge-less Chrome shortcut which will cause windows to ignore
301 // the relaunch details.
302 // TODO(calamity): ideally this should not be necessary but due to issues
303 // with the default shortcut being pinned, we add the runtime badge for
304 // safety. See crbug.com/313800.
305 bool show_decoration = AvatarMenu::ShouldShowAvatarMenu() &&
306 !browser_view_->browser()->profile()->IsGuestSession();
307 // In tests, make sure that the browser process and profile manager are
308 // valid before using.
309 if (g_browser_process && g_browser_process->profile_manager()) {
310 const ProfileInfoCache& cache =
311 g_browser_process->profile_manager()->GetProfileInfoCache();
312 show_decoration = show_decoration && cache.GetNumberOfProfiles() > 1;
314 chrome::DrawTaskbarDecoration(frame_->GetNativeWindow(),
315 show_decoration
316 ? (taskbar_badge_avatar.IsEmpty() ? &avatar : &taskbar_badge_avatar)
317 : nullptr);