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