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 |