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/file_util.h" |
7 #include "base/format_macros.h" | 8 #include "base/format_macros.h" |
8 #include "base/logging.h" | 9 #include "base/logging.h" |
9 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
10 #include "base/rand_util.h" | 11 #include "base/rand_util.h" |
11 #include "base/string_number_conversions.h" | 12 #include "base/string_number_conversions.h" |
12 #include "base/stringprintf.h" | 13 #include "base/stringprintf.h" |
| 14 #include "base/threading/thread_restrictions.h" |
13 #include "base/utf_string_conversions.h" | 15 #include "base/utf_string_conversions.h" |
14 #include "base/values.h" | 16 #include "base/values.h" |
15 #include "chrome/browser/prefs/pref_service.h" | 17 #include "chrome/browser/prefs/pref_service.h" |
16 #include "chrome/browser/prefs/scoped_user_pref_update.h" | 18 #include "chrome/browser/prefs/scoped_user_pref_update.h" |
17 #include "chrome/common/chrome_notification_types.h" | 19 #include "chrome/common/chrome_notification_types.h" |
18 #include "chrome/common/pref_names.h" | 20 #include "chrome/common/pref_names.h" |
19 #include "content/public/browser/notification_service.h" | 21 #include "content/public/browser/notification_service.h" |
20 #include "grit/generated_resources.h" | 22 #include "grit/generated_resources.h" |
21 #include "grit/theme_resources.h" | 23 #include "grit/theme_resources.h" |
22 #include "ui/base/l10n/l10n_util.h" | 24 #include "ui/base/l10n/l10n_util.h" |
23 #include "ui/base/resource/resource_bundle.h" | 25 #include "ui/base/resource/resource_bundle.h" |
| 26 #include "ui/gfx/codec/png_codec.h" |
| 27 #include "ui/gfx/image/image.h" |
24 | 28 |
25 namespace { | 29 namespace { |
26 | 30 |
27 const char kNameKey[] = "name"; | 31 const char kNameKey[] = "name"; |
| 32 const char kGAIANameKey[] = "test_gaia_name"; |
28 const char kUserNameKey[] = "user_name"; | 33 const char kUserNameKey[] = "user_name"; |
29 const char kAvatarIconKey[] = "avatar_icon"; | 34 const char kAvatarIconKey[] = "avatar_icon"; |
| 35 const char kAvatarIconFileNameKey[] = "test_avatar_icon_file_name"; |
30 const char kBackgroundAppsKey[] = "background_apps"; | 36 const char kBackgroundAppsKey[] = "background_apps"; |
31 const char kDefaultUrlPrefix[] = "chrome://theme/IDR_PROFILE_AVATAR_"; | 37 const char kDefaultUrlPrefix[] = "chrome://theme/IDR_PROFILE_AVATAR_"; |
| 38 const char kIsUsingCustomAvatarIcon[] = "test_is_using_custom_avatar_icon"; |
| 39 const char kIsUsingGAIAName[] = "test_is_using_gaia_name"; |
32 | 40 |
33 const int kDefaultAvatarIconResources[] = { | 41 const int kDefaultAvatarIconResources[] = { |
34 IDR_PROFILE_AVATAR_0, | 42 IDR_PROFILE_AVATAR_0, |
35 IDR_PROFILE_AVATAR_1, | 43 IDR_PROFILE_AVATAR_1, |
36 IDR_PROFILE_AVATAR_2, | 44 IDR_PROFILE_AVATAR_2, |
37 IDR_PROFILE_AVATAR_3, | 45 IDR_PROFILE_AVATAR_3, |
38 IDR_PROFILE_AVATAR_4, | 46 IDR_PROFILE_AVATAR_4, |
39 IDR_PROFILE_AVATAR_5, | 47 IDR_PROFILE_AVATAR_5, |
40 IDR_PROFILE_AVATAR_6, | 48 IDR_PROFILE_AVATAR_6, |
41 IDR_PROFILE_AVATAR_7, | 49 IDR_PROFILE_AVATAR_7, |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 IDS_DEFAULT_AVATAR_NAME_20, | 89 IDS_DEFAULT_AVATAR_NAME_20, |
82 IDS_DEFAULT_AVATAR_NAME_21, | 90 IDS_DEFAULT_AVATAR_NAME_21, |
83 IDS_DEFAULT_AVATAR_NAME_22, | 91 IDS_DEFAULT_AVATAR_NAME_22, |
84 IDS_DEFAULT_AVATAR_NAME_23, | 92 IDS_DEFAULT_AVATAR_NAME_23, |
85 IDS_DEFAULT_AVATAR_NAME_24, | 93 IDS_DEFAULT_AVATAR_NAME_24, |
86 IDS_DEFAULT_AVATAR_NAME_25 | 94 IDS_DEFAULT_AVATAR_NAME_25 |
87 }; | 95 }; |
88 | 96 |
89 } // namespace | 97 } // namespace |
90 | 98 |
| 99 FilePath ProfileInfoCache::GetImagePath(std::string key, |
| 100 string16 file_name) { |
| 101 FilePath::StringType f1; |
| 102 #if defined(OS_POSIX) |
| 103 f1 = key; |
| 104 #elif defined(OS_WIN) |
| 105 f1 = ASCIIToWide(key); |
| 106 #endif |
| 107 |
| 108 FilePath::StringType f2; |
| 109 #if defined(OS_POSIX) |
| 110 f2 = UTF16ToUTF8(file_name); |
| 111 #elif defined(OS_WIN) |
| 112 f2 = file_name; |
| 113 #endif |
| 114 |
| 115 FilePath p = user_data_dir_.Append(f1); |
| 116 return p.Append(f2); |
| 117 } |
| 118 |
| 119 void ProfileInfoCache::ReadBitmap(std::string key, |
| 120 string16 file_name, |
| 121 SkBitmap* bmp) { |
| 122 if (file_name.empty()) |
| 123 return; |
| 124 |
| 125 base::ThreadRestrictions::ScopedAllowIO allow_io; |
| 126 FilePath image_path = GetImagePath(key, file_name); |
| 127 |
| 128 std::string image_data; |
| 129 if (!file_util::ReadFileToString(image_path, &image_data)) { |
| 130 LOG(ERROR) << "Failed to read PNG file from disk."; |
| 131 return; |
| 132 } |
| 133 |
| 134 const unsigned char* data = |
| 135 reinterpret_cast<const unsigned char*>(image_data.data()); |
| 136 SkBitmap image; |
| 137 if (!gfx::PNGCodec::Decode(data, image_data.length(), &image)) { |
| 138 LOG(ERROR) << "Failed to decode PNG file."; |
| 139 return; |
| 140 } |
| 141 |
| 142 *bmp = image; |
| 143 } |
| 144 |
| 145 void ProfileInfoCache::SaveBitmap(std::string key, |
| 146 string16 file_name, |
| 147 const SkBitmap& image) { |
| 148 base::ThreadRestrictions::ScopedAllowIO allow_io; |
| 149 FilePath image_path = GetImagePath(key, file_name); |
| 150 |
| 151 std::vector<unsigned char> encoded_image; |
| 152 if (!gfx::PNGCodec::EncodeBGRASkBitmap(image, true, &encoded_image)) { |
| 153 LOG(ERROR) << "Failed to PNG encode the image."; |
| 154 return; |
| 155 } |
| 156 |
| 157 if (file_util::WriteFile(image_path, |
| 158 reinterpret_cast<char*>(&encoded_image[0]), |
| 159 encoded_image.size()) == -1) { |
| 160 LOG(ERROR) << "Failed to save image to file."; |
| 161 return; |
| 162 } |
| 163 } |
| 164 |
91 ProfileInfoCache::ProfileInfoCache(PrefService* prefs, | 165 ProfileInfoCache::ProfileInfoCache(PrefService* prefs, |
92 const FilePath& user_data_dir) | 166 const FilePath& user_data_dir) |
93 : prefs_(prefs), | 167 : prefs_(prefs), |
94 user_data_dir_(user_data_dir) { | 168 user_data_dir_(user_data_dir) { |
95 // Populate the cache | 169 // Populate the cache |
96 const DictionaryValue* cache = | 170 const DictionaryValue* cache = |
97 prefs_->GetDictionary(prefs::kProfileInfoCache); | 171 prefs_->GetDictionary(prefs::kProfileInfoCache); |
98 for (DictionaryValue::key_iterator it = cache->begin_keys(); | 172 for (DictionaryValue::key_iterator it = cache->begin_keys(); |
99 it != cache->end_keys(); ++it) { | 173 it != cache->end_keys(); ++it) { |
100 std::string key = *it; | 174 std::string key = *it; |
101 DictionaryValue* info = NULL; | 175 DictionaryValue* info = NULL; |
102 cache->GetDictionary(key, &info); | 176 cache->GetDictionary(key, &info); |
103 string16 name; | 177 string16 name; |
104 info->GetString(kNameKey, &name); | 178 info->GetString(kNameKey, &name); |
105 sorted_keys_.insert(FindPositionForProfile(key, name), key); | 179 sorted_keys_.insert(FindPositionForProfile(key, name), key); |
| 180 |
| 181 string16 file_name; |
| 182 info->GetString(kAvatarIconFileNameKey, &file_name); |
| 183 SkBitmap bmp; |
| 184 ReadBitmap(key, UTF8ToUTF16("gaia_picture.png"), &bmp); |
| 185 if (!bmp.isNull()) { |
| 186 bitmaps_[key] = new SkBitmap(bmp); |
| 187 } else { |
| 188 } |
106 } | 189 } |
107 } | 190 } |
108 | 191 |
109 ProfileInfoCache::~ProfileInfoCache() { | 192 ProfileInfoCache::~ProfileInfoCache() { |
110 } | 193 } |
111 | 194 |
112 void ProfileInfoCache::AddProfileToCache(const FilePath& profile_path, | 195 void ProfileInfoCache::AddProfileToCache(const FilePath& profile_path, |
113 const string16& name, | 196 const string16& name, |
114 const string16& username, | 197 const string16& username, |
115 size_t icon_index) { | 198 size_t icon_index) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 return std::string::npos; | 240 return std::string::npos; |
158 std::string search_key = CacheKeyFromProfilePath(profile_path); | 241 std::string search_key = CacheKeyFromProfilePath(profile_path); |
159 for (size_t i = 0; i < sorted_keys_.size(); ++i) { | 242 for (size_t i = 0; i < sorted_keys_.size(); ++i) { |
160 if (sorted_keys_[i] == search_key) | 243 if (sorted_keys_[i] == search_key) |
161 return i; | 244 return i; |
162 } | 245 } |
163 return std::string::npos; | 246 return std::string::npos; |
164 } | 247 } |
165 | 248 |
166 string16 ProfileInfoCache::GetNameOfProfileAtIndex(size_t index) const { | 249 string16 ProfileInfoCache::GetNameOfProfileAtIndex(size_t index) const { |
| 250 if (IsUsinGAIANameForProfileAtIndex(index)) { |
| 251 return GetGAIANameOfProfileAtIndex(index); |
| 252 } else { |
| 253 string16 name; |
| 254 GetInfoForProfileAtIndex(index)->GetString(kNameKey, &name); |
| 255 return name; |
| 256 } |
| 257 } |
| 258 |
| 259 string16 ProfileInfoCache::GetGAIANameOfProfileAtIndex(size_t index) const { |
167 string16 name; | 260 string16 name; |
168 GetInfoForProfileAtIndex(index)->GetString(kNameKey, &name); | 261 GetInfoForProfileAtIndex(index)->GetString(kGAIANameKey, &name); |
169 return name; | 262 return name; |
170 } | 263 } |
171 | 264 |
172 FilePath ProfileInfoCache::GetPathOfProfileAtIndex(size_t index) const { | 265 FilePath ProfileInfoCache::GetPathOfProfileAtIndex(size_t index) const { |
173 FilePath::StringType base_name; | 266 FilePath::StringType base_name; |
174 #if defined(OS_POSIX) | 267 #if defined(OS_POSIX) |
175 base_name = sorted_keys_[index]; | 268 base_name = sorted_keys_[index]; |
176 #elif defined(OS_WIN) | 269 #elif defined(OS_WIN) |
177 base_name = ASCIIToWide(sorted_keys_[index]); | 270 base_name = ASCIIToWide(sorted_keys_[index]); |
178 #endif | 271 #endif |
179 return user_data_dir_.Append(base_name); | 272 return user_data_dir_.Append(base_name); |
180 } | 273 } |
181 | 274 |
182 string16 ProfileInfoCache::GetUserNameOfProfileAtIndex(size_t index) const { | 275 string16 ProfileInfoCache::GetUserNameOfProfileAtIndex(size_t index) const { |
183 string16 user_name; | 276 string16 user_name; |
184 GetInfoForProfileAtIndex(index)->GetString(kUserNameKey, &user_name); | 277 GetInfoForProfileAtIndex(index)->GetString(kUserNameKey, &user_name); |
185 return user_name; | 278 return user_name; |
186 } | 279 } |
187 | 280 |
188 const gfx::Image& ProfileInfoCache::GetAvatarIconOfProfileAtIndex( | 281 gfx::Image ProfileInfoCache::GetAvatarIconOfProfileAtIndex( |
189 size_t index) const { | 282 size_t index) const { |
| 283 if (IsUsingCustomAvatarIconForProfileAtIndex(index)) { |
| 284 SkBitmap bmp = GetGAIAPictureOfProfileAtIndex(index); |
| 285 if (!bmp.isNull()) { |
| 286 return gfx::Image(new SkBitmap(bmp)); |
| 287 } |
| 288 } |
| 289 |
190 int resource_id = GetDefaultAvatarIconResourceIDAtIndex( | 290 int resource_id = GetDefaultAvatarIconResourceIDAtIndex( |
191 GetAvatarIconIndexOfProfileAtIndex(index)); | 291 GetAvatarIconIndexOfProfileAtIndex(index)); |
192 return ResourceBundle::GetSharedInstance().GetImageNamed(resource_id); | 292 return ResourceBundle::GetSharedInstance().GetImageNamed(resource_id); |
193 } | 293 } |
194 | 294 |
| 295 SkBitmap ProfileInfoCache::GetGAIAPictureOfProfileAtIndex( |
| 296 size_t index) const { |
| 297 std::string key = CacheKeyFromProfilePath(GetPathOfProfileAtIndex(index)); |
| 298 const SkBitmap* bitmap = bitmaps_[key]; |
| 299 if (bitmap) |
| 300 return *bitmap; |
| 301 return SkBitmap(); |
| 302 } |
| 303 |
195 bool ProfileInfoCache::GetBackgroundStatusOfProfileAtIndex( | 304 bool ProfileInfoCache::GetBackgroundStatusOfProfileAtIndex( |
196 size_t index) const { | 305 size_t index) const { |
197 bool background_app_status; | 306 bool background_app_status; |
198 GetInfoForProfileAtIndex(index)->GetBoolean(kBackgroundAppsKey, | 307 GetInfoForProfileAtIndex(index)->GetBoolean(kBackgroundAppsKey, |
199 &background_app_status); | 308 &background_app_status); |
200 return background_app_status; | 309 return background_app_status; |
201 } | 310 } |
202 | 311 |
203 size_t ProfileInfoCache::GetAvatarIconIndexOfProfileAtIndex(size_t index) | 312 size_t ProfileInfoCache::GetAvatarIconIndexOfProfileAtIndex(size_t index) |
204 const { | 313 const { |
(...skipping 21 matching lines...) Expand all Loading... |
226 DCHECK(key_it != sorted_keys_.end()); | 335 DCHECK(key_it != sorted_keys_.end()); |
227 sorted_keys_.erase(key_it); | 336 sorted_keys_.erase(key_it); |
228 sorted_keys_.insert(FindPositionForProfile(key, name), key); | 337 sorted_keys_.insert(FindPositionForProfile(key, name), key); |
229 | 338 |
230 content::NotificationService::current()->Notify( | 339 content::NotificationService::current()->Notify( |
231 chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, | 340 chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, |
232 content::NotificationService::AllSources(), | 341 content::NotificationService::AllSources(), |
233 content::NotificationService::NoDetails()); | 342 content::NotificationService::NoDetails()); |
234 } | 343 } |
235 | 344 |
| 345 void ProfileInfoCache::SetGAIANameOfProfileAtIndex(size_t index, |
| 346 const string16& name) { |
| 347 scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy()); |
| 348 info->SetString(kGAIANameKey, name); |
| 349 // This takes ownership of |info|. |
| 350 SetInfoForProfileAtIndex(index, info.release()); |
| 351 } |
| 352 |
236 void ProfileInfoCache::SetUserNameOfProfileAtIndex(size_t index, | 353 void ProfileInfoCache::SetUserNameOfProfileAtIndex(size_t index, |
237 const string16& user_name) { | 354 const string16& user_name) { |
238 scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy()); | 355 scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy()); |
239 info->SetString(kUserNameKey, user_name); | 356 info->SetString(kUserNameKey, user_name); |
240 // This takes ownership of |info|. | 357 // This takes ownership of |info|. |
241 SetInfoForProfileAtIndex(index, info.release()); | 358 SetInfoForProfileAtIndex(index, info.release()); |
242 } | 359 } |
243 | 360 |
| 361 bool ProfileInfoCache::IsUsingCustomAvatarIconForProfileAtIndex( |
| 362 size_t index) const { |
| 363 if (GetUserNameOfProfileAtIndex(index).empty()) { |
| 364 return false; |
| 365 } |
| 366 |
| 367 bool is_custom = false; |
| 368 GetInfoForProfileAtIndex(index)->GetBoolean(kIsUsingCustomAvatarIcon, |
| 369 &is_custom); |
| 370 return is_custom; |
| 371 } |
| 372 |
| 373 void ProfileInfoCache::SetIsUsingCustomAvatarIconForProfileAtIndex( |
| 374 size_t index, bool value) { |
| 375 scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy()); |
| 376 info->SetBoolean(kIsUsingCustomAvatarIcon, value); |
| 377 // This takes ownership of |info|. |
| 378 SetInfoForProfileAtIndex(index, info.release()); |
| 379 } |
| 380 |
| 381 bool ProfileInfoCache::IsUsinGAIANameForProfileAtIndex( |
| 382 size_t index) const { |
| 383 if (GetUserNameOfProfileAtIndex(index).empty()) { |
| 384 return false; |
| 385 } |
| 386 |
| 387 bool is_custom = false; |
| 388 GetInfoForProfileAtIndex(index)->GetBoolean(kIsUsingGAIAName, &is_custom); |
| 389 return is_custom; |
| 390 } |
| 391 |
| 392 void ProfileInfoCache::SetIsUsingGAIANameForProfileAtIndex( |
| 393 size_t index, bool value) { |
| 394 scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy()); |
| 395 info->SetBoolean(kIsUsingGAIAName, value); |
| 396 // This takes ownership of |info|. |
| 397 SetInfoForProfileAtIndex(index, info.release()); |
| 398 } |
| 399 |
| 400 |
| 401 |
244 void ProfileInfoCache::SetAvatarIconOfProfileAtIndex(size_t index, | 402 void ProfileInfoCache::SetAvatarIconOfProfileAtIndex(size_t index, |
245 size_t icon_index) { | 403 size_t icon_index) { |
246 scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy()); | 404 scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy()); |
247 info->SetString(kAvatarIconKey, GetDefaultAvatarIconUrl(icon_index)); | 405 info->SetString(kAvatarIconKey, GetDefaultAvatarIconUrl(icon_index)); |
248 // This takes ownership of |info|. | 406 // This takes ownership of |info|. |
249 SetInfoForProfileAtIndex(index, info.release()); | 407 SetInfoForProfileAtIndex(index, info.release()); |
250 } | 408 } |
251 | 409 |
| 410 void ProfileInfoCache::SetGAIAPictureOfProfileAtIndex( |
| 411 size_t index, const SkBitmap& bitmap) { |
| 412 std::string key = CacheKeyFromProfilePath(GetPathOfProfileAtIndex(index)); |
| 413 bitmaps_[key] = new SkBitmap(bitmap); |
| 414 SaveBitmap(key, UTF8ToUTF16("gaia_picture.png"), bitmap); |
| 415 |
| 416 content::NotificationService::current()->Notify( |
| 417 chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, |
| 418 content::NotificationService::AllSources(), |
| 419 content::NotificationService::NoDetails()); |
| 420 } |
| 421 |
252 void ProfileInfoCache::SetBackgroundStatusOfProfileAtIndex( | 422 void ProfileInfoCache::SetBackgroundStatusOfProfileAtIndex( |
253 size_t index, | 423 size_t index, |
254 bool running_background_apps) { | 424 bool running_background_apps) { |
255 if (GetBackgroundStatusOfProfileAtIndex(index) == running_background_apps) | 425 if (GetBackgroundStatusOfProfileAtIndex(index) == running_background_apps) |
256 return; | 426 return; |
257 scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy()); | 427 scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy()); |
258 info->SetBoolean(kBackgroundAppsKey, running_background_apps); | 428 info->SetBoolean(kBackgroundAppsKey, running_background_apps); |
259 // This takes ownership of |info|. | 429 // This takes ownership of |info|. |
260 SetInfoForProfileAtIndex(index, info.release()); | 430 SetInfoForProfileAtIndex(index, info.release()); |
261 } | 431 } |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
413 if (key_compare < 0) | 583 if (key_compare < 0) |
414 return sorted_keys_.begin() + i; | 584 return sorted_keys_.begin() + i; |
415 } | 585 } |
416 } | 586 } |
417 return sorted_keys_.end(); | 587 return sorted_keys_.end(); |
418 } | 588 } |
419 | 589 |
420 void ProfileInfoCache::RegisterPrefs(PrefService* prefs) { | 590 void ProfileInfoCache::RegisterPrefs(PrefService* prefs) { |
421 prefs->RegisterDictionaryPref(prefs::kProfileInfoCache); | 591 prefs->RegisterDictionaryPref(prefs::kProfileInfoCache); |
422 } | 592 } |
OLD | NEW |