Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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" | |
| 8 #include "base/file_util.h" | |
| 7 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
| 10 #include "base/i18n/case_conversion.h" | |
| 8 #include "base/logging.h" | 11 #include "base/logging.h" |
| 9 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/rand_util.h" | 13 #include "base/rand_util.h" |
| 14 #include "base/stl_util.h" | |
| 11 #include "base/string_number_conversions.h" | 15 #include "base/string_number_conversions.h" |
| 12 #include "base/stringprintf.h" | 16 #include "base/stringprintf.h" |
| 13 #include "base/utf_string_conversions.h" | 17 #include "base/utf_string_conversions.h" |
| 14 #include "base/values.h" | 18 #include "base/values.h" |
| 15 #include "chrome/browser/prefs/pref_service.h" | 19 #include "chrome/browser/prefs/pref_service.h" |
| 16 #include "chrome/browser/prefs/scoped_user_pref_update.h" | 20 #include "chrome/browser/prefs/scoped_user_pref_update.h" |
| 17 #include "chrome/common/chrome_notification_types.h" | 21 #include "chrome/common/chrome_notification_types.h" |
| 18 #include "chrome/common/pref_names.h" | 22 #include "chrome/common/pref_names.h" |
| 23 #include "content/public/browser/browser_thread.h" | |
| 19 #include "content/public/browser/notification_service.h" | 24 #include "content/public/browser/notification_service.h" |
| 20 #include "grit/generated_resources.h" | 25 #include "grit/generated_resources.h" |
| 21 #include "grit/theme_resources.h" | 26 #include "grit/theme_resources.h" |
| 27 #include "third_party/skia/include/core/SkBitmap.h" | |
| 22 #include "ui/base/l10n/l10n_util.h" | 28 #include "ui/base/l10n/l10n_util.h" |
| 23 #include "ui/base/resource/resource_bundle.h" | 29 #include "ui/base/resource/resource_bundle.h" |
| 30 #include "ui/gfx/image/image.h" | |
| 31 #include "ui/gfx/image/image_util.h" | |
| 32 | |
| 33 using content::BrowserThread; | |
| 24 | 34 |
| 25 namespace { | 35 namespace { |
| 26 | 36 |
| 27 const char kNameKey[] = "name"; | 37 const char kNameKey[] = "name"; |
| 38 const char kGAIANameKey[] = "gaia_name"; | |
| 39 const char kUseGAIANameKey[] = "use_gaia_name"; | |
| 28 const char kUserNameKey[] = "user_name"; | 40 const char kUserNameKey[] = "user_name"; |
| 29 const char kAvatarIconKey[] = "avatar_icon"; | 41 const char kAvatarIconKey[] = "avatar_icon"; |
| 42 const char kUseGAIAPictureKey[] = "use_gaia_picture"; | |
| 30 const char kBackgroundAppsKey[] = "background_apps"; | 43 const char kBackgroundAppsKey[] = "background_apps"; |
| 44 const char kHasMigratedToGAIAInfoKey[] = "has_migrated_to_gaia_info"; | |
| 31 const char kDefaultUrlPrefix[] = "chrome://theme/IDR_PROFILE_AVATAR_"; | 45 const char kDefaultUrlPrefix[] = "chrome://theme/IDR_PROFILE_AVATAR_"; |
| 46 const char kGAIAPictureFileName[] = "Google Profile Picture.png"; | |
| 32 | 47 |
| 33 const int kDefaultAvatarIconResources[] = { | 48 const int kDefaultAvatarIconResources[] = { |
| 34 IDR_PROFILE_AVATAR_0, | 49 IDR_PROFILE_AVATAR_0, |
| 35 IDR_PROFILE_AVATAR_1, | 50 IDR_PROFILE_AVATAR_1, |
| 36 IDR_PROFILE_AVATAR_2, | 51 IDR_PROFILE_AVATAR_2, |
| 37 IDR_PROFILE_AVATAR_3, | 52 IDR_PROFILE_AVATAR_3, |
| 38 IDR_PROFILE_AVATAR_4, | 53 IDR_PROFILE_AVATAR_4, |
| 39 IDR_PROFILE_AVATAR_5, | 54 IDR_PROFILE_AVATAR_5, |
| 40 IDR_PROFILE_AVATAR_6, | 55 IDR_PROFILE_AVATAR_6, |
| 41 IDR_PROFILE_AVATAR_7, | 56 IDR_PROFILE_AVATAR_7, |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 79 IDS_DEFAULT_AVATAR_NAME_18, | 94 IDS_DEFAULT_AVATAR_NAME_18, |
| 80 IDS_DEFAULT_AVATAR_NAME_19, | 95 IDS_DEFAULT_AVATAR_NAME_19, |
| 81 IDS_DEFAULT_AVATAR_NAME_20, | 96 IDS_DEFAULT_AVATAR_NAME_20, |
| 82 IDS_DEFAULT_AVATAR_NAME_21, | 97 IDS_DEFAULT_AVATAR_NAME_21, |
| 83 IDS_DEFAULT_AVATAR_NAME_22, | 98 IDS_DEFAULT_AVATAR_NAME_22, |
| 84 IDS_DEFAULT_AVATAR_NAME_23, | 99 IDS_DEFAULT_AVATAR_NAME_23, |
| 85 IDS_DEFAULT_AVATAR_NAME_24, | 100 IDS_DEFAULT_AVATAR_NAME_24, |
| 86 IDS_DEFAULT_AVATAR_NAME_25 | 101 IDS_DEFAULT_AVATAR_NAME_25 |
| 87 }; | 102 }; |
| 88 | 103 |
| 104 // Writes the given bitmap as a PNG to disk. On completion |success| is set to | |
| 105 // true on success and false on failure. | |
| 106 void SaveBitmap(gfx::Image image, | |
| 107 FilePath image_path, | |
| 108 bool *success) { | |
|
Robert Sesek
2011/11/22 21:26:37
^T[ *]
sail
2011/11/22 21:43:23
Done.
| |
| 109 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | |
| 110 *success = false; | |
| 111 | |
| 112 // Make sure the destination directory exists. | |
| 113 FilePath dir = image_path.DirName(); | |
| 114 if (!file_util::DirectoryExists(dir) && !file_util::CreateDirectory(dir)) { | |
| 115 LOG(ERROR) << "Failed to create parent directory."; | |
| 116 return; | |
| 117 } | |
| 118 | |
| 119 std::vector<unsigned char> encoded_image; | |
| 120 if (!gfx::PNGEncodedDataFromImage(image, &encoded_image)) { | |
| 121 LOG(ERROR) << "Failed to PNG encode the image."; | |
| 122 return; | |
| 123 } | |
| 124 | |
| 125 if (file_util::WriteFile(image_path, | |
| 126 reinterpret_cast<char*>(&encoded_image[0]), | |
| 127 encoded_image.size()) == -1) { | |
| 128 LOG(ERROR) << "Failed to save image to file."; | |
| 129 return; | |
| 130 } | |
| 131 | |
| 132 *success = true; | |
| 133 } | |
| 134 | |
| 135 // Reads a PNG from disk and decodes it. If the bitmap was successfully read | |
| 136 // from disk the then |out_image| will contain the bitmap image, otherwise it | |
| 137 // will be NULL. | |
| 138 void ReadBitmap(FilePath image_path, | |
| 139 gfx::Image** out_image) { | |
| 140 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | |
| 141 *out_image = NULL; | |
| 142 | |
| 143 std::string image_data; | |
| 144 if (!file_util::ReadFileToString(image_path, &image_data)) { | |
| 145 LOG(ERROR) << "Failed to read PNG file from disk."; | |
| 146 return; | |
| 147 } | |
| 148 | |
| 149 const unsigned char* data = | |
| 150 reinterpret_cast<const unsigned char*>(image_data.data()); | |
| 151 gfx::Image* image = gfx::ImageFromPNGEncodedData(data, image_data.length()); | |
| 152 if (image == NULL) { | |
| 153 LOG(ERROR) << "Failed to decode PNG file."; | |
| 154 return; | |
| 155 } | |
| 156 | |
| 157 *out_image = image; | |
| 158 } | |
| 159 | |
| 89 } // namespace | 160 } // namespace |
| 90 | 161 |
| 91 ProfileInfoCache::ProfileInfoCache(PrefService* prefs, | 162 ProfileInfoCache::ProfileInfoCache(PrefService* prefs, |
| 92 const FilePath& user_data_dir) | 163 const FilePath& user_data_dir) |
| 93 : prefs_(prefs), | 164 : prefs_(prefs), |
| 94 user_data_dir_(user_data_dir) { | 165 user_data_dir_(user_data_dir) { |
| 95 // Populate the cache | 166 // Populate the cache |
| 96 const DictionaryValue* cache = | 167 const DictionaryValue* cache = |
| 97 prefs_->GetDictionary(prefs::kProfileInfoCache); | 168 prefs_->GetDictionary(prefs::kProfileInfoCache); |
| 98 for (DictionaryValue::key_iterator it = cache->begin_keys(); | 169 for (DictionaryValue::key_iterator it = cache->begin_keys(); |
| 99 it != cache->end_keys(); ++it) { | 170 it != cache->end_keys(); ++it) { |
| 100 std::string key = *it; | 171 std::string key = *it; |
| 101 DictionaryValue* info = NULL; | 172 DictionaryValue* info = NULL; |
| 102 cache->GetDictionary(key, &info); | 173 cache->GetDictionary(key, &info); |
| 103 string16 name; | 174 string16 name; |
| 104 info->GetString(kNameKey, &name); | 175 info->GetString(kNameKey, &name); |
| 105 sorted_keys_.insert(FindPositionForProfile(key, name), key); | 176 sorted_keys_.insert(FindPositionForProfile(key, name), key); |
| 106 } | 177 } |
| 107 } | 178 } |
| 108 | 179 |
| 109 ProfileInfoCache::~ProfileInfoCache() { | 180 ProfileInfoCache::~ProfileInfoCache() { |
| 181 STLDeleteContainerPairSecondPointers( | |
| 182 gaia_pictures_.begin(), gaia_pictures_.end()); | |
| 110 } | 183 } |
| 111 | 184 |
| 112 void ProfileInfoCache::AddProfileToCache(const FilePath& profile_path, | 185 void ProfileInfoCache::AddProfileToCache(const FilePath& profile_path, |
| 113 const string16& name, | 186 const string16& name, |
| 114 const string16& username, | 187 const string16& username, |
| 115 size_t icon_index) { | 188 size_t icon_index) { |
| 116 std::string key = CacheKeyFromProfilePath(profile_path); | 189 std::string key = CacheKeyFromProfilePath(profile_path); |
| 117 DictionaryPrefUpdate update(prefs_, prefs::kProfileInfoCache); | 190 DictionaryPrefUpdate update(prefs_, prefs::kProfileInfoCache); |
| 118 DictionaryValue* cache = update.Get(); | 191 DictionaryValue* cache = update.Get(); |
| 119 | 192 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 157 return std::string::npos; | 230 return std::string::npos; |
| 158 std::string search_key = CacheKeyFromProfilePath(profile_path); | 231 std::string search_key = CacheKeyFromProfilePath(profile_path); |
| 159 for (size_t i = 0; i < sorted_keys_.size(); ++i) { | 232 for (size_t i = 0; i < sorted_keys_.size(); ++i) { |
| 160 if (sorted_keys_[i] == search_key) | 233 if (sorted_keys_[i] == search_key) |
| 161 return i; | 234 return i; |
| 162 } | 235 } |
| 163 return std::string::npos; | 236 return std::string::npos; |
| 164 } | 237 } |
| 165 | 238 |
| 166 string16 ProfileInfoCache::GetNameOfProfileAtIndex(size_t index) const { | 239 string16 ProfileInfoCache::GetNameOfProfileAtIndex(size_t index) const { |
| 240 if (IsUsingGAIANameOfProfileAtIndex(index)) | |
| 241 return GetGAIANameOfProfileAtIndex(index); | |
| 242 | |
| 167 string16 name; | 243 string16 name; |
| 168 GetInfoForProfileAtIndex(index)->GetString(kNameKey, &name); | 244 GetInfoForProfileAtIndex(index)->GetString(kNameKey, &name); |
| 169 return name; | 245 return name; |
| 170 } | 246 } |
| 171 | 247 |
| 172 FilePath ProfileInfoCache::GetPathOfProfileAtIndex(size_t index) const { | 248 FilePath ProfileInfoCache::GetPathOfProfileAtIndex(size_t index) const { |
| 173 FilePath::StringType base_name; | 249 return user_data_dir_.AppendASCII(sorted_keys_[index]); |
| 174 #if defined(OS_POSIX) | |
| 175 base_name = sorted_keys_[index]; | |
| 176 #elif defined(OS_WIN) | |
| 177 base_name = ASCIIToWide(sorted_keys_[index]); | |
| 178 #endif | |
| 179 return user_data_dir_.Append(base_name); | |
| 180 } | 250 } |
| 181 | 251 |
| 182 string16 ProfileInfoCache::GetUserNameOfProfileAtIndex(size_t index) const { | 252 string16 ProfileInfoCache::GetUserNameOfProfileAtIndex(size_t index) const { |
| 183 string16 user_name; | 253 string16 user_name; |
| 184 GetInfoForProfileAtIndex(index)->GetString(kUserNameKey, &user_name); | 254 GetInfoForProfileAtIndex(index)->GetString(kUserNameKey, &user_name); |
| 185 return user_name; | 255 return user_name; |
| 186 } | 256 } |
| 187 | 257 |
| 188 const gfx::Image& ProfileInfoCache::GetAvatarIconOfProfileAtIndex( | 258 const gfx::Image& ProfileInfoCache::GetAvatarIconOfProfileAtIndex( |
| 189 size_t index) const { | 259 size_t index) const { |
| 260 if (IsUsingGAIAPictureOfProfileAtIndex(index)) | |
| 261 return GetGAIAPictureOfProfileAtIndex(index); | |
| 262 | |
| 190 int resource_id = GetDefaultAvatarIconResourceIDAtIndex( | 263 int resource_id = GetDefaultAvatarIconResourceIDAtIndex( |
| 191 GetAvatarIconIndexOfProfileAtIndex(index)); | 264 GetAvatarIconIndexOfProfileAtIndex(index)); |
| 192 return ResourceBundle::GetSharedInstance().GetImageNamed(resource_id); | 265 return ResourceBundle::GetSharedInstance().GetImageNamed(resource_id); |
| 193 } | 266 } |
| 194 | 267 |
| 195 bool ProfileInfoCache::GetBackgroundStatusOfProfileAtIndex( | 268 bool ProfileInfoCache::GetBackgroundStatusOfProfileAtIndex( |
| 196 size_t index) const { | 269 size_t index) const { |
| 197 bool background_app_status; | 270 bool background_app_status; |
| 198 GetInfoForProfileAtIndex(index)->GetBoolean(kBackgroundAppsKey, | 271 GetInfoForProfileAtIndex(index)->GetBoolean(kBackgroundAppsKey, |
| 199 &background_app_status); | 272 &background_app_status); |
| 200 return background_app_status; | 273 return background_app_status; |
| 201 } | 274 } |
| 202 | 275 |
| 276 string16 ProfileInfoCache::GetGAIANameOfProfileAtIndex(size_t index) const { | |
| 277 string16 name; | |
| 278 GetInfoForProfileAtIndex(index)->GetString(kGAIANameKey, &name); | |
| 279 return name; | |
| 280 } | |
| 281 | |
| 282 bool ProfileInfoCache::IsUsingGAIANameOfProfileAtIndex(size_t index) const { | |
| 283 bool value = false; | |
| 284 GetInfoForProfileAtIndex(index)->GetBoolean(kUseGAIANameKey, &value); | |
| 285 return value; | |
| 286 } | |
| 287 | |
| 288 const gfx::Image& ProfileInfoCache::GetGAIAPictureOfProfileAtIndex( | |
| 289 size_t index) const { | |
| 290 FilePath path = GetPathOfProfileAtIndex(index); | |
| 291 std::string key = CacheKeyFromProfilePath(path); | |
| 292 if (gaia_pictures_.count(key)) { | |
| 293 return *gaia_pictures_[key]; | |
| 294 } | |
| 295 | |
| 296 // The GAIA picture is not in the cache yet. Load it from disk and return | |
| 297 // a blank picture for now. | |
| 298 gaia_pictures_[key] = new gfx::Image(new SkBitmap()); | |
| 299 | |
| 300 FilePath image_path = path.AppendASCII(kGAIAPictureFileName); | |
| 301 gfx::Image** image = new gfx::Image*; | |
| 302 BrowserThread::PostTaskAndReply(BrowserThread::FILE, FROM_HERE, | |
| 303 base::Bind(&ReadBitmap, image_path, image), | |
| 304 base::Bind(&ProfileInfoCache::OnGAIAPictureLoaded, | |
| 305 const_cast<ProfileInfoCache*>(this)->AsWeakPtr(), path, image)); | |
| 306 | |
| 307 return *gaia_pictures_[key]; | |
| 308 } | |
| 309 | |
| 310 void ProfileInfoCache::OnGAIAPictureLoaded(FilePath path, | |
| 311 gfx::Image** image) const { | |
| 312 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 313 | |
| 314 if (*image) { | |
| 315 std::string key = CacheKeyFromProfilePath(path); | |
| 316 gaia_pictures_[key] = *image; | |
| 317 | |
| 318 content::NotificationService::current()->Notify( | |
| 319 chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, | |
| 320 content::NotificationService::AllSources(), | |
| 321 content::NotificationService::NoDetails()); | |
| 322 } | |
| 323 delete image; | |
| 324 } | |
| 325 | |
| 326 void ProfileInfoCache::OnGAIAPictureSaved(FilePath path, bool* success) const { | |
| 327 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 328 | |
| 329 if (*success) { | |
| 330 content::NotificationService::current()->Notify( | |
| 331 chrome::NOTIFICATION_PROFILE_CACHE_PICTURE_SAVED, | |
| 332 content::NotificationService::AllSources(), | |
| 333 content::NotificationService::NoDetails()); | |
| 334 } | |
| 335 delete success; | |
| 336 } | |
| 337 | |
| 338 bool ProfileInfoCache::IsUsingGAIAPictureOfProfileAtIndex( | |
| 339 size_t index) const { | |
| 340 bool value = false; | |
| 341 GetInfoForProfileAtIndex(index)->GetBoolean(kUseGAIAPictureKey, &value); | |
| 342 return value; | |
| 343 } | |
| 344 | |
| 203 size_t ProfileInfoCache::GetAvatarIconIndexOfProfileAtIndex(size_t index) | 345 size_t ProfileInfoCache::GetAvatarIconIndexOfProfileAtIndex(size_t index) |
| 204 const { | 346 const { |
| 205 std::string icon_url; | 347 std::string icon_url; |
| 206 GetInfoForProfileAtIndex(index)->GetString(kAvatarIconKey, &icon_url); | 348 GetInfoForProfileAtIndex(index)->GetString(kAvatarIconKey, &icon_url); |
| 207 size_t icon_index = 0; | 349 size_t icon_index = 0; |
| 208 if (IsDefaultAvatarIconUrl(icon_url, &icon_index)) | 350 if (IsDefaultAvatarIconUrl(icon_url, &icon_index)) |
| 209 return icon_index; | 351 return icon_index; |
| 210 | 352 |
| 211 DLOG(WARNING) << "Unknown avatar icon: " << icon_url; | 353 DLOG(WARNING) << "Unknown avatar icon: " << icon_url; |
| 212 return GetDefaultAvatarIconResourceIDAtIndex(0); | 354 return GetDefaultAvatarIconResourceIDAtIndex(0); |
| 213 } | 355 } |
| 214 | 356 |
| 215 void ProfileInfoCache::SetNameOfProfileAtIndex(size_t index, | 357 void ProfileInfoCache::SetNameOfProfileAtIndex(size_t index, |
| 216 const string16& name) { | 358 const string16& name) { |
| 359 if (name == GetNameOfProfileAtIndex(index)) | |
| 360 return; | |
| 361 | |
| 217 scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy()); | 362 scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy()); |
| 218 info->SetString(kNameKey, name); | 363 info->SetString(kNameKey, name); |
| 219 // This takes ownership of |info|. | 364 // This takes ownership of |info|. |
| 220 SetInfoForProfileAtIndex(index, info.release()); | 365 SetInfoForProfileAtIndex(index, info.release()); |
| 221 | 366 UpdateSortForProfileIndex(index); |
| 222 // Remove and reinsert key in |sorted_keys_| to alphasort. | |
| 223 std::string key = CacheKeyFromProfilePath(GetPathOfProfileAtIndex(index)); | |
| 224 std::vector<std::string>::iterator key_it = | |
| 225 std::find(sorted_keys_.begin(), sorted_keys_.end(), key); | |
| 226 DCHECK(key_it != sorted_keys_.end()); | |
| 227 sorted_keys_.erase(key_it); | |
| 228 sorted_keys_.insert(FindPositionForProfile(key, name), key); | |
| 229 | |
| 230 content::NotificationService::current()->Notify( | |
| 231 chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, | |
| 232 content::NotificationService::AllSources(), | |
| 233 content::NotificationService::NoDetails()); | |
| 234 } | 367 } |
| 235 | 368 |
| 236 void ProfileInfoCache::SetUserNameOfProfileAtIndex(size_t index, | 369 void ProfileInfoCache::SetUserNameOfProfileAtIndex(size_t index, |
| 237 const string16& user_name) { | 370 const string16& user_name) { |
| 238 string16 old_user_name; | 371 if (user_name == GetUserNameOfProfileAtIndex(index)) |
| 239 const base::DictionaryValue* old_info = GetInfoForProfileAtIndex(index); | |
| 240 old_info->GetString(kUserNameKey, &old_user_name); | |
| 241 if (old_user_name == user_name) | |
| 242 return; | 372 return; |
| 243 | 373 |
| 244 scoped_ptr<DictionaryValue> info(old_info->DeepCopy()); | 374 scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy()); |
| 245 info->SetString(kUserNameKey, user_name); | 375 info->SetString(kUserNameKey, user_name); |
| 246 // This takes ownership of |info|. | 376 // This takes ownership of |info|. |
| 247 SetInfoForProfileAtIndex(index, info.release()); | 377 SetInfoForProfileAtIndex(index, info.release()); |
| 248 } | 378 } |
| 249 | 379 |
| 250 void ProfileInfoCache::SetAvatarIconOfProfileAtIndex(size_t index, | 380 void ProfileInfoCache::SetAvatarIconOfProfileAtIndex(size_t index, |
| 251 size_t icon_index) { | 381 size_t icon_index) { |
| 252 scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy()); | 382 scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy()); |
| 253 info->SetString(kAvatarIconKey, GetDefaultAvatarIconUrl(icon_index)); | 383 info->SetString(kAvatarIconKey, GetDefaultAvatarIconUrl(icon_index)); |
| 254 // This takes ownership of |info|. | 384 // This takes ownership of |info|. |
| 255 SetInfoForProfileAtIndex(index, info.release()); | 385 SetInfoForProfileAtIndex(index, info.release()); |
| 256 } | 386 } |
| 257 | 387 |
| 258 void ProfileInfoCache::SetBackgroundStatusOfProfileAtIndex( | 388 void ProfileInfoCache::SetBackgroundStatusOfProfileAtIndex( |
| 259 size_t index, | 389 size_t index, |
| 260 bool running_background_apps) { | 390 bool running_background_apps) { |
| 261 if (GetBackgroundStatusOfProfileAtIndex(index) == running_background_apps) | 391 if (GetBackgroundStatusOfProfileAtIndex(index) == running_background_apps) |
| 262 return; | 392 return; |
| 263 scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy()); | 393 scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy()); |
| 264 info->SetBoolean(kBackgroundAppsKey, running_background_apps); | 394 info->SetBoolean(kBackgroundAppsKey, running_background_apps); |
| 265 // This takes ownership of |info|. | 395 // This takes ownership of |info|. |
| 266 SetInfoForProfileAtIndex(index, info.release()); | 396 SetInfoForProfileAtIndex(index, info.release()); |
| 267 } | 397 } |
| 268 | 398 |
| 399 void ProfileInfoCache::SetGAIANameOfProfileAtIndex(size_t index, | |
| 400 const string16& name) { | |
| 401 if (name == GetGAIANameOfProfileAtIndex(index)) | |
| 402 return; | |
| 403 | |
| 404 scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy()); | |
| 405 info->SetString(kGAIANameKey, name); | |
| 406 // This takes ownership of |info|. | |
| 407 SetInfoForProfileAtIndex(index, info.release()); | |
| 408 UpdateSortForProfileIndex(index); | |
| 409 } | |
| 410 | |
| 411 void ProfileInfoCache::SetIsUsingGAIANameOfProfileAtIndex(size_t index, | |
| 412 bool value) { | |
| 413 if (value == IsUsingGAIANameOfProfileAtIndex(index)) | |
| 414 return; | |
| 415 | |
| 416 scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy()); | |
| 417 info->SetBoolean(kUseGAIANameKey, value); | |
| 418 // This takes ownership of |info|. | |
| 419 SetInfoForProfileAtIndex(index, info.release()); | |
| 420 UpdateSortForProfileIndex(index); | |
| 421 } | |
| 422 | |
| 423 void ProfileInfoCache::SetGAIAPictureOfProfileAtIndex(size_t index, | |
| 424 const gfx::Image& image) { | |
| 425 FilePath path = GetPathOfProfileAtIndex(index); | |
| 426 std::string key = CacheKeyFromProfilePath(path); | |
| 427 | |
| 428 delete gaia_pictures_[key]; | |
| 429 gaia_pictures_[key] = new gfx::Image(image); | |
| 430 | |
| 431 FilePath image_path = path.AppendASCII(kGAIAPictureFileName); | |
| 432 bool* success = new bool; | |
| 433 BrowserThread::PostTaskAndReply(BrowserThread::FILE, FROM_HERE, | |
| 434 base::Bind(&SaveBitmap, image, image_path, success), | |
| 435 base::Bind(&ProfileInfoCache::OnGAIAPictureSaved, AsWeakPtr(), path, | |
|
Robert Sesek
2011/11/22 21:26:37
I'd wrap this by breaking before path and aligning
sail
2011/11/22 21:43:23
Done.
| |
| 436 success)); | |
| 437 | |
| 438 content::NotificationService::current()->Notify( | |
| 439 chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, | |
| 440 content::NotificationService::AllSources(), | |
| 441 content::NotificationService::NoDetails()); | |
| 442 } | |
| 443 | |
| 444 void ProfileInfoCache::SetIsUsingGAIAPictureOfProfileAtIndex(size_t index, | |
| 445 bool value) { | |
| 446 scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy()); | |
| 447 info->SetBoolean(kUseGAIAPictureKey, value); | |
| 448 // This takes ownership of |info|. | |
| 449 SetInfoForProfileAtIndex(index, info.release()); | |
| 450 } | |
| 451 | |
| 269 string16 ProfileInfoCache::ChooseNameForNewProfile(size_t icon_index) { | 452 string16 ProfileInfoCache::ChooseNameForNewProfile(size_t icon_index) { |
| 270 string16 name; | 453 string16 name; |
| 271 for (int name_index = 1; ; ++name_index) { | 454 for (int name_index = 1; ; ++name_index) { |
| 272 if (icon_index < kGenericIconCount) { | 455 if (icon_index < kGenericIconCount) { |
| 273 name = l10n_util::GetStringFUTF16Int(IDS_NUMBERED_PROFILE_NAME, | 456 name = l10n_util::GetStringFUTF16Int(IDS_NUMBERED_PROFILE_NAME, |
| 274 name_index); | 457 name_index); |
| 275 } else { | 458 } else { |
| 276 name = l10n_util::GetStringUTF16( | 459 name = l10n_util::GetStringUTF16( |
| 277 kDefaultNames[icon_index - kGenericIconCount]); | 460 kDefaultNames[icon_index - kGenericIconCount]); |
| 278 if (name_index > 1) | 461 if (name_index > 1) |
| 279 name.append(UTF8ToUTF16(base::IntToString(name_index))); | 462 name.append(UTF8ToUTF16(base::IntToString(name_index))); |
| 280 } | 463 } |
| 281 | 464 |
| 282 // Loop through previously named profiles to ensure we're not duplicating. | 465 // Loop through previously named profiles to ensure we're not duplicating. |
| 283 bool name_found = false; | 466 bool name_found = false; |
| 284 for (size_t i = 0; i < GetNumberOfProfiles(); ++i) { | 467 for (size_t i = 0; i < GetNumberOfProfiles(); ++i) { |
| 285 if (GetNameOfProfileAtIndex(i) == name) { | 468 if (GetNameOfProfileAtIndex(i) == name) { |
| 286 name_found = true; | 469 name_found = true; |
| 287 break; | 470 break; |
| 288 } | 471 } |
| 289 } | 472 } |
| 290 if (!name_found) | 473 if (!name_found) |
| 291 return name; | 474 return name; |
| 292 } | 475 } |
| 293 } | 476 } |
| 294 | 477 |
| 478 bool ProfileInfoCache::GetHasMigratedToGAIAInfoOfProfileAtIndex( | |
| 479 size_t index) const { | |
| 480 bool value = false; | |
| 481 GetInfoForProfileAtIndex(index)->GetBoolean( | |
| 482 kHasMigratedToGAIAInfoKey, &value); | |
| 483 return value; | |
| 484 } | |
| 485 | |
| 486 void ProfileInfoCache::SetHasMigratedToGAIAInfoOfProfileAtIndex( | |
| 487 size_t index, bool value) { | |
| 488 scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy()); | |
| 489 info->SetBoolean(kHasMigratedToGAIAInfoKey, value); | |
| 490 // This takes ownership of |info|. | |
| 491 SetInfoForProfileAtIndex(index, info.release()); | |
| 492 } | |
| 493 | |
| 295 bool ProfileInfoCache::IconIndexIsUnique(size_t icon_index) const { | 494 bool ProfileInfoCache::IconIndexIsUnique(size_t icon_index) const { |
| 296 for (size_t i = 0; i < GetNumberOfProfiles(); ++i) { | 495 for (size_t i = 0; i < GetNumberOfProfiles(); ++i) { |
| 297 if (GetAvatarIconIndexOfProfileAtIndex(i) == icon_index) | 496 if (GetAvatarIconIndexOfProfileAtIndex(i) == icon_index) |
| 298 return false; | 497 return false; |
| 299 } | 498 } |
| 300 return true; | 499 return true; |
| 301 } | 500 } |
| 302 | 501 |
| 303 bool ProfileInfoCache::ChooseAvatarIconIndexForNewProfile( | 502 bool ProfileInfoCache::ChooseAvatarIconIndexForNewProfile( |
| 304 bool allow_generic_icon, | 503 bool allow_generic_icon, |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 403 std::string ProfileInfoCache::CacheKeyFromProfilePath( | 602 std::string ProfileInfoCache::CacheKeyFromProfilePath( |
| 404 const FilePath& profile_path) const { | 603 const FilePath& profile_path) const { |
| 405 DCHECK(user_data_dir_ == profile_path.DirName()); | 604 DCHECK(user_data_dir_ == profile_path.DirName()); |
| 406 FilePath base_name = profile_path.BaseName(); | 605 FilePath base_name = profile_path.BaseName(); |
| 407 return base_name.MaybeAsASCII(); | 606 return base_name.MaybeAsASCII(); |
| 408 } | 607 } |
| 409 | 608 |
| 410 std::vector<std::string>::iterator ProfileInfoCache::FindPositionForProfile( | 609 std::vector<std::string>::iterator ProfileInfoCache::FindPositionForProfile( |
| 411 std::string search_key, | 610 std::string search_key, |
| 412 const string16& search_name) { | 611 const string16& search_name) { |
| 612 string16 search_name_l = base::i18n::ToLower(search_name); | |
| 413 for (size_t i = 0; i < GetNumberOfProfiles(); ++i) { | 613 for (size_t i = 0; i < GetNumberOfProfiles(); ++i) { |
| 414 int name_compare = search_name.compare(GetNameOfProfileAtIndex(i)); | 614 string16 name_l = base::i18n::ToLower(GetNameOfProfileAtIndex(i)); |
| 615 int name_compare = search_name_l.compare(name_l); | |
| 415 if (name_compare < 0) | 616 if (name_compare < 0) |
| 416 return sorted_keys_.begin() + i; | 617 return sorted_keys_.begin() + i; |
| 417 if (name_compare == 0) { | 618 if (name_compare == 0) { |
| 418 int key_compare = search_key.compare(sorted_keys_[i]); | 619 int key_compare = search_key.compare(sorted_keys_[i]); |
| 419 if (key_compare < 0) | 620 if (key_compare < 0) |
| 420 return sorted_keys_.begin() + i; | 621 return sorted_keys_.begin() + i; |
| 421 } | 622 } |
| 422 } | 623 } |
| 423 return sorted_keys_.end(); | 624 return sorted_keys_.end(); |
| 424 } | 625 } |
| 425 | 626 |
| 426 void ProfileInfoCache::RegisterPrefs(PrefService* prefs) { | 627 void ProfileInfoCache::RegisterPrefs(PrefService* prefs) { |
| 427 prefs->RegisterDictionaryPref(prefs::kProfileInfoCache); | 628 prefs->RegisterDictionaryPref(prefs::kProfileInfoCache); |
| 428 } | 629 } |
| 630 | |
| 631 void ProfileInfoCache::UpdateSortForProfileIndex(size_t index) { | |
| 632 string16 name = GetNameOfProfileAtIndex(index); | |
| 633 | |
| 634 // Remove and reinsert key in |sorted_keys_| to alphasort. | |
| 635 std::string key = CacheKeyFromProfilePath(GetPathOfProfileAtIndex(index)); | |
| 636 std::vector<std::string>::iterator key_it = | |
| 637 std::find(sorted_keys_.begin(), sorted_keys_.end(), key); | |
| 638 DCHECK(key_it != sorted_keys_.end()); | |
| 639 sorted_keys_.erase(key_it); | |
| 640 sorted_keys_.insert(FindPositionForProfile(key, name), key); | |
| 641 | |
| 642 content::NotificationService::current()->Notify( | |
| 643 chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, | |
| 644 content::NotificationService::AllSources(), | |
| 645 content::NotificationService::NoDetails()); | |
| 646 } | |
| OLD | NEW |