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

Side by Side Diff: chrome/browser/chromeos/login/user_manager.cc

Issue 8541002: [cros] Initial user image loading and repeated profile image loading fixes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Whitespace 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/chromeos/login/user_manager.h" 5 #include "chrome/browser/chromeos/login/user_manager.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/compiler_specific.h" 9 #include "base/compiler_specific.h"
10 #include "base/file_path.h" 10 #include "base/file_path.h"
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 // depends on that and it's hard to figure out what). 69 // depends on that and it's hard to figure out what).
70 const char kGuestUser[] = ""; 70 const char kGuestUser[] = "";
71 71
72 // Stub user email (for test paths). 72 // Stub user email (for test paths).
73 const char kStubUser[] = "stub-user@example.com"; 73 const char kStubUser[] = "stub-user@example.com";
74 74
75 // Names of nodes with info about user image. 75 // Names of nodes with info about user image.
76 const char kImagePathNodeName[] = "path"; 76 const char kImagePathNodeName[] = "path";
77 const char kImageIndexNodeName[] = "index"; 77 const char kImageIndexNodeName[] = "index";
78 78
79 // Index of the default image used as stub while the real user image is loading
80 // from file and for the |kStubUser| user.
81 const int kStubDefaultImageIndex = 0;
82
79 // Delay betweeen user login and attempt to update user's profile image. 83 // Delay betweeen user login and attempt to update user's profile image.
80 const long kProfileImageDownloadDelayMs = 10000; 84 const long kProfileImageDownloadDelayMs = 10000;
81 85
82 base::LazyInstance<UserManager> g_user_manager(base::LINKER_INITIALIZED); 86 base::LazyInstance<UserManager> g_user_manager(base::LINKER_INITIALIZED);
83 87
84 // Used to handle the asynchronous response of deleting a cryptohome directory. 88 // Used to handle the asynchronous response of deleting a cryptohome directory.
85 class RemoveAttempt : public CryptohomeLibrary::Delegate { 89 class RemoveAttempt : public CryptohomeLibrary::Delegate {
86 public: 90 public:
87 // Creates new remove attempt for the given user. Note, |delegate| can 91 // Creates new remove attempt for the given user. Note, |delegate| can
88 // be NULL. 92 // be NULL.
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 return static_cast<User::OAuthTokenStatus>(oauth_token_status); 414 return static_cast<User::OAuthTokenStatus>(oauth_token_status);
411 } 415 }
412 } 416 }
413 417
414 return User::OAUTH_TOKEN_STATUS_UNKNOWN; 418 return User::OAUTH_TOKEN_STATUS_UNKNOWN;
415 } 419 }
416 420
417 void UserManager::SaveUserDefaultImageIndex(const std::string& username, 421 void UserManager::SaveUserDefaultImageIndex(const std::string& username,
418 int image_index) { 422 int image_index) {
419 DCHECK(image_index >= 0 && image_index < kDefaultImagesCount); 423 DCHECK(image_index >= 0 && image_index < kDefaultImagesCount);
420 SetUserImage(username, image_index, 424 SetUserImage(username, image_index, GetDefaultImage(image_index));
421 *ResourceBundle::GetSharedInstance().
422 GetBitmapNamed(kDefaultImageResources[image_index]));
423 SaveImageToLocalState(username, "", image_index, false); 425 SaveImageToLocalState(username, "", image_index, false);
424 } 426 }
425 427
426 void UserManager::SaveUserImage(const std::string& username, 428 void UserManager::SaveUserImage(const std::string& username,
427 const SkBitmap& image) { 429 const SkBitmap& image) {
428 SaveUserImageInternal(username, User::kExternalImageIndex, image); 430 SaveUserImageInternal(username, User::kExternalImageIndex, image);
429 } 431 }
430 432
431 void UserManager::SaveUserImageFromFile(const std::string& username, 433 void UserManager::SaveUserImageFromFile(const std::string& username,
432 const FilePath& path) { 434 const FilePath& path) {
(...skipping 11 matching lines...) Expand all
444 } else { 446 } else {
445 // No profile image - use the default gray avatar. 447 // No profile image - use the default gray avatar.
446 SetUserImage(username, User::kProfileImageIndex, 448 SetUserImage(username, User::kProfileImageIndex,
447 *ResourceBundle::GetSharedInstance(). 449 *ResourceBundle::GetSharedInstance().
448 GetBitmapNamed(IDR_PROFILE_PICTURE_LOADING)); 450 GetBitmapNamed(IDR_PROFILE_PICTURE_LOADING));
449 SaveImageToLocalState(username, "", User::kProfileImageIndex, false); 451 SaveImageToLocalState(username, "", User::kProfileImageIndex, false);
450 } 452 }
451 } 453 }
452 454
453 void UserManager::DownloadProfileImage() { 455 void UserManager::DownloadProfileImage() {
454 if (!profile_image_downloader_.get()) 456 if (profile_image_downloader_.get()) {
455 profile_image_downloader_.reset(new ProfileImageDownloader(this)); 457 // Another download is already in progress
458 return;
459 }
460 profile_image_downloader_.reset(new ProfileImageDownloader(this));
456 profile_image_downloader_->Start(); 461 profile_image_downloader_->Start();
457 profile_image_load_start_time_ = base::Time::Now(); 462 profile_image_load_start_time_ = base::Time::Now();
458 } 463 }
459 464
460 void UserManager::Observe(int type, 465 void UserManager::Observe(int type,
461 const content::NotificationSource& source, 466 const content::NotificationSource& source,
462 const content::NotificationDetails& details) { 467 const content::NotificationDetails& details) {
463 if (type == chrome::NOTIFICATION_OWNER_KEY_FETCH_ATTEMPT_SUCCEEDED) { 468 if (type == chrome::NOTIFICATION_OWNER_KEY_FETCH_ATTEMPT_SUCCEEDED) {
464 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 469 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
465 base::Bind(&UserManager::CheckOwnership, 470 base::Bind(&UserManager::CheckOwnership,
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
546 551
547 if (prefs_images) { 552 if (prefs_images) {
548 // Get account image path. 553 // Get account image path.
549 // TODO(avayvod): Reading image path as a string is here for 554 // TODO(avayvod): Reading image path as a string is here for
550 // backward compatibility. 555 // backward compatibility.
551 std::string image_path; 556 std::string image_path;
552 base::DictionaryValue* image_properties; 557 base::DictionaryValue* image_properties;
553 if (prefs_images->GetStringWithoutPathExpansion(email, &image_path)) { 558 if (prefs_images->GetStringWithoutPathExpansion(email, &image_path)) {
554 int image_id = User::kInvalidImageIndex; 559 int image_id = User::kInvalidImageIndex;
555 if (IsDefaultImagePath(image_path, &image_id)) { 560 if (IsDefaultImagePath(image_path, &image_id)) {
556 DCHECK(image_id >= 0 && image_id < kDefaultImagesCount); 561 user->SetImage(GetDefaultImage(image_id), image_id);
557 int resource_id = kDefaultImageResources[image_id];
558 user->SetImage(*ResourceBundle::GetSharedInstance().
559 GetBitmapNamed(resource_id),
560 image_id);
561 } else { 562 } else {
562 int image_index = User::kExternalImageIndex; 563 int image_index = User::kExternalImageIndex;
564 // Until image has been loaded, use a stub.
565 user->SetImage(GetDefaultImage(kStubDefaultImageIndex),
566 image_index);
567 DCHECK(!image_path.empty());
563 // Load user image asynchronously. 568 // Load user image asynchronously.
564 image_loader_->Start( 569 image_loader_->Start(
565 image_path, 0, 570 image_path, 0,
566 base::Bind(&UserManager::SetUserImage, 571 base::Bind(&UserManager::SetUserImage,
567 base::Unretained(this), email, image_index)); 572 base::Unretained(this), email, image_index));
568 } 573 }
569 } else if (prefs_images->GetDictionaryWithoutPathExpansion( 574 } else if (prefs_images->GetDictionaryWithoutPathExpansion(
570 email, &image_properties)) { 575 email, &image_properties)) {
571 int image_index = User::kInvalidImageIndex; 576 int image_index = User::kInvalidImageIndex;
572 image_properties->GetString(kImagePathNodeName, &image_path); 577 image_properties->GetString(kImagePathNodeName, &image_path);
573 image_properties->GetInteger(kImageIndexNodeName, &image_index); 578 image_properties->GetInteger(kImageIndexNodeName, &image_index);
574 if (image_index >= 0 && image_index < kDefaultImagesCount) { 579 if (image_index >= 0 && image_index < kDefaultImagesCount) {
575 int resource_id = kDefaultImageResources[image_index]; 580 user->SetImage(GetDefaultImage(image_index), image_index);
576 user->SetImage(*ResourceBundle::GetSharedInstance().
577 GetBitmapNamed(resource_id),
578 image_index);
579 } else if (image_index == User::kProfileImageIndex &&
580 image_path.empty()) {
581 // User has profile image as his picture but no profile image
582 // has been downloaded yet, so use a grey avatar for now.
583 user->SetImage(*ResourceBundle::GetSharedInstance().
584 GetBitmapNamed(IDR_PROFILE_PICTURE_LOADING),
585 User::kProfileImageIndex);
586 } else if (image_index == User::kExternalImageIndex || 581 } else if (image_index == User::kExternalImageIndex ||
587 image_index == User::kProfileImageIndex) { 582 image_index == User::kProfileImageIndex) {
588 // Load user image asynchronously. 583 // Path may be empty for profile images (meaning that the image
589 image_loader_->Start( 584 // hasn't been downloaded for the first time yet, in which case a
590 image_path, 0, 585 // download will be scheduled for |kProfileImageDownloadDelayMs|
591 base::Bind(&UserManager::SetUserImage, 586 // after user logs in).
592 base::Unretained(this), email, image_index)); 587 DCHECK(!image_path.empty() ||
588 image_index == User::kProfileImageIndex);
589 // Until image has been loaded, use a stub.
590 user->SetImage(GetDefaultImage(kStubDefaultImageIndex),
591 image_index);
592 if (!image_path.empty()) {
593 // Load user image asynchronously.
594 image_loader_->Start(
595 image_path, 0,
596 base::Bind(&UserManager::SetUserImage,
597 base::Unretained(this), email, image_index));
598 }
593 } else { 599 } else {
594 NOTREACHED(); 600 NOTREACHED();
595 } 601 }
596 } 602 }
597 } 603 }
598 } 604 }
599 } 605 }
600 } 606 }
601 } 607 }
602 608
603 void UserManager::StubUserLoggedIn() { 609 void UserManager::StubUserLoggedIn() {
604 logged_in_user_ = &stub_user_; 610 logged_in_user_ = &stub_user_;
605 SetUserImage(stub_user_.email(), 0, 611 stub_user_.SetImage(GetDefaultImage(kStubDefaultImageIndex),
606 *ResourceBundle::GetSharedInstance(). 612 kStubDefaultImageIndex);
607 GetBitmapNamed(kDefaultImageResources[0]));
608 } 613 }
609 614
610 void UserManager::NotifyOnLogin() { 615 void UserManager::NotifyOnLogin() {
611 content::NotificationService::current()->Notify( 616 content::NotificationService::current()->Notify(
612 chrome::NOTIFICATION_LOGIN_USER_CHANGED, 617 chrome::NOTIFICATION_LOGIN_USER_CHANGED,
613 content::Source<UserManager>(this), 618 content::Source<UserManager>(this),
614 content::Details<const User>(logged_in_user_)); 619 content::Details<const User>(logged_in_user_));
615 620
616 chromeos::input_method::InputMethodManager::GetInstance()-> 621 chromeos::input_method::InputMethodManager::GetInstance()->
617 SetDeferImeStartup(false); 622 SetDeferImeStartup(false);
(...skipping 30 matching lines...) Expand all
648 // Choose a random default image. 653 // Choose a random default image.
649 int image_id = base::RandInt(0, kDefaultImagesCount - 1); 654 int image_id = base::RandInt(0, kDefaultImagesCount - 1);
650 SaveUserDefaultImageIndex(username, image_id); 655 SaveUserDefaultImageIndex(username, image_id);
651 } 656 }
652 657
653 void UserManager::SetUserImage(const std::string& username, 658 void UserManager::SetUserImage(const std::string& username,
654 int image_index, 659 int image_index,
655 const SkBitmap& image) { 660 const SkBitmap& image) {
656 User* user = const_cast<User*>(FindUser(username)); 661 User* user = const_cast<User*>(FindUser(username));
657 // User may have been removed by now. 662 // User may have been removed by now.
658 if (user) 663 if (user) {
664 // For existing users, a valid image index should have been set upon loading
665 // them from Local State.
666 DCHECK(user->image_index() != User::kInvalidImageIndex ||
667 current_user_is_new_);
668 bool image_changed = user->image_index() != User::kInvalidImageIndex;
659 user->SetImage(image, image_index); 669 user->SetImage(image, image_index);
670 if (image_changed) {
671 // Unless this is first-time setting with |SetInitialUserImage|,
672 // send a notification about image change.
673 content::NotificationService::current()->Notify(
674 chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED,
675 content::Source<UserManager>(this),
676 content::Details<const User>(user));
677 }
678 }
660 } 679 }
661 680
662 void UserManager::SaveUserImageInternal(const std::string& username, 681 void UserManager::SaveUserImageInternal(const std::string& username,
663 int image_index, 682 int image_index,
664 const SkBitmap& image) { 683 const SkBitmap& image) {
665 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 684 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
666 685
667 SetUserImage(username, image_index, image); 686 SetUserImage(username, image_index, image);
668 687
669 FilePath image_path = GetImagePathForUser(username); 688 FilePath image_path = GetImagePathForUser(username);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 DictionaryPrefUpdate images_update(local_state, kUserImages); 746 DictionaryPrefUpdate images_update(local_state, kUserImages);
728 base::DictionaryValue* image_properties = new base::DictionaryValue(); 747 base::DictionaryValue* image_properties = new base::DictionaryValue();
729 image_properties->Set(kImagePathNodeName, new StringValue(image_path)); 748 image_properties->Set(kImagePathNodeName, new StringValue(image_path));
730 image_properties->Set(kImageIndexNodeName, 749 image_properties->Set(kImageIndexNodeName,
731 new base::FundamentalValue(image_index)); 750 new base::FundamentalValue(image_index));
732 images_update->SetWithoutPathExpansion(username, image_properties); 751 images_update->SetWithoutPathExpansion(username, image_properties);
733 DVLOG(1) << "Saving path to user image in Local State."; 752 DVLOG(1) << "Saving path to user image in Local State.";
734 local_state->ScheduleSavePersistentPrefs(); 753 local_state->ScheduleSavePersistentPrefs();
735 754
736 NotifyLocalStateChanged(); 755 NotifyLocalStateChanged();
737 content::NotificationService::current()->Notify(
738 chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED,
739 content::Source<UserManager>(this),
740 content::Details<const User>(logged_in_user_));
741 } 756 }
742 757
743 void UserManager::DeleteUserImage(const FilePath& image_path) { 758 void UserManager::DeleteUserImage(const FilePath& image_path) {
744 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 759 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
745 if (!file_util::Delete(image_path, false)) { 760 if (!file_util::Delete(image_path, false)) {
746 LOG(ERROR) << "Failed to remove user image."; 761 LOG(ERROR) << "Failed to remove user image.";
747 return; 762 return;
748 } 763 }
749 } 764 }
750 765
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
805 ProfileImageDownloader::kDownloadResultsCount); 820 ProfileImageDownloader::kDownloadResultsCount);
806 821
807 // This will persist |downloaded_profile_image_| to file. 822 // This will persist |downloaded_profile_image_| to file.
808 SaveUserImageFromProfileImage(logged_in_user().email()); 823 SaveUserImageFromProfileImage(logged_in_user().email());
809 } 824 }
810 825
811 content::NotificationService::current()->Notify( 826 content::NotificationService::current()->Notify(
812 chrome::NOTIFICATION_PROFILE_IMAGE_UPDATED, 827 chrome::NOTIFICATION_PROFILE_IMAGE_UPDATED,
813 content::Source<UserManager>(this), 828 content::Source<UserManager>(this),
814 content::Details<const SkBitmap>(&image)); 829 content::Details<const SkBitmap>(&image));
830
831 profile_image_downloader_.reset();
815 } 832 }
816 833
817 void UserManager::OnDownloadFailure() { 834 void UserManager::OnDownloadFailure() {
818 VLOG(1) << "Download of profile image for logged-in user failed."; 835 VLOG(1) << "Download of profile image for logged-in user failed.";
819 UMA_HISTOGRAM_ENUMERATION("UserImageDownloadResult.LoggedIn", 836 UMA_HISTOGRAM_ENUMERATION("UserImageDownloadResult.LoggedIn",
820 ProfileImageDownloader::kDownloadFailure, 837 ProfileImageDownloader::kDownloadFailure,
821 ProfileImageDownloader::kDownloadResultsCount); 838 ProfileImageDownloader::kDownloadResultsCount);
822 content::NotificationService::current()->Notify( 839 content::NotificationService::current()->Notify(
823 chrome::NOTIFICATION_PROFILE_IMAGE_UPDATE_FAILED, 840 chrome::NOTIFICATION_PROFILE_IMAGE_UPDATE_FAILED,
824 content::Source<UserManager>(this), 841 content::Source<UserManager>(this),
825 content::NotificationService::NoDetails()); 842 content::NotificationService::NoDetails());
843 profile_image_downloader_.reset();
826 } 844 }
827 845
828 void UserManager::OnDownloadDefaultImage() { 846 void UserManager::OnDownloadDefaultImage() {
829 VLOG(1) << "Logged-in user still has the default profile image."; 847 VLOG(1) << "Logged-in user still has the default profile image.";
830 UMA_HISTOGRAM_ENUMERATION("UserImageDownloadResult.LoggedIn", 848 UMA_HISTOGRAM_ENUMERATION("UserImageDownloadResult.LoggedIn",
831 ProfileImageDownloader::kDownloadDefault, 849 ProfileImageDownloader::kDownloadDefault,
832 ProfileImageDownloader::kDownloadResultsCount); 850 ProfileImageDownloader::kDownloadResultsCount);
833 content::NotificationService::current()->Notify( 851 content::NotificationService::current()->Notify(
834 chrome::NOTIFICATION_PROFILE_IMAGE_UPDATE_FAILED, 852 chrome::NOTIFICATION_PROFILE_IMAGE_UPDATE_FAILED,
835 content::Source<UserManager>(this), 853 content::Source<UserManager>(this),
836 content::NotificationService::NoDetails()); 854 content::NotificationService::NoDetails());
855 profile_image_downloader_.reset();
837 } 856 }
838 857
839 User* UserManager::CreateUser(const std::string& email) const { 858 User* UserManager::CreateUser(const std::string& email) const {
840 User* user = new User(email); 859 User* user = new User(email);
841 user->set_oauth_token_status(GetUserOAuthStatus(email)); 860 user->set_oauth_token_status(GetUserOAuthStatus(email));
842 // Used to determine whether user's display name is unique. 861 // Used to determine whether user's display name is unique.
843 ++display_name_count_[user->GetDisplayName()]; 862 ++display_name_count_[user->GetDisplayName()];
844 return user; 863 return user;
845 } 864 }
846 865
847 } // namespace chromeos 866 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/login/user_manager.h ('k') | chrome/browser/resources/options/chromeos/change_picture_options.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698