Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / profiles / avatar_menu.cc
blob510d208ac0ede3ed1ee09f4e6a3276ae07c546bb
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/profiles/avatar_menu.h"
7 #include "ash/ash_switches.h"
8 #include "base/bind.h"
9 #include "base/i18n/case_conversion.h"
10 #include "base/metrics/field_trial.h"
11 #include "base/profiler/scoped_tracker.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/chrome_notification_types.h"
15 #include "chrome/browser/profiles/avatar_menu_actions.h"
16 #include "chrome/browser/profiles/avatar_menu_observer.h"
17 #include "chrome/browser/profiles/profile_list.h"
18 #include "chrome/browser/profiles/profile_manager.h"
19 #include "chrome/browser/profiles/profile_metrics.h"
20 #include "chrome/browser/profiles/profile_window.h"
21 #include "chrome/browser/profiles/profiles_state.h"
22 #include "chrome/browser/ui/ash/chrome_shell_delegate.h"
23 #include "chrome/browser/ui/browser.h"
24 #include "chrome/browser/ui/browser_dialogs.h"
25 #include "chrome/browser/ui/host_desktop.h"
26 #include "chrome/browser/ui/startup/startup_browser_creator.h"
27 #include "chrome/browser/ui/user_manager.h"
28 #include "chrome/common/chrome_switches.h"
29 #include "chrome/grit/generated_resources.h"
30 #include "components/signin/core/common/profile_management_switches.h"
31 #include "content/public/browser/browser_thread.h"
32 #include "content/public/browser/notification_service.h"
33 #include "grit/theme_resources.h"
34 #include "ui/base/l10n/l10n_util.h"
35 #include "ui/base/resource/resource_bundle.h"
37 #if defined(ENABLE_SUPERVISED_USERS)
38 #include "chrome/browser/supervised_user/supervised_user_service.h"
39 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
40 #endif
42 using content::BrowserThread;
44 namespace {
46 // Constants for the show profile switcher experiment
47 const char kShowProfileSwitcherFieldTrialName[] = "ShowProfileSwitcher";
48 const char kAlwaysShowSwitcherGroupName[] = "AlwaysShow";
50 } // namespace
52 AvatarMenu::AvatarMenu(ProfileInfoInterface* profile_cache,
53 AvatarMenuObserver* observer,
54 Browser* browser)
55 : profile_list_(ProfileList::Create(profile_cache)),
56 menu_actions_(AvatarMenuActions::Create()),
57 #if defined(ENABLE_SUPERVISED_USERS)
58 supervised_user_observer_(this),
59 #endif
60 profile_info_(profile_cache),
61 observer_(observer),
62 browser_(browser) {
63 DCHECK(profile_info_);
64 // Don't DCHECK(browser_) so that unit tests can reuse this ctor.
66 ActiveBrowserChanged(browser_);
68 // Register this as an observer of the info cache.
69 g_browser_process->profile_manager()->GetProfileInfoCache().AddObserver(this);
71 #if defined(ENABLE_SUPERVISED_USERS)
72 // Register this as an observer of the SupervisedUserService to be notified
73 // of changes to the custodian info.
74 if (browser_) {
75 supervised_user_observer_.Add(
76 SupervisedUserServiceFactory::GetForProfile(browser_->profile()));
78 #endif
81 AvatarMenu::~AvatarMenu() {
82 g_browser_process->profile_manager()->
83 GetProfileInfoCache().RemoveObserver(this);
86 AvatarMenu::Item::Item(size_t menu_index,
87 size_t profile_index,
88 const gfx::Image& icon)
89 : icon(icon),
90 active(false),
91 signed_in(false),
92 signin_required(false),
93 menu_index(menu_index),
94 profile_index(profile_index) {
97 AvatarMenu::Item::~Item() {
100 // static
101 bool AvatarMenu::ShouldShowAvatarMenu() {
102 if (base::FieldTrialList::FindFullName(kShowProfileSwitcherFieldTrialName) ==
103 kAlwaysShowSwitcherGroupName) {
104 // We should only be in this group when multi-profiles is enabled.
105 DCHECK(profiles::IsMultipleProfilesEnabled());
106 return true;
109 // TODO: Eliminate this ifdef. Add a delegate interface for the menu which
110 // would also help remove the Browser dependency in AvatarMenuActions
111 // implementations.
112 if (profiles::IsMultipleProfilesEnabled()) {
113 #if defined(OS_CHROMEOS)
114 // On ChromeOS the menu will not be shown.
115 return false;
116 #else
117 return switches::IsNewAvatarMenu() ||
118 (g_browser_process->profile_manager() &&
119 g_browser_process->profile_manager()->GetNumberOfProfiles() > 1);
120 #endif
122 return false;
125 bool AvatarMenu::CompareItems(const Item* item1, const Item* item2) {
126 return base::i18n::ToLower(item1->name).compare(
127 base::i18n::ToLower(item2->name)) < 0;
130 void AvatarMenu::SwitchToProfile(size_t index,
131 bool always_create,
132 ProfileMetrics::ProfileOpen metric) {
133 DCHECK(profiles::IsMultipleProfilesEnabled() ||
134 index == GetActiveProfileIndex());
135 const Item& item = GetItemAt(index);
137 if (switches::IsNewAvatarMenu()) {
138 // Don't open a browser window for signed-out profiles.
139 if (item.signin_required) {
140 UserManager::Show(item.profile_path,
141 profiles::USER_MANAGER_NO_TUTORIAL,
142 profiles::USER_MANAGER_SELECT_PROFILE_NO_ACTION);
143 return;
147 base::FilePath path =
148 profile_info_->GetPathOfProfileAtIndex(item.profile_index);
150 chrome::HostDesktopType desktop_type = chrome::GetActiveDesktop();
151 if (browser_)
152 desktop_type = browser_->host_desktop_type();
154 profiles::SwitchToProfile(path, desktop_type, always_create,
155 ProfileManager::CreateCallback(),
156 metric);
159 void AvatarMenu::AddNewProfile(ProfileMetrics::ProfileAdd type) {
160 menu_actions_->AddNewProfile(type);
163 void AvatarMenu::EditProfile(size_t index) {
164 // Get the index in the profile cache from the menu index.
165 size_t profile_index = profile_list_->GetItemAt(index).profile_index;
167 Profile* profile = g_browser_process->profile_manager()->GetProfileByPath(
168 profile_info_->GetPathOfProfileAtIndex(profile_index));
170 menu_actions_->EditProfile(profile, profile_index);
173 void AvatarMenu::RebuildMenu() {
174 profile_list_->RebuildMenu();
177 size_t AvatarMenu::GetNumberOfItems() const {
178 return profile_list_->GetNumberOfItems();
181 const AvatarMenu::Item& AvatarMenu::GetItemAt(size_t index) const {
182 return profile_list_->GetItemAt(index);
184 size_t AvatarMenu::GetActiveProfileIndex() {
186 // During singleton profile deletion, this function can be called with no
187 // profiles in the model - crbug.com/102278 .
188 if (profile_list_->GetNumberOfItems() == 0)
189 return 0;
191 Profile* active_profile = NULL;
192 if (!browser_)
193 active_profile = ProfileManager::GetLastUsedProfile();
194 else
195 active_profile = browser_->profile();
197 size_t index =
198 profile_info_->GetIndexOfProfileWithPath(active_profile->GetPath());
200 index = profile_list_->MenuIndexFromProfileIndex(index);
201 DCHECK_LT(index, profile_list_->GetNumberOfItems());
202 return index;
205 base::string16 AvatarMenu::GetSupervisedUserInformation() const {
206 // |browser_| can be NULL in unit_tests.
207 if (browser_ && browser_->profile()->IsSupervised()) {
208 #if defined(ENABLE_SUPERVISED_USERS)
209 SupervisedUserService* service =
210 SupervisedUserServiceFactory::GetForProfile(browser_->profile());
211 base::string16 custodian =
212 base::UTF8ToUTF16(service->GetCustodianEmailAddress());
213 if (browser_->profile()->IsLegacySupervised())
214 return l10n_util::GetStringFUTF16(IDS_SUPERVISED_USER_INFO, custodian);
215 base::string16 second_custodian =
216 base::UTF8ToUTF16(service->GetSecondCustodianEmailAddress());
217 if (second_custodian.empty()) {
218 return l10n_util::GetStringFUTF16(IDS_CHILD_INFO_ONE_CUSTODIAN,
219 custodian);
220 } else {
221 return l10n_util::GetStringFUTF16(IDS_CHILD_INFO_TWO_CUSTODIANS,
222 custodian, second_custodian);
224 #endif
226 return base::string16();
229 const gfx::Image& AvatarMenu::GetSupervisedUserIcon() const {
230 if (browser_ && browser_->profile()->IsChild()) {
231 return ResourceBundle::GetSharedInstance().GetNativeImageNamed(
232 IDR_CHILD_USER_ICON);
234 return ResourceBundle::GetSharedInstance().GetNativeImageNamed(
235 IDR_LEGACY_SUPERVISED_USER_ICON);
238 void AvatarMenu::ActiveBrowserChanged(Browser* browser) {
239 browser_ = browser;
240 menu_actions_->ActiveBrowserChanged(browser);
242 // If browser is not NULL, get the path of its active profile.
243 base::FilePath path;
244 if (browser)
245 path = browser->profile()->GetPath();
246 profile_list_->ActiveProfilePathChanged(path);
249 bool AvatarMenu::ShouldShowAddNewProfileLink() const {
250 return menu_actions_->ShouldShowAddNewProfileLink();
253 bool AvatarMenu::ShouldShowEditProfileLink() const {
254 return menu_actions_->ShouldShowEditProfileLink();
257 void AvatarMenu::OnProfileAdded(const base::FilePath& profile_path) {
258 Update();
261 void AvatarMenu::OnProfileWasRemoved(const base::FilePath& profile_path,
262 const base::string16& profile_name) {
263 Update();
266 void AvatarMenu::OnProfileNameChanged(const base::FilePath& profile_path,
267 const base::string16& old_profile_name) {
268 Update();
271 void AvatarMenu::OnProfileUserNameChanged(const base::FilePath& profile_path) {
272 Update();
275 void AvatarMenu::OnProfileAvatarChanged(const base::FilePath& profile_path) {
276 Update();
279 void AvatarMenu::OnProfileHighResAvatarLoaded(
280 const base::FilePath& profile_path) {
281 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/461175
282 // is fixed.
283 tracked_objects::ScopedTracker tracking_profile(
284 FROM_HERE_WITH_EXPLICIT_FUNCTION(
285 "461175 AvatarMenu::OnProfileHighResAvatarLoaded"));
286 Update();
289 void AvatarMenu::OnProfileSigninRequiredChanged(
290 const base::FilePath& profile_path) {
291 Update();
294 #if defined(ENABLE_SUPERVISED_USERS)
295 void AvatarMenu::OnCustodianInfoChanged() {
296 RebuildMenu();
297 if (observer_)
298 observer_->OnAvatarMenuChanged(this);
300 #endif
302 void AvatarMenu::Update() {
303 RebuildMenu();
304 if (observer_)
305 observer_->OnAvatarMenuChanged(this);