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 |