Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(458)

Side by Side Diff: chrome/browser/profiles/profile_info_cache.cc

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

Powered by Google App Engine
This is Rietveld 408576698