OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/profiles/profile_info_cache.h" | 5 #include "chrome/browser/profiles/profile_info_cache.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
9 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
10 #include "base/i18n/case_conversion.h" | 10 #include "base/i18n/case_conversion.h" |
(...skipping 26 matching lines...) Expand all Loading... |
37 using content::BrowserThread; | 37 using content::BrowserThread; |
38 | 38 |
39 namespace { | 39 namespace { |
40 | 40 |
41 const char kNameKey[] = "name"; | 41 const char kNameKey[] = "name"; |
42 const char kShortcutNameKey[] = "shortcut_name"; | 42 const char kShortcutNameKey[] = "shortcut_name"; |
43 const char kGAIANameKey[] = "gaia_name"; | 43 const char kGAIANameKey[] = "gaia_name"; |
44 const char kGAIAGivenNameKey[] = "gaia_given_name"; | 44 const char kGAIAGivenNameKey[] = "gaia_given_name"; |
45 const char kUseGAIANameKey[] = "use_gaia_name"; | 45 const char kUseGAIANameKey[] = "use_gaia_name"; |
46 const char kUserNameKey[] = "user_name"; | 46 const char kUserNameKey[] = "user_name"; |
| 47 const char kIsUsingDefaultName[] = "is_using_default_name"; |
47 const char kAvatarIconKey[] = "avatar_icon"; | 48 const char kAvatarIconKey[] = "avatar_icon"; |
48 const char kAuthCredentialsKey[] = "local_auth_credentials"; | 49 const char kAuthCredentialsKey[] = "local_auth_credentials"; |
49 const char kUseGAIAPictureKey[] = "use_gaia_picture"; | 50 const char kUseGAIAPictureKey[] = "use_gaia_picture"; |
50 const char kBackgroundAppsKey[] = "background_apps"; | 51 const char kBackgroundAppsKey[] = "background_apps"; |
51 const char kHasMigratedToGAIAInfoKey[] = "has_migrated_to_gaia_info"; | 52 const char kHasMigratedToGAIAInfoKey[] = "has_migrated_to_gaia_info"; |
52 const char kGAIAPictureFileNameKey[] = "gaia_picture_file_name"; | 53 const char kGAIAPictureFileNameKey[] = "gaia_picture_file_name"; |
53 const char kIsManagedKey[] = "is_managed"; | 54 const char kIsManagedKey[] = "is_managed"; |
54 const char kIsOmittedFromProfileListKey[] = "is_omitted_from_profile_list"; | 55 const char kIsOmittedFromProfileListKey[] = "is_omitted_from_profile_list"; |
55 const char kSigninRequiredKey[] = "signin_required"; | 56 const char kSigninRequiredKey[] = "signin_required"; |
56 const char kManagedUserId[] = "managed_user_id"; | 57 const char kManagedUserId[] = "managed_user_id"; |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 } | 167 } |
167 | 168 |
168 *out_image = new gfx::Image(image); | 169 *out_image = new gfx::Image(image); |
169 } | 170 } |
170 | 171 |
171 void DeleteBitmap(const base::FilePath& image_path) { | 172 void DeleteBitmap(const base::FilePath& image_path) { |
172 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 173 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
173 base::DeleteFile(image_path, false); | 174 base::DeleteFile(image_path, false); |
174 } | 175 } |
175 | 176 |
| 177 bool IsDefaultName(const base::string16& name) { |
| 178 // Check if it's a "First user" old-style name. |
| 179 if (name == l10n_util::GetStringUTF16(IDS_DEFAULT_PROFILE_NAME)) |
| 180 return true; |
| 181 |
| 182 // Check if it's one of the old-style profile names. |
| 183 for (size_t i = 0; i < arraysize(kDefaultNames); ++i) { |
| 184 if (name == l10n_util::GetStringUTF16(kDefaultNames[i])) |
| 185 return true; |
| 186 } |
| 187 |
| 188 // Check whether it's one of the "Person %d" style names. |
| 189 std::string default_name_format = l10n_util::GetStringFUTF8( |
| 190 IDS_NEW_NUMBERED_PROFILE_NAME, base::string16()) + "%d"; |
| 191 |
| 192 int generic_profile_number; // Unused. Just a placeholder for sscanf. |
| 193 int assignments = sscanf(base::UTF16ToUTF8(name).c_str(), |
| 194 default_name_format.c_str(), |
| 195 &generic_profile_number); |
| 196 // Unless it matched the format, this is a custom name. |
| 197 return assignments == 1; |
| 198 } |
| 199 |
176 } // namespace | 200 } // namespace |
177 | 201 |
178 ProfileInfoCache::ProfileInfoCache(PrefService* prefs, | 202 ProfileInfoCache::ProfileInfoCache(PrefService* prefs, |
179 const base::FilePath& user_data_dir) | 203 const base::FilePath& user_data_dir) |
180 : prefs_(prefs), | 204 : prefs_(prefs), |
181 user_data_dir_(user_data_dir) { | 205 user_data_dir_(user_data_dir) { |
182 // Populate the cache | 206 // Populate the cache |
183 DictionaryPrefUpdate update(prefs_, prefs::kProfileInfoCache); | 207 DictionaryPrefUpdate update(prefs_, prefs::kProfileInfoCache); |
184 base::DictionaryValue* cache = update.Get(); | 208 base::DictionaryValue* cache = update.Get(); |
185 for (base::DictionaryValue::Iterator it(*cache); | 209 for (base::DictionaryValue::Iterator it(*cache); |
186 !it.IsAtEnd(); it.Advance()) { | 210 !it.IsAtEnd(); it.Advance()) { |
187 base::DictionaryValue* info = NULL; | 211 base::DictionaryValue* info = NULL; |
188 cache->GetDictionaryWithoutPathExpansion(it.key(), &info); | 212 cache->GetDictionaryWithoutPathExpansion(it.key(), &info); |
189 base::string16 name; | 213 base::string16 name; |
190 info->GetString(kNameKey, &name); | 214 info->GetString(kNameKey, &name); |
191 sorted_keys_.insert(FindPositionForProfile(it.key(), name), it.key()); | 215 sorted_keys_.insert(FindPositionForProfile(it.key(), name), it.key()); |
192 // TODO(ibraaaa): delete this when 97% of our users are using M31. | 216 // TODO(ibraaaa): delete this when 97% of our users are using M31. |
193 // http://crbug.com/276163 | 217 // http://crbug.com/276163 |
194 bool is_managed = false; | 218 bool is_managed = false; |
195 if (info->GetBoolean(kIsManagedKey, &is_managed)) { | 219 if (info->GetBoolean(kIsManagedKey, &is_managed)) { |
196 info->Remove(kIsManagedKey, NULL); | 220 info->Remove(kIsManagedKey, NULL); |
197 info->SetString(kManagedUserId, is_managed ? "DUMMY_ID" : std::string()); | 221 info->SetString(kManagedUserId, is_managed ? "DUMMY_ID" : std::string()); |
198 } | 222 } |
| 223 info->SetBoolean(kIsUsingDefaultName, IsDefaultName(name)); |
199 } | 224 } |
200 } | 225 } |
201 | 226 |
202 ProfileInfoCache::~ProfileInfoCache() { | 227 ProfileInfoCache::~ProfileInfoCache() { |
203 STLDeleteContainerPairSecondPointers( | 228 STLDeleteContainerPairSecondPointers( |
204 gaia_pictures_.begin(), gaia_pictures_.end()); | 229 gaia_pictures_.begin(), gaia_pictures_.end()); |
205 } | 230 } |
206 | 231 |
207 void ProfileInfoCache::AddProfileToCache(const base::FilePath& profile_path, | 232 void ProfileInfoCache::AddProfileToCache(const base::FilePath& profile_path, |
208 const base::string16& name, | 233 const base::string16& name, |
209 const base::string16& username, | 234 const base::string16& username, |
210 size_t icon_index, | 235 size_t icon_index, |
211 const std::string& managed_user_id) { | 236 const std::string& managed_user_id) { |
212 std::string key = CacheKeyFromProfilePath(profile_path); | 237 std::string key = CacheKeyFromProfilePath(profile_path); |
213 DictionaryPrefUpdate update(prefs_, prefs::kProfileInfoCache); | 238 DictionaryPrefUpdate update(prefs_, prefs::kProfileInfoCache); |
214 base::DictionaryValue* cache = update.Get(); | 239 base::DictionaryValue* cache = update.Get(); |
215 | 240 |
216 scoped_ptr<base::DictionaryValue> info(new base::DictionaryValue); | 241 scoped_ptr<base::DictionaryValue> info(new base::DictionaryValue); |
217 info->SetString(kNameKey, name); | 242 info->SetString(kNameKey, name); |
218 info->SetString(kUserNameKey, username); | 243 info->SetString(kUserNameKey, username); |
219 info->SetString(kAvatarIconKey, GetDefaultAvatarIconUrl(icon_index)); | 244 info->SetString(kAvatarIconKey, GetDefaultAvatarIconUrl(icon_index)); |
220 // Default value for whether background apps are running is false. | 245 // Default value for whether background apps are running is false. |
221 info->SetBoolean(kBackgroundAppsKey, false); | 246 info->SetBoolean(kBackgroundAppsKey, false); |
222 info->SetString(kManagedUserId, managed_user_id); | 247 info->SetString(kManagedUserId, managed_user_id); |
223 info->SetBoolean(kIsOmittedFromProfileListKey, !managed_user_id.empty()); | 248 info->SetBoolean(kIsOmittedFromProfileListKey, !managed_user_id.empty()); |
224 info->SetBoolean(kProfileIsEphemeral, false); | 249 info->SetBoolean(kProfileIsEphemeral, false); |
| 250 info->SetBoolean(kIsUsingDefaultName, IsDefaultName(name)); |
225 cache->SetWithoutPathExpansion(key, info.release()); | 251 cache->SetWithoutPathExpansion(key, info.release()); |
226 | 252 |
227 sorted_keys_.insert(FindPositionForProfile(key, name), key); | 253 sorted_keys_.insert(FindPositionForProfile(key, name), key); |
228 | 254 |
229 FOR_EACH_OBSERVER(ProfileInfoCacheObserver, | 255 FOR_EACH_OBSERVER(ProfileInfoCacheObserver, |
230 observer_list_, | 256 observer_list_, |
231 OnProfileAdded(profile_path)); | 257 OnProfileAdded(profile_path)); |
232 | 258 |
233 content::NotificationService::current()->Notify( | 259 content::NotificationService::current()->Notify( |
234 chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, | 260 chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 std::string search_key = CacheKeyFromProfilePath(profile_path); | 310 std::string search_key = CacheKeyFromProfilePath(profile_path); |
285 for (size_t i = 0; i < sorted_keys_.size(); ++i) { | 311 for (size_t i = 0; i < sorted_keys_.size(); ++i) { |
286 if (sorted_keys_[i] == search_key) | 312 if (sorted_keys_[i] == search_key) |
287 return i; | 313 return i; |
288 } | 314 } |
289 return std::string::npos; | 315 return std::string::npos; |
290 } | 316 } |
291 | 317 |
292 base::string16 ProfileInfoCache::GetNameOfProfileAtIndex(size_t index) const { | 318 base::string16 ProfileInfoCache::GetNameOfProfileAtIndex(size_t index) const { |
293 base::string16 name; | 319 base::string16 name; |
294 if (IsUsingGAIANameOfProfileAtIndex(index)) { | 320 // Unless the user has customized the profile name, we should use the |
| 321 // profile's Gaia given name, if it's available. |
| 322 if (IsUsingGAIANameOfProfileAtIndex(index) && |
| 323 ProfileIsUsingDefaultNameAtIndex(index)) { |
295 base::string16 given_name = GetGAIAGivenNameOfProfileAtIndex(index); | 324 base::string16 given_name = GetGAIAGivenNameOfProfileAtIndex(index); |
296 name = given_name.empty() ? GetGAIANameOfProfileAtIndex(index) : given_name; | 325 name = given_name.empty() ? GetGAIANameOfProfileAtIndex(index) : given_name; |
297 } | 326 } |
298 | |
299 if (name.empty()) | 327 if (name.empty()) |
300 GetInfoForProfileAtIndex(index)->GetString(kNameKey, &name); | 328 GetInfoForProfileAtIndex(index)->GetString(kNameKey, &name); |
301 return name; | 329 return name; |
302 } | 330 } |
303 | 331 |
304 base::string16 ProfileInfoCache::GetShortcutNameOfProfileAtIndex(size_t index) | 332 base::string16 ProfileInfoCache::GetShortcutNameOfProfileAtIndex(size_t index) |
305 const { | 333 const { |
306 base::string16 shortcut_name; | 334 base::string16 shortcut_name; |
307 GetInfoForProfileAtIndex(index)->GetString( | 335 GetInfoForProfileAtIndex(index)->GetString( |
308 kShortcutNameKey, &shortcut_name); | 336 kShortcutNameKey, &shortcut_name); |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 GetInfoForProfileAtIndex(index)->GetString(kManagedUserId, &managed_user_id); | 462 GetInfoForProfileAtIndex(index)->GetString(kManagedUserId, &managed_user_id); |
435 return managed_user_id; | 463 return managed_user_id; |
436 } | 464 } |
437 | 465 |
438 bool ProfileInfoCache::ProfileIsEphemeralAtIndex(size_t index) const { | 466 bool ProfileInfoCache::ProfileIsEphemeralAtIndex(size_t index) const { |
439 bool value = false; | 467 bool value = false; |
440 GetInfoForProfileAtIndex(index)->GetBoolean(kProfileIsEphemeral, &value); | 468 GetInfoForProfileAtIndex(index)->GetBoolean(kProfileIsEphemeral, &value); |
441 return value; | 469 return value; |
442 } | 470 } |
443 | 471 |
| 472 bool ProfileInfoCache::ProfileIsUsingDefaultNameAtIndex(size_t index) const { |
| 473 bool value = false; |
| 474 GetInfoForProfileAtIndex(index)->GetBoolean(kIsUsingDefaultName, &value); |
| 475 return value; |
| 476 } |
| 477 |
444 void ProfileInfoCache::OnGAIAPictureLoaded(const base::FilePath& path, | 478 void ProfileInfoCache::OnGAIAPictureLoaded(const base::FilePath& path, |
445 gfx::Image** image) const { | 479 gfx::Image** image) const { |
446 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 480 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
447 | 481 |
448 std::string key = CacheKeyFromProfilePath(path); | 482 std::string key = CacheKeyFromProfilePath(path); |
449 gaia_pictures_loading_[key] = false; | 483 gaia_pictures_loading_[key] = false; |
450 | 484 |
451 if (*image) { | 485 if (*image) { |
452 delete gaia_pictures_[key]; | 486 delete gaia_pictures_[key]; |
453 gaia_pictures_[key] = *image; | 487 gaia_pictures_[key] = *image; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
506 const base::string16& name) { | 540 const base::string16& name) { |
507 scoped_ptr<base::DictionaryValue> info( | 541 scoped_ptr<base::DictionaryValue> info( |
508 GetInfoForProfileAtIndex(index)->DeepCopy()); | 542 GetInfoForProfileAtIndex(index)->DeepCopy()); |
509 base::string16 current_name; | 543 base::string16 current_name; |
510 info->GetString(kNameKey, ¤t_name); | 544 info->GetString(kNameKey, ¤t_name); |
511 if (name == current_name) | 545 if (name == current_name) |
512 return; | 546 return; |
513 | 547 |
514 base::string16 old_display_name = GetNameOfProfileAtIndex(index); | 548 base::string16 old_display_name = GetNameOfProfileAtIndex(index); |
515 info->SetString(kNameKey, name); | 549 info->SetString(kNameKey, name); |
| 550 info->SetBoolean(kIsUsingDefaultName, false); |
| 551 |
516 // This takes ownership of |info|. | 552 // This takes ownership of |info|. |
517 SetInfoForProfileAtIndex(index, info.release()); | 553 SetInfoForProfileAtIndex(index, info.release()); |
518 base::string16 new_display_name = GetNameOfProfileAtIndex(index); | 554 base::string16 new_display_name = GetNameOfProfileAtIndex(index); |
519 base::FilePath profile_path = GetPathOfProfileAtIndex(index); | 555 base::FilePath profile_path = GetPathOfProfileAtIndex(index); |
520 UpdateSortForProfileIndex(index); | 556 UpdateSortForProfileIndex(index); |
521 | 557 |
522 if (old_display_name != new_display_name) { | 558 if (old_display_name != new_display_name) { |
523 FOR_EACH_OBSERVER(ProfileInfoCacheObserver, | 559 FOR_EACH_OBSERVER(ProfileInfoCacheObserver, |
524 observer_list_, | 560 observer_list_, |
525 OnProfileNameChanged(profile_path, old_display_name)); | 561 OnProfileNameChanged(profile_path, old_display_name)); |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
755 if (value == ProfileIsEphemeralAtIndex(index)) | 791 if (value == ProfileIsEphemeralAtIndex(index)) |
756 return; | 792 return; |
757 | 793 |
758 scoped_ptr<base::DictionaryValue> info( | 794 scoped_ptr<base::DictionaryValue> info( |
759 GetInfoForProfileAtIndex(index)->DeepCopy()); | 795 GetInfoForProfileAtIndex(index)->DeepCopy()); |
760 info->SetBoolean(kProfileIsEphemeral, value); | 796 info->SetBoolean(kProfileIsEphemeral, value); |
761 // This takes ownership of |info|. | 797 // This takes ownership of |info|. |
762 SetInfoForProfileAtIndex(index, info.release()); | 798 SetInfoForProfileAtIndex(index, info.release()); |
763 } | 799 } |
764 | 800 |
| 801 void ProfileInfoCache::SetProfileIsUsingDefaultNameAtIndex( |
| 802 size_t index, bool value) { |
| 803 if (value == ProfileIsUsingDefaultNameAtIndex(index)) |
| 804 return; |
| 805 |
| 806 scoped_ptr<base::DictionaryValue> info( |
| 807 GetInfoForProfileAtIndex(index)->DeepCopy()); |
| 808 info->SetBoolean(kIsUsingDefaultName, value); |
| 809 // This takes ownership of |info|. |
| 810 SetInfoForProfileAtIndex(index, info.release()); |
| 811 } |
| 812 |
765 base::string16 ProfileInfoCache::ChooseNameForNewProfile( | 813 base::string16 ProfileInfoCache::ChooseNameForNewProfile( |
766 size_t icon_index) const { | 814 size_t icon_index) const { |
767 base::string16 name; | 815 base::string16 name; |
768 for (int name_index = 1; ; ++name_index) { | 816 for (int name_index = 1; ; ++name_index) { |
769 if (switches::IsNewProfileManagement()) { | 817 if (switches::IsNewProfileManagement()) { |
770 name = l10n_util::GetStringFUTF16Int(IDS_NEW_NUMBERED_PROFILE_NAME, | 818 name = l10n_util::GetStringFUTF16Int(IDS_NEW_NUMBERED_PROFILE_NAME, |
771 name_index); | 819 name_index); |
772 } else if (icon_index < kGenericIconCount) { | 820 } else if (icon_index < kGenericIconCount) { |
773 name = l10n_util::GetStringFUTF16Int(IDS_NUMBERED_PROFILE_NAME, | 821 name = l10n_util::GetStringFUTF16Int(IDS_NUMBERED_PROFILE_NAME, |
774 name_index); | 822 name_index); |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
989 info->GetString(kNameKey, &name); | 1037 info->GetString(kNameKey, &name); |
990 names.push_back(name); | 1038 names.push_back(name); |
991 } | 1039 } |
992 return names; | 1040 return names; |
993 } | 1041 } |
994 | 1042 |
995 // static | 1043 // static |
996 void ProfileInfoCache::RegisterPrefs(PrefRegistrySimple* registry) { | 1044 void ProfileInfoCache::RegisterPrefs(PrefRegistrySimple* registry) { |
997 registry->RegisterDictionaryPref(prefs::kProfileInfoCache); | 1045 registry->RegisterDictionaryPref(prefs::kProfileInfoCache); |
998 } | 1046 } |
OLD | NEW |