Chromium Code Reviews| 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/files/file_util.h" | 8 #include "base/files/file_util.h" |
| 9 #include "base/i18n/case_conversion.h" | 9 #include "base/i18n/case_conversion.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 128 gfx::Image image = gfx::Image::CreateFrom1xPNGBytes( | 128 gfx::Image image = gfx::Image::CreateFrom1xPNGBytes( |
| 129 base::RefCountedString::TakeString(&image_data)); | 129 base::RefCountedString::TakeString(&image_data)); |
| 130 if (image.IsEmpty()) { | 130 if (image.IsEmpty()) { |
| 131 LOG(ERROR) << "Failed to decode PNG file."; | 131 LOG(ERROR) << "Failed to decode PNG file."; |
| 132 return; | 132 return; |
| 133 } | 133 } |
| 134 | 134 |
| 135 *out_image = new gfx::Image(image); | 135 *out_image = new gfx::Image(image); |
| 136 } | 136 } |
| 137 | 137 |
| 138 void CheckIfFileExists(const base::FilePath& file_path, | |
|
Mike Lerman
2015/01/27 16:39:15
Not a huge fan of the name (sorry!). I feel like a
noms (inactive)
2015/01/28 02:18:35
Done.
| |
| 139 const base::Closure& callback) { | |
| 140 if (!base::PathExists(file_path)) | |
|
Mike Lerman
2015/01/27 16:39:15
Do a CHECK that you're on FILE thread.
noms (inactive)
2015/01/28 02:18:35
Done.
| |
| 141 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback); | |
| 142 } | |
| 143 | |
| 138 void DeleteBitmap(const base::FilePath& image_path) { | 144 void DeleteBitmap(const base::FilePath& image_path) { |
| 139 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 145 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 140 base::DeleteFile(image_path, false); | 146 base::DeleteFile(image_path, false); |
| 141 } | 147 } |
| 142 | 148 |
| 143 } // namespace | 149 } // namespace |
| 144 | 150 |
| 145 ProfileInfoCache::ProfileInfoCache(PrefService* prefs, | 151 ProfileInfoCache::ProfileInfoCache(PrefService* prefs, |
| 146 const base::FilePath& user_data_dir) | 152 const base::FilePath& user_data_dir) |
| 147 : prefs_(prefs), | 153 : prefs_(prefs), |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 207 info->SetBoolean(kIsOmittedFromProfileListKey, !supervised_user_id.empty()); | 213 info->SetBoolean(kIsOmittedFromProfileListKey, !supervised_user_id.empty()); |
| 208 info->SetBoolean(kProfileIsEphemeral, false); | 214 info->SetBoolean(kProfileIsEphemeral, false); |
| 209 info->SetBoolean(kIsUsingDefaultNameKey, IsDefaultProfileName(name)); | 215 info->SetBoolean(kIsUsingDefaultNameKey, IsDefaultProfileName(name)); |
| 210 // Assume newly created profiles use a default avatar. | 216 // Assume newly created profiles use a default avatar. |
| 211 info->SetBoolean(kIsUsingDefaultAvatarKey, true); | 217 info->SetBoolean(kIsUsingDefaultAvatarKey, true); |
| 212 cache->SetWithoutPathExpansion(key, info.release()); | 218 cache->SetWithoutPathExpansion(key, info.release()); |
| 213 | 219 |
| 214 sorted_keys_.insert(FindPositionForProfile(key, name), key); | 220 sorted_keys_.insert(FindPositionForProfile(key, name), key); |
| 215 | 221 |
| 216 if (switches::IsNewAvatarMenu()) | 222 if (switches::IsNewAvatarMenu()) |
| 217 DownloadHighResAvatar(icon_index, profile_path); | 223 DownloadHighResAvatarIfNeeded(icon_index, profile_path); |
| 218 | 224 |
| 219 FOR_EACH_OBSERVER(ProfileInfoCacheObserver, | 225 FOR_EACH_OBSERVER(ProfileInfoCacheObserver, |
| 220 observer_list_, | 226 observer_list_, |
| 221 OnProfileAdded(profile_path)); | 227 OnProfileAdded(profile_path)); |
| 222 | 228 |
| 223 content::NotificationService::current()->Notify( | 229 content::NotificationService::current()->Notify( |
| 224 chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, | 230 chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, |
| 225 content::NotificationService::AllSources(), | 231 content::NotificationService::AllSources(), |
| 226 content::NotificationService::NoDetails()); | 232 content::NotificationService::NoDetails()); |
| 227 } | 233 } |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 529 size_t icon_index) { | 535 size_t icon_index) { |
| 530 scoped_ptr<base::DictionaryValue> info( | 536 scoped_ptr<base::DictionaryValue> info( |
| 531 GetInfoForProfileAtIndex(index)->DeepCopy()); | 537 GetInfoForProfileAtIndex(index)->DeepCopy()); |
| 532 info->SetString(kAvatarIconKey, | 538 info->SetString(kAvatarIconKey, |
| 533 profiles::GetDefaultAvatarIconUrl(icon_index)); | 539 profiles::GetDefaultAvatarIconUrl(icon_index)); |
| 534 // This takes ownership of |info|. | 540 // This takes ownership of |info|. |
| 535 SetInfoForProfileAtIndex(index, info.release()); | 541 SetInfoForProfileAtIndex(index, info.release()); |
| 536 | 542 |
| 537 base::FilePath profile_path = GetPathOfProfileAtIndex(index); | 543 base::FilePath profile_path = GetPathOfProfileAtIndex(index); |
| 538 | 544 |
| 539 // If needed, start downloading the high-res avatar. | |
| 540 if (switches::IsNewAvatarMenu()) | 545 if (switches::IsNewAvatarMenu()) |
| 541 DownloadHighResAvatar(icon_index, profile_path); | 546 DownloadHighResAvatarIfNeeded(icon_index, profile_path); |
| 542 | 547 |
| 543 FOR_EACH_OBSERVER(ProfileInfoCacheObserver, | 548 FOR_EACH_OBSERVER(ProfileInfoCacheObserver, |
| 544 observer_list_, | 549 observer_list_, |
| 545 OnProfileAvatarChanged(profile_path)); | 550 OnProfileAvatarChanged(profile_path)); |
| 546 } | 551 } |
| 547 | 552 |
| 548 void ProfileInfoCache::SetIsOmittedProfileAtIndex(size_t index, | 553 void ProfileInfoCache::SetIsOmittedProfileAtIndex(size_t index, |
| 549 bool is_omitted) { | 554 bool is_omitted) { |
| 550 if (IsOmittedProfileAtIndex(index) == is_omitted) | 555 if (IsOmittedProfileAtIndex(index) == is_omitted) |
| 551 return; | 556 return; |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 686 } | 691 } |
| 687 | 692 |
| 688 void ProfileInfoCache::SetIsUsingGAIAPictureOfProfileAtIndex(size_t index, | 693 void ProfileInfoCache::SetIsUsingGAIAPictureOfProfileAtIndex(size_t index, |
| 689 bool value) { | 694 bool value) { |
| 690 scoped_ptr<base::DictionaryValue> info( | 695 scoped_ptr<base::DictionaryValue> info( |
| 691 GetInfoForProfileAtIndex(index)->DeepCopy()); | 696 GetInfoForProfileAtIndex(index)->DeepCopy()); |
| 692 info->SetBoolean(kUseGAIAPictureKey, value); | 697 info->SetBoolean(kUseGAIAPictureKey, value); |
| 693 // This takes ownership of |info|. | 698 // This takes ownership of |info|. |
| 694 SetInfoForProfileAtIndex(index, info.release()); | 699 SetInfoForProfileAtIndex(index, info.release()); |
| 695 | 700 |
| 696 // Retrieve some info to update observers who care about avatar changes. | |
| 697 base::FilePath profile_path = GetPathOfProfileAtIndex(index); | 701 base::FilePath profile_path = GetPathOfProfileAtIndex(index); |
| 698 FOR_EACH_OBSERVER(ProfileInfoCacheObserver, | 702 FOR_EACH_OBSERVER(ProfileInfoCacheObserver, |
| 699 observer_list_, | 703 observer_list_, |
| 700 OnProfileAvatarChanged(profile_path)); | 704 OnProfileAvatarChanged(profile_path)); |
| 701 } | 705 } |
| 702 | 706 |
| 703 void ProfileInfoCache::SetProfileSigninRequiredAtIndex(size_t index, | 707 void ProfileInfoCache::SetProfileSigninRequiredAtIndex(size_t index, |
| 704 bool value) { | 708 bool value) { |
| 705 if (value == ProfileIsSigninRequiredAtIndex(index)) | 709 if (value == ProfileIsSigninRequiredAtIndex(index)) |
| 706 return; | 710 return; |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 841 names.push_back(name); | 845 names.push_back(name); |
| 842 } | 846 } |
| 843 return names; | 847 return names; |
| 844 } | 848 } |
| 845 | 849 |
| 846 // static | 850 // static |
| 847 void ProfileInfoCache::RegisterPrefs(PrefRegistrySimple* registry) { | 851 void ProfileInfoCache::RegisterPrefs(PrefRegistrySimple* registry) { |
| 848 registry->RegisterDictionaryPref(prefs::kProfileInfoCache); | 852 registry->RegisterDictionaryPref(prefs::kProfileInfoCache); |
| 849 } | 853 } |
| 850 | 854 |
| 851 void ProfileInfoCache::DownloadHighResAvatar( | 855 void ProfileInfoCache::DownloadHighResAvatarIfNeeded( |
| 852 size_t icon_index, | 856 size_t icon_index, |
| 853 const base::FilePath& profile_path) { | 857 const base::FilePath& profile_path) { |
| 854 // Downloading is only supported on desktop. | 858 // Downloading is only supported on desktop. |
| 855 #if defined(OS_ANDROID) || defined(OS_IOS) || defined(OS_CHROMEOS) | 859 #if defined(OS_ANDROID) || defined(OS_IOS) || defined(OS_CHROMEOS) |
| 856 return; | 860 return; |
| 857 #endif | 861 #endif |
| 858 | 862 |
| 859 // TODO(noms): We should check whether the file already exists on disk | 863 const base::FilePath file_path = |
| 860 // before trying to re-download it. For now, since this is behind a flag and | 864 profiles::GetPathOfHighResAvatarAtIndex(icon_index); |
| 861 // the resources are still changing, re-download it every time the profile | 865 base::Closure callback = |
| 862 // avatar changes, to make sure we have the latest copy. | 866 base::Bind(&ProfileInfoCache::DownloadHighResAvatar, |
| 863 std::string file_name = profiles::GetDefaultAvatarIconFileNameAtIndex( | 867 AsWeakPtr(), |
| 864 icon_index); | 868 profiles::GetDefaultAvatarIconFileNameAtIndex(icon_index), |
| 865 // If the file is already being downloaded, don't start another download. | 869 icon_index, |
| 866 if (avatar_images_downloads_in_progress_[file_name]) | 870 profile_path); |
| 867 return; | 871 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
|
Mike Lerman
2015/01/27 16:39:15
Rather that posting to FILE, consider using a Bloc
noms (inactive)
2015/01/28 02:18:35
I'd rather have all the posts in this file look th
Mike Lerman
2015/01/28 18:32:56
that's ok :)
| |
| 868 | 872 base::Bind(&CheckIfFileExists, file_path, callback)); |
| 869 // Start the download for this file. The cache takes ownership of the | |
| 870 // |avatar_downloader|, which will be deleted when the download completes, or | |
| 871 // if that never happens, when the ProfileInfoCache is destroyed. | |
| 872 ProfileAvatarDownloader* avatar_downloader = new ProfileAvatarDownloader( | |
| 873 icon_index, | |
| 874 profile_path, | |
| 875 this); | |
| 876 avatar_images_downloads_in_progress_[file_name] = avatar_downloader; | |
| 877 avatar_downloader->Start(); | |
| 878 } | 873 } |
| 879 | 874 |
| 880 void ProfileInfoCache::SaveAvatarImageAtPath( | 875 void ProfileInfoCache::SaveAvatarImageAtPath( |
| 881 const gfx::Image* image, | 876 const gfx::Image* image, |
| 882 const std::string& key, | 877 const std::string& key, |
| 883 const base::FilePath& image_path, | 878 const base::FilePath& image_path, |
| 884 const base::FilePath& profile_path) { | 879 const base::FilePath& profile_path) { |
| 885 cached_avatar_images_[key] = new gfx::Image(*image); | 880 cached_avatar_images_[key] = new gfx::Image(*image); |
| 886 | 881 |
| 887 scoped_ptr<ImageData> data(new ImageData); | 882 scoped_ptr<ImageData> data(new ImageData); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1008 | 1003 |
| 1009 if (!strcmp(key.c_str(), profiles::GetNoHighResAvatarFileName())) | 1004 if (!strcmp(key.c_str(), profiles::GetNoHighResAvatarFileName())) |
| 1010 return NULL; | 1005 return NULL; |
| 1011 | 1006 |
| 1012 base::FilePath image_path = | 1007 base::FilePath image_path = |
| 1013 profiles::GetPathOfHighResAvatarAtIndex(avatar_index); | 1008 profiles::GetPathOfHighResAvatarAtIndex(avatar_index); |
| 1014 return LoadAvatarPictureFromPath(GetPathOfProfileAtIndex(index), | 1009 return LoadAvatarPictureFromPath(GetPathOfProfileAtIndex(index), |
| 1015 key, image_path); | 1010 key, image_path); |
| 1016 } | 1011 } |
| 1017 | 1012 |
| 1013 void ProfileInfoCache::DownloadHighResAvatar( | |
| 1014 const std::string file_name, | |
|
Mike Lerman
2015/01/27 16:39:15
For simplicity, and to have this signature match D
noms (inactive)
2015/01/28 02:18:35
Done.
| |
| 1015 size_t icon_index, | |
| 1016 const base::FilePath& profile_path) { | |
| 1017 // Downloading is only supported on desktop. | |
| 1018 #if defined(OS_ANDROID) || defined(OS_IOS) || defined(OS_CHROMEOS) | |
| 1019 return; | |
| 1020 #endif | |
| 1021 | |
| 1022 // If the file is already being downloaded, don't start another download. | |
| 1023 if (avatar_images_downloads_in_progress_[file_name]) | |
| 1024 return; | |
| 1025 | |
| 1026 // Start the download for this file. The cache takes ownership of the | |
| 1027 // |avatar_downloader|, which will be deleted when the download completes, or | |
| 1028 // if that never happens, when the ProfileInfoCache is destroyed. | |
| 1029 ProfileAvatarDownloader* avatar_downloader = new ProfileAvatarDownloader( | |
| 1030 icon_index, | |
| 1031 profile_path, | |
| 1032 this); | |
| 1033 avatar_images_downloads_in_progress_[file_name] = avatar_downloader; | |
| 1034 avatar_downloader->Start(); | |
| 1035 } | |
| 1036 | |
| 1018 const gfx::Image* ProfileInfoCache::LoadAvatarPictureFromPath( | 1037 const gfx::Image* ProfileInfoCache::LoadAvatarPictureFromPath( |
| 1019 const base::FilePath& profile_path, | 1038 const base::FilePath& profile_path, |
| 1020 const std::string& key, | 1039 const std::string& key, |
| 1021 const base::FilePath& image_path) const { | 1040 const base::FilePath& image_path) const { |
| 1022 // If the picture is already loaded then use it. | 1041 // If the picture is already loaded then use it. |
| 1023 if (cached_avatar_images_.count(key)) { | 1042 if (cached_avatar_images_.count(key)) { |
| 1024 if (cached_avatar_images_[key]->IsEmpty()) | 1043 if (cached_avatar_images_[key]->IsEmpty()) |
| 1025 return NULL; | 1044 return NULL; |
| 1026 return cached_avatar_images_[key]; | 1045 return cached_avatar_images_[key]; |
| 1027 } | 1046 } |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 1056 } | 1075 } |
| 1057 delete image; | 1076 delete image; |
| 1058 | 1077 |
| 1059 content::NotificationService::current()->Notify( | 1078 content::NotificationService::current()->Notify( |
| 1060 chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, | 1079 chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, |
| 1061 content::NotificationService::AllSources(), | 1080 content::NotificationService::AllSources(), |
| 1062 content::NotificationService::NoDetails()); | 1081 content::NotificationService::NoDetails()); |
| 1063 | 1082 |
| 1064 FOR_EACH_OBSERVER(ProfileInfoCacheObserver, | 1083 FOR_EACH_OBSERVER(ProfileInfoCacheObserver, |
| 1065 observer_list_, | 1084 observer_list_, |
| 1066 OnProfileAvatarChanged(profile_path)); | 1085 OnProfileHighResAvatarLoaded(profile_path)); |
| 1067 } | 1086 } |
| 1068 | 1087 |
| 1069 void ProfileInfoCache::OnAvatarPictureSaved( | 1088 void ProfileInfoCache::OnAvatarPictureSaved( |
| 1070 const std::string& file_name, | 1089 const std::string& file_name, |
| 1071 const base::FilePath& profile_path) { | 1090 const base::FilePath& profile_path) { |
| 1072 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1091 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1073 | 1092 |
| 1074 content::NotificationService::current()->Notify( | 1093 content::NotificationService::current()->Notify( |
| 1075 chrome::NOTIFICATION_PROFILE_CACHE_PICTURE_SAVED, | 1094 chrome::NOTIFICATION_PROFILE_CACHE_PICTURE_SAVED, |
| 1076 content::NotificationService::AllSources(), | 1095 content::NotificationService::AllSources(), |
| 1077 content::NotificationService::NoDetails()); | 1096 content::NotificationService::NoDetails()); |
| 1078 | 1097 |
| 1079 FOR_EACH_OBSERVER(ProfileInfoCacheObserver, | 1098 FOR_EACH_OBSERVER(ProfileInfoCacheObserver, |
| 1080 observer_list_, | 1099 observer_list_, |
| 1081 OnProfileAvatarChanged(profile_path)); | 1100 OnProfileHighResAvatarLoaded(profile_path)); |
| 1082 | 1101 |
| 1083 // Remove the file from the list of downloads in progress. Note that this list | 1102 // Remove the file from the list of downloads in progress. Note that this list |
| 1084 // only contains the high resolution avatars, and not the Gaia profile images. | 1103 // only contains the high resolution avatars, and not the Gaia profile images. |
| 1085 if (!avatar_images_downloads_in_progress_[file_name]) | 1104 if (!avatar_images_downloads_in_progress_[file_name]) |
| 1086 return; | 1105 return; |
| 1087 | 1106 |
| 1088 delete avatar_images_downloads_in_progress_[file_name]; | 1107 delete avatar_images_downloads_in_progress_[file_name]; |
| 1089 avatar_images_downloads_in_progress_[file_name] = NULL; | 1108 avatar_images_downloads_in_progress_[file_name] = NULL; |
| 1090 } | 1109 } |
| 1091 | 1110 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1103 // depend on the names of all the other profiles in the info cache, so they | 1122 // depend on the names of all the other profiles in the info cache, so they |
| 1104 // need to be re-computed after each rename. | 1123 // need to be re-computed after each rename. |
| 1105 std::vector<base::FilePath> profiles_to_rename; | 1124 std::vector<base::FilePath> profiles_to_rename; |
| 1106 | 1125 |
| 1107 const base::string16 default_profile_name = base::i18n::ToLower( | 1126 const base::string16 default_profile_name = base::i18n::ToLower( |
| 1108 l10n_util::GetStringUTF16(IDS_DEFAULT_PROFILE_NAME)); | 1127 l10n_util::GetStringUTF16(IDS_DEFAULT_PROFILE_NAME)); |
| 1109 const base::string16 default_legacy_profile_name = base::i18n::ToLower( | 1128 const base::string16 default_legacy_profile_name = base::i18n::ToLower( |
| 1110 l10n_util::GetStringUTF16(IDS_LEGACY_DEFAULT_PROFILE_NAME)); | 1129 l10n_util::GetStringUTF16(IDS_LEGACY_DEFAULT_PROFILE_NAME)); |
| 1111 | 1130 |
| 1112 for (size_t i = 0; i < GetNumberOfProfiles(); i++) { | 1131 for (size_t i = 0; i < GetNumberOfProfiles(); i++) { |
| 1113 // If needed, start downloading the high-res avatar for this profile. | 1132 DownloadHighResAvatarIfNeeded(GetAvatarIconIndexOfProfileAtIndex(i), |
| 1114 DownloadHighResAvatar(GetAvatarIconIndexOfProfileAtIndex(i), | 1133 GetPathOfProfileAtIndex(i)); |
| 1115 GetPathOfProfileAtIndex(i)); | |
| 1116 | 1134 |
| 1117 base::string16 name = base::i18n::ToLower(GetNameOfProfileAtIndex(i)); | 1135 base::string16 name = base::i18n::ToLower(GetNameOfProfileAtIndex(i)); |
| 1118 if (name == default_profile_name || name == default_legacy_profile_name) | 1136 if (name == default_profile_name || name == default_legacy_profile_name) |
| 1119 profiles_to_rename.push_back(GetPathOfProfileAtIndex(i)); | 1137 profiles_to_rename.push_back(GetPathOfProfileAtIndex(i)); |
| 1120 } | 1138 } |
| 1121 | 1139 |
| 1122 // Rename the necessary profiles. | 1140 // Rename the necessary profiles. |
| 1123 std::vector<base::FilePath>::const_iterator it; | 1141 std::vector<base::FilePath>::const_iterator it; |
| 1124 for (it = profiles_to_rename.begin(); it != profiles_to_rename.end(); ++it) { | 1142 for (it = profiles_to_rename.begin(); it != profiles_to_rename.end(); ++it) { |
| 1125 size_t profile_index = GetIndexOfProfileWithPath(*it); | 1143 size_t profile_index = GetIndexOfProfileWithPath(*it); |
| 1126 SetProfileIsUsingDefaultNameAtIndex(profile_index, true); | 1144 SetProfileIsUsingDefaultNameAtIndex(profile_index, true); |
| 1127 // This will assign a new "Person %d" type name and re-sort the cache. | 1145 // This will assign a new "Person %d" type name and re-sort the cache. |
| 1128 SetNameOfProfileAtIndex(profile_index, ChooseNameForNewProfile( | 1146 SetNameOfProfileAtIndex(profile_index, ChooseNameForNewProfile( |
| 1129 GetAvatarIconIndexOfProfileAtIndex(profile_index))); | 1147 GetAvatarIconIndexOfProfileAtIndex(profile_index))); |
| 1130 } | 1148 } |
| 1131 #endif | 1149 #endif |
| 1132 } | 1150 } |
| OLD | NEW |