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