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

Side by Side Diff: chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.cc

Issue 2537713002: Add support for transparent/translucent pixels in the user image (Closed)
Patch Set: Add support for transparent/translucent pixels in the user image Created 4 years 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/chromeos/login/users/avatar/user_image_manager_impl.h" 5 #include "chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/files/file_path.h" 12 #include "base/files/file_path.h"
13 #include "base/files/file_util.h" 13 #include "base/files/file_util.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/macros.h" 15 #include "base/macros.h"
16 #include "base/memory/ptr_util.h" 16 #include "base/memory/ptr_util.h"
17 #include "base/metrics/histogram_macros.h" 17 #include "base/metrics/histogram_macros.h"
18 #include "base/path_service.h" 18 #include "base/path_service.h"
19 #include "base/rand_util.h" 19 #include "base/rand_util.h"
20 #include "base/sequenced_task_runner.h" 20 #include "base/sequenced_task_runner.h"
21 #include "base/strings/string_util.h"
21 #include "base/task_runner_util.h" 22 #include "base/task_runner_util.h"
22 #include "base/threading/sequenced_worker_pool.h" 23 #include "base/threading/sequenced_worker_pool.h"
23 #include "base/threading/thread_task_runner_handle.h" 24 #include "base/threading/thread_task_runner_handle.h"
24 #include "base/time/time.h" 25 #include "base/time/time.h"
25 #include "base/trace_event/trace_event.h" 26 #include "base/trace_event/trace_event.h"
26 #include "base/values.h" 27 #include "base/values.h"
27 #include "chrome/browser/browser_process.h" 28 #include "chrome/browser/browser_process.h"
28 #include "chrome/browser/chrome_notification_types.h" 29 #include "chrome/browser/chrome_notification_types.h"
29 #include "chrome/browser/chromeos/login/helper.h" 30 #include "chrome/browser/chromeos/login/helper.h"
30 #include "chrome/browser/chromeos/login/users/avatar/user_image_loader.h" 31 #include "chrome/browser/chromeos/login/users/avatar/user_image_loader.h"
(...skipping 21 matching lines...) Expand all
52 53
53 // Delay betweeen user login and attempt to update user's profile data. 54 // Delay betweeen user login and attempt to update user's profile data.
54 const int kProfileDataDownloadDelaySec = 10; 55 const int kProfileDataDownloadDelaySec = 10;
55 56
56 // Interval betweeen retries to update user's profile data. 57 // Interval betweeen retries to update user's profile data.
57 const int kProfileDataDownloadRetryIntervalSec = 300; 58 const int kProfileDataDownloadRetryIntervalSec = 300;
58 59
59 // Delay betweeen subsequent profile refresh attempts (24 hrs). 60 // Delay betweeen subsequent profile refresh attempts (24 hrs).
60 const int kProfileRefreshIntervalSec = 24 * 3600; 61 const int kProfileRefreshIntervalSec = 24 * 3600;
61 62
62 const char kSafeImagePathExtension[] = ".jpg";
63
64 // Enum for reporting histograms about profile picture download. 63 // Enum for reporting histograms about profile picture download.
65 enum ProfileDownloadResult { 64 enum ProfileDownloadResult {
66 kDownloadSuccessChanged, 65 kDownloadSuccessChanged,
67 kDownloadSuccess, 66 kDownloadSuccess,
68 kDownloadFailure, 67 kDownloadFailure,
69 kDownloadDefault, 68 kDownloadDefault,
70 kDownloadCached, 69 kDownloadCached,
71 70
72 // Must be the last, convenient count. 71 // Must be the last, convenient count.
73 kDownloadResultsCount 72 kDownloadResultsCount
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 base::WriteFile(image_path, 154 base::WriteFile(image_path,
156 reinterpret_cast<const char*>(image_bytes->front()), 155 reinterpret_cast<const char*>(image_bytes->front()),
157 image_bytes->size()) == -1) { 156 image_bytes->size()) == -1) {
158 LOG(ERROR) << "Failed to save image to file."; 157 LOG(ERROR) << "Failed to save image to file.";
159 return false; 158 return false;
160 } 159 }
161 160
162 return true; 161 return true;
163 } 162 }
164 163
164 // Returns the robust codec enum for the given image path's extension.
165 // The user image is always stored in either JPEG or PNG.
166 ImageDecoder::ImageCodec ChooseRobustCodecFromPath(
167 const base::FilePath& image_path) {
168 const std::string utf8_path = image_path.AsUTF8Unsafe();
169 if (base::EndsWith(utf8_path, ".jpg", base::CompareCase::INSENSITIVE_ASCII))
xiyuan 2016/11/30 00:04:22 nit: image_path.Extension() == FILE_PATH_LITERAL("
satorux1 2016/12/01 07:43:36 Good idea. Wanted to make it case-insensitive but
170 return ImageDecoder::ROBUST_JPEG_CODEC;
171 if (base::EndsWith(utf8_path, ".png", base::CompareCase::INSENSITIVE_ASCII))
172 return ImageDecoder::ROBUST_PNG_CODEC;
173
174 NOTREACHED() << "Invalid path: " << image_path.AsUTF8Unsafe();
175 return ImageDecoder::ROBUST_JPEG_CODEC;
176 }
177
178 // Returns the suffix for the given image format, that should be JPEG or PNG.
179 const char* ChooseExtensionFromImageFormat(
180 user_manager::UserImage::ImageFormat image_format) {
181 switch (image_format) {
182 case user_manager::UserImage::FORMAT_JPEG:
183 return ".jpg";
184 case user_manager::UserImage::FORMAT_PNG:
185 return ".png";
186 default:
187 NOTREACHED() << "Invalid format: " << image_format;
188 return ".jpg";
189 }
190 }
191
165 } // namespace 192 } // namespace
166 193
167 const char UserImageManagerImpl::kUserImageProperties[] = "user_image_info"; 194 const char UserImageManagerImpl::kUserImageProperties[] = "user_image_info";
168 const char UserImageManagerImpl::kImagePathNodeName[] = "path"; 195 const char UserImageManagerImpl::kImagePathNodeName[] = "path";
169 const char UserImageManagerImpl::kImageIndexNodeName[] = "index"; 196 const char UserImageManagerImpl::kImageIndexNodeName[] = "index";
170 const char UserImageManagerImpl::kImageURLNodeName[] = "url"; 197 const char UserImageManagerImpl::kImageURLNodeName[] = "url";
171 198
172 // static 199 // static
173 void UserImageManager::RegisterPrefs(PrefRegistrySimple* registry) { 200 void UserImageManager::RegisterPrefs(PrefRegistrySimple* registry) {
174 registry->RegisterDictionaryPref(UserImageManagerImpl::kUserImageProperties); 201 registry->RegisterDictionaryPref(UserImageManagerImpl::kUserImageProperties);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 std::unique_ptr<user_manager::UserImage> user_image); 253 std::unique_ptr<user_manager::UserImage> user_image);
227 254
228 // Updates the user object with |user_image|. 255 // Updates the user object with |user_image|.
229 void UpdateUser(std::unique_ptr<user_manager::UserImage> user_image); 256 void UpdateUser(std::unique_ptr<user_manager::UserImage> user_image);
230 257
231 // Updates the user object with |user_image|, and saves the image 258 // Updates the user object with |user_image|, and saves the image
232 // bytes. Local state will be updated as needed. 259 // bytes. Local state will be updated as needed.
233 void UpdateUserAndSaveImage( 260 void UpdateUserAndSaveImage(
234 std::unique_ptr<user_manager::UserImage> user_image); 261 std::unique_ptr<user_manager::UserImage> user_image);
235 262
236 // Saves |image_bytes| to disk in JPEG format if 263 // Saves |image_bytes| to disk in |image_format| if
237 // |image_is_safe_format|. Local state will be updated as needed. 264 // |image_is_safe_format|. Local state will be updated as needed.
238 void SaveImageAndUpdateLocalState( 265 void SaveImageAndUpdateLocalState(
239 bool image_is_safe_format, 266 bool image_is_safe_format,
240 scoped_refptr<base::RefCountedBytes> image_bytes); 267 scoped_refptr<base::RefCountedBytes> image_bytes,
268 user_manager::UserImage::ImageFormat image_format);
241 269
242 // Called back after the user image has been saved to 270 // Called back after the user image has been saved to
243 // disk. Updates the user image information in local state. The 271 // disk. Updates the user image information in local state. The
244 // information is only updated if |success| is true (indicating that 272 // information is only updated if |success| is true (indicating that
245 // the image was saved successfully) or the user image is the 273 // the image was saved successfully) or the user image is the
246 // profile image (indicating that even if the image could not be 274 // profile image (indicating that even if the image could not be
247 // saved because it is not available right now, it will be 275 // saved because it is not available right now, it will be
248 // downloaded eventually). 276 // downloaded eventually).
249 void OnSaveImageDone(bool success); 277 void OnSaveImageDone(bool success);
250 278
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 image_index_ < default_user_image::kDefaultImagesCount) { 323 image_index_ < default_user_image::kDefaultImagesCount) {
296 // Load one of the default images. This happens synchronously. 324 // Load one of the default images. This happens synchronously.
297 std::unique_ptr<user_manager::UserImage> user_image( 325 std::unique_ptr<user_manager::UserImage> user_image(
298 new user_manager::UserImage( 326 new user_manager::UserImage(
299 default_user_image::GetDefaultImage(image_index_))); 327 default_user_image::GetDefaultImage(image_index_)));
300 UpdateUser(std::move(user_image)); 328 UpdateUser(std::move(user_image));
301 NotifyJobDone(); 329 NotifyJobDone();
302 } else if (image_index_ == user_manager::User::USER_IMAGE_EXTERNAL || 330 } else if (image_index_ == user_manager::User::USER_IMAGE_EXTERNAL ||
303 image_index_ == user_manager::User::USER_IMAGE_PROFILE) { 331 image_index_ == user_manager::User::USER_IMAGE_PROFILE) {
304 // Load the user image from a file referenced by |image_path|. This happens 332 // Load the user image from a file referenced by |image_path|. This happens
305 // asynchronously. ROBUST_JPEG_CODEC can be used here because 333 // asynchronously. ROBUST_JPEG_CODEC or ROBUST_PNG_CODEC can be used here
306 // LoadImage() is called only for users whose user image has previously 334 // because LoadImage() is called only for users whose user image has
307 // been set by one of the Set*() methods, which transcode to JPEG format. 335 // previously been set by one of the Set*() methods, which transcode to
336 // JPEG or PNG format.
308 DCHECK(!image_path_.empty()); 337 DCHECK(!image_path_.empty());
309 user_image_loader::StartWithFilePath( 338 user_image_loader::StartWithFilePath(
310 parent_->background_task_runner_, image_path_, 339 parent_->background_task_runner_, image_path_,
311 ImageDecoder::ROBUST_JPEG_CODEC, 340 ChooseRobustCodecFromPath(image_path_),
312 0, // Do not crop. 341 0, // Do not crop.
313 base::Bind(&Job::OnLoadImageDone, weak_factory_.GetWeakPtr(), false)); 342 base::Bind(&Job::OnLoadImageDone, weak_factory_.GetWeakPtr(), false));
314 } else { 343 } else {
315 NOTREACHED(); 344 NOTREACHED();
316 NotifyJobDone(); 345 NotifyJobDone();
317 } 346 }
318 } 347 }
319 348
320 void UserImageManagerImpl::Job::SetToDefaultImage(int default_image_index) { 349 void UserImageManagerImpl::Job::SetToDefaultImage(int default_image_index) {
321 DCHECK(!run_); 350 DCHECK(!run_);
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 parent_->OnJobChangedUserImage(); 448 parent_->OnJobChangedUserImage();
420 } 449 }
421 450
422 void UserImageManagerImpl::Job::UpdateUserAndSaveImage( 451 void UserImageManagerImpl::Job::UpdateUserAndSaveImage(
423 std::unique_ptr<user_manager::UserImage> user_image) { 452 std::unique_ptr<user_manager::UserImage> user_image) {
424 const bool image_is_safe_format = user_image->is_safe_format(); 453 const bool image_is_safe_format = user_image->is_safe_format();
425 // Create a reference before user_image is passed. 454 // Create a reference before user_image is passed.
426 scoped_refptr<base::RefCountedBytes> image_bytes; 455 scoped_refptr<base::RefCountedBytes> image_bytes;
427 if (image_is_safe_format) 456 if (image_is_safe_format)
428 image_bytes = user_image->image_bytes(); 457 image_bytes = user_image->image_bytes();
458 const user_manager::UserImage::ImageFormat image_format =
459 user_image->image_format();
429 460
430 UpdateUser(std::move(user_image)); 461 UpdateUser(std::move(user_image));
431 462
432 SaveImageAndUpdateLocalState(image_is_safe_format, image_bytes); 463 SaveImageAndUpdateLocalState(image_is_safe_format, image_bytes, image_format);
433 } 464 }
434 465
435 void UserImageManagerImpl::Job::SaveImageAndUpdateLocalState( 466 void UserImageManagerImpl::Job::SaveImageAndUpdateLocalState(
436 bool image_is_safe_format, 467 bool image_is_safe_format,
437 scoped_refptr<base::RefCountedBytes> image_bytes) { 468 scoped_refptr<base::RefCountedBytes> image_bytes,
469 user_manager::UserImage::ImageFormat image_format) {
438 base::FilePath user_data_dir; 470 base::FilePath user_data_dir;
439 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); 471 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
440 image_path_ = user_data_dir.Append(user_id() + kSafeImagePathExtension); 472 image_path_ = user_data_dir.AppendASCII(
473 user_id() + ChooseExtensionFromImageFormat(image_format));
441 474
442 // This should always be true, because of the following reasons: 475 // This should always be true, because of the following reasons:
443 // 476 //
444 // 1) Profile image from Google account -> UserImage is created with 477 // 1) Profile image from Google account -> UserImage is created with
445 // CreateAndEncode() that generates safe bytes representation. 478 // CreateAndEncode() that generates safe bytes representation.
446 // 2) Profile image from user-specified image -> The bytes representation 479 // 2) Profile image from user-specified image -> The bytes representation
447 // is regenerated after the original image is decoded and cropped. 480 // is regenerated after the original image is decoded and cropped.
448 // 3) Profile image from policy (via OnExternalDataFetched()) -> JPEG is 481 // 3) Profile image from policy (via OnExternalDataFetched()) -> JPEG is
449 // only allowed and ROBUST_JPEG_CODEC is used. 482 // only allowed and ROBUST_JPEG_CODEC is used.
450 // 483 //
451 // However, check the value just in case because an unsafe image should 484 // However, check the value just in case because an unsafe image should
452 // never be saved. 485 // never be saved.
453 if (!image_is_safe_format) { 486 if (!image_is_safe_format) {
454 LOG(ERROR) << "User image is not in safe format"; 487 LOG(ERROR) << "User image is not in safe format";
455 OnSaveImageDone(false); 488 OnSaveImageDone(false);
456 return; 489 return;
457 } 490 }
458 491
459 base::PostTaskAndReplyWithResult( 492 base::PostTaskAndReplyWithResult(
460 parent_->background_task_runner_.get(), FROM_HERE, 493 parent_->background_task_runner_.get(), FROM_HERE,
461 base::Bind(&SaveImage, image_bytes, image_path_), 494 base::Bind(&SaveImage, image_bytes, image_path_),
462 base::Bind(&Job::OnSaveImageDone, weak_factory_.GetWeakPtr())); 495 base::Bind(&Job::OnSaveImageDone, weak_factory_.GetWeakPtr()));
463 } 496 }
464 497
465 void UserImageManagerImpl::Job::OnSaveImageDone(bool success) { 498 void UserImageManagerImpl::Job::OnSaveImageDone(bool success) {
466 if (success || image_index_ == user_manager::User::USER_IMAGE_PROFILE) 499 if (success || image_index_ == user_manager::User::USER_IMAGE_PROFILE) {
500 // Remove the old image file if the path is different. This can happen if
achuithb 2016/11/30 00:26:48 Should this code be browser tested?
satorux1 2016/12/01 07:43:36 Thank you for pointing this out! I've just added a
501 // the user image format is changed from JPEG to PNG or vice versa.
502 PrefService* local_state = g_browser_process->local_state();
503 // Because the user ID (i.e. email address) contains '.', the code here
504 // cannot use the dots notation (path expantion) hence is verbose.
505 const base::DictionaryValue* prefs_images =
506 local_state->GetDictionary(kUserImageProperties);
507 if (prefs_images) {
508 const base::DictionaryValue* image_properties = nullptr;
509 prefs_images->GetDictionaryWithoutPathExpansion(user_id(),
510 &image_properties);
511 if (image_properties) {
512 std::string value;
513 image_properties->GetString(kImagePathNodeName, &value);
514 const base::FilePath original_path =
515 base::FilePath::FromUTF8Unsafe(value);
516 if (!original_path.empty() && original_path != image_path_) {
517 parent_->background_task_runner_->PostTask(
518 FROM_HERE, base::Bind(base::IgnoreResult(&base::DeleteFile),
519 base::FilePath(original_path), false));
520 }
521 }
522 }
523
467 UpdateLocalState(); 524 UpdateLocalState();
525 }
468 NotifyJobDone(); 526 NotifyJobDone();
469 } 527 }
470 528
471 void UserImageManagerImpl::Job::UpdateLocalState() { 529 void UserImageManagerImpl::Job::UpdateLocalState() {
472 // Ignore if data stored or cached outside the user's cryptohome is to be 530 // Ignore if data stored or cached outside the user's cryptohome is to be
473 // treated as ephemeral. 531 // treated as ephemeral.
474 if (parent_->user_manager_->IsUserNonCryptohomeDataEphemeral( 532 if (parent_->user_manager_->IsUserNonCryptohomeDataEphemeral(
475 AccountId::FromUserEmail(user_id()))) 533 AccountId::FromUserEmail(user_id())))
476 return; 534 return;
477 535
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 UserImageManagerImpl::~UserImageManagerImpl() {} 569 UserImageManagerImpl::~UserImageManagerImpl() {}
512 570
513 void UserImageManagerImpl::LoadUserImage() { 571 void UserImageManagerImpl::LoadUserImage() {
514 PrefService* local_state = g_browser_process->local_state(); 572 PrefService* local_state = g_browser_process->local_state();
515 const base::DictionaryValue* prefs_images = 573 const base::DictionaryValue* prefs_images =
516 local_state->GetDictionary(kUserImageProperties); 574 local_state->GetDictionary(kUserImageProperties);
517 if (!prefs_images) 575 if (!prefs_images)
518 return; 576 return;
519 user_manager::User* user = GetUserAndModify(); 577 user_manager::User* user = GetUserAndModify();
520 578
521 const base::DictionaryValue* image_properties = NULL; 579 const base::DictionaryValue* image_properties = nullptr;
522 prefs_images->GetDictionaryWithoutPathExpansion(user_id(), &image_properties); 580 prefs_images->GetDictionaryWithoutPathExpansion(user_id(), &image_properties);
523 581
524 // If the user image for |user_id| is managed by policy and the policy-set 582 // If the user image for |user_id| is managed by policy and the policy-set
525 // image is being loaded and persisted right now, let that job continue. It 583 // image is being loaded and persisted right now, let that job continue. It
526 // will update the user image when done. 584 // will update the user image when done.
527 if (IsUserImageManaged() && job_.get()) 585 if (IsUserImageManaged() && job_.get())
528 return; 586 return;
529 587
530 if (!image_properties) { 588 if (!image_properties) {
531 SetInitialUserImage(); 589 SetInitialUserImage();
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 return; 698 return;
641 job_.reset(new Job(this)); 699 job_.reset(new Job(this));
642 job_->SetToPath(path, user_manager::User::USER_IMAGE_EXTERNAL, GURL(), true); 700 job_->SetToPath(path, user_manager::User::USER_IMAGE_EXTERNAL, GURL(), true);
643 } 701 }
644 702
645 void UserImageManagerImpl::SaveUserImageFromProfileImage() { 703 void UserImageManagerImpl::SaveUserImageFromProfileImage() {
646 if (IsUserImageManaged()) 704 if (IsUserImageManaged())
647 return; 705 return;
648 // Use the profile image if it has been downloaded already. Otherwise, use a 706 // Use the profile image if it has been downloaded already. Otherwise, use a
649 // stub image (gray avatar). 707 // stub image (gray avatar).
708 std::unique_ptr<user_manager::UserImage> user_image;
709 if (downloaded_profile_image_.isNull()) {
710 user_image = base::WrapUnique(new user_manager::UserImage);
711 } else {
712 user_image = user_manager::UserImage::CreateAndEncode(
713 downloaded_profile_image_, user_manager::UserImage::ChooseImageFormat(
714 *downloaded_profile_image_.bitmap()));
715 }
650 job_.reset(new Job(this)); 716 job_.reset(new Job(this));
651 job_->SetToImage(user_manager::User::USER_IMAGE_PROFILE, 717 job_->SetToImage(user_manager::User::USER_IMAGE_PROFILE,
652 downloaded_profile_image_.isNull() 718 std::move(user_image));
653 ? base::WrapUnique(new user_manager::UserImage)
654 : user_manager::UserImage::CreateAndEncode(
655 downloaded_profile_image_));
656 // If no profile image has been downloaded yet, ensure that a download is 719 // If no profile image has been downloaded yet, ensure that a download is
657 // started. 720 // started.
658 if (downloaded_profile_image_.isNull()) 721 if (downloaded_profile_image_.isNull())
659 DownloadProfileData(kProfileDownloadReasonProfileImageChosen); 722 DownloadProfileData(kProfileDownloadReasonProfileImageChosen);
660 } 723 }
661 724
662 void UserImageManagerImpl::DeleteUserImage() { 725 void UserImageManagerImpl::DeleteUserImage() {
663 job_.reset(); 726 job_.reset();
664 DeleteUserImageAndLocalStateEntry(kUserImageProperties); 727 DeleteUserImageAndLocalStateEntry(kUserImageProperties);
665 } 728 }
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
910 973
911 std::string image_path; 974 std::string image_path;
912 image_properties->GetString(kImagePathNodeName, &image_path); 975 image_properties->GetString(kImagePathNodeName, &image_path);
913 if (!image_path.empty()) { 976 if (!image_path.empty()) {
914 background_task_runner_->PostTask( 977 background_task_runner_->PostTask(
915 FROM_HERE, 978 FROM_HERE,
916 base::Bind(base::IgnoreResult(&base::DeleteFile), 979 base::Bind(base::IgnoreResult(&base::DeleteFile),
917 base::FilePath(image_path), 980 base::FilePath(image_path),
918 false)); 981 false));
919 } 982 }
920 update->RemoveWithoutPathExpansion(user_id(), NULL); 983 update->RemoveWithoutPathExpansion(user_id(), nullptr);
921 } 984 }
922 985
923 void UserImageManagerImpl::OnJobChangedUserImage() { 986 void UserImageManagerImpl::OnJobChangedUserImage() {
924 if (GetUser()->is_logged_in()) 987 if (GetUser()->is_logged_in())
925 TryToInitDownloadedProfileImage(); 988 TryToInitDownloadedProfileImage();
926 989
927 content::NotificationService::current()->Notify( 990 content::NotificationService::current()->Notify(
928 chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED, 991 chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED,
929 content::Source<UserImageManagerImpl>(this), 992 content::Source<UserImageManagerImpl>(this),
930 content::Details<const user_manager::User>(GetUser())); 993 content::Details<const user_manager::User>(GetUser()));
(...skipping 26 matching lines...) Expand all
957 } 1020 }
958 1021
959 bool UserImageManagerImpl::IsUserLoggedInAndHasGaiaAccount() const { 1022 bool UserImageManagerImpl::IsUserLoggedInAndHasGaiaAccount() const {
960 const user_manager::User* user = GetUser(); 1023 const user_manager::User* user = GetUser();
961 if (!user) 1024 if (!user)
962 return false; 1025 return false;
963 return user->is_logged_in() && user->HasGaiaAccount(); 1026 return user->is_logged_in() && user->HasGaiaAccount();
964 } 1027 }
965 1028
966 } // namespace chromeos 1029 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698