diff options
author | ygorshenin@chromium.org <ygorshenin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-24 18:36:55 +0000 |
---|---|---|
committer | ygorshenin@chromium.org <ygorshenin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-24 18:36:55 +0000 |
commit | 28126586a68d2aaed9557c505e10ebc20f50ed5b (patch) | |
tree | aab74653a82078a24c827cad951d939e6db06891 | |
parent | 670d3239b119ec0dd29271b3851aa96ec4d2072b (diff) | |
download | chromium_src-28126586a68d2aaed9557c505e10ebc20f50ed5b.zip chromium_src-28126586a68d2aaed9557c505e10ebc20f50ed5b.tar.gz chromium_src-28126586a68d2aaed9557c505e10ebc20f50ed5b.tar.bz2 |
Refactoring of the UserImageManager.
BUG=313303,322682
TEST=browser_tests:UserImageManager*
Review URL: https://codereview.chromium.org/106093008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@242448 0039d316-1c4b-4281-b951-d872f2087c98
20 files changed, 478 insertions, 428 deletions
diff --git a/chrome/browser/chromeos/login/fake_user_manager.cc b/chrome/browser/chromeos/login/fake_user_manager.cc index 023a51a..34f3248 100644 --- a/chrome/browser/chromeos/login/fake_user_manager.cc +++ b/chrome/browser/chromeos/login/fake_user_manager.cc @@ -127,7 +127,8 @@ SupervisedUserManager* FakeUserManager::GetSupervisedUserManager() { return supervised_user_manager_.get(); } -UserImageManager* FakeUserManager::GetUserImageManager() { +UserImageManager* FakeUserManager::GetUserImageManager( + const std::string& /* user_id */) { return NULL; } diff --git a/chrome/browser/chromeos/login/fake_user_manager.h b/chrome/browser/chromeos/login/fake_user_manager.h index 31ab136..a6e4e9f 100644 --- a/chrome/browser/chromeos/login/fake_user_manager.h +++ b/chrome/browser/chromeos/login/fake_user_manager.h @@ -58,7 +58,8 @@ class FakeUserManager : public UserManager { const std::string& user_id, const UserAccountData& account_data) OVERRIDE {} virtual void Shutdown() OVERRIDE {} - virtual UserImageManager* GetUserImageManager() OVERRIDE; + virtual UserImageManager* GetUserImageManager( + const std::string& user_id) OVERRIDE; virtual SupervisedUserManager* GetSupervisedUserManager() OVERRIDE; virtual const UserList& GetLRULoggedInUsers() OVERRIDE; virtual UserList GetUnlockUsers() const OVERRIDE; diff --git a/chrome/browser/chromeos/login/managed/locally_managed_user_creation_screen.cc b/chrome/browser/chromeos/login/managed/locally_managed_user_creation_screen.cc index 8225560..34ea096 100644 --- a/chrome/browser/chromeos/login/managed/locally_managed_user_creation_screen.cc +++ b/chrome/browser/chromeos/login/managed/locally_managed_user_creation_screen.cc @@ -406,9 +406,9 @@ bool LocallyManagedUserCreationScreen::FindUserByDisplayName( // It should be removed by issue 251179. void LocallyManagedUserCreationScreen::ApplyPicture() { - UserManager* user_manager = UserManager::Get(); - UserImageManager* image_manager = user_manager->GetUserImageManager(); std::string user_id = controller_->GetManagedUserId(); + UserManager* user_manager = UserManager::Get(); + UserImageManager* image_manager = user_manager->GetUserImageManager(user_id); switch (selected_image_) { case User::kExternalImageIndex: // Photo decoding may not have been finished yet. @@ -416,15 +416,14 @@ void LocallyManagedUserCreationScreen::ApplyPicture() { apply_photo_after_decoding_ = true; return; } - image_manager-> - SaveUserImage(user_id, UserImage::CreateAndEncode(user_photo_)); + image_manager->SaveUserImage(UserImage::CreateAndEncode(user_photo_)); break; case User::kProfileImageIndex: NOTREACHED() << "Supervised users have no profile pictures"; break; default: DCHECK(selected_image_ >= 0 && selected_image_ < kDefaultImagesCount); - image_manager->SaveUserDefaultImageIndex(user_id, selected_image_); + image_manager->SaveUserDefaultImageIndex(selected_image_); break; } // Proceed to tutorial. diff --git a/chrome/browser/chromeos/login/mock_user_image_manager.cc b/chrome/browser/chromeos/login/mock_user_image_manager.cc index 07482350..9aadb5a 100644 --- a/chrome/browser/chromeos/login/mock_user_image_manager.cc +++ b/chrome/browser/chromeos/login/mock_user_image_manager.cc @@ -6,10 +6,9 @@ namespace chromeos { -MockUserImageManager::MockUserImageManager() { -} +MockUserImageManager::MockUserImageManager(const std::string& user_id) + : UserImageManager(user_id) {} -MockUserImageManager::~MockUserImageManager() { -} +MockUserImageManager::~MockUserImageManager() {} } // namespace chromeos diff --git a/chrome/browser/chromeos/login/mock_user_image_manager.h b/chrome/browser/chromeos/login/mock_user_image_manager.h index 9ee0328..e263a0b 100644 --- a/chrome/browser/chromeos/login/mock_user_image_manager.h +++ b/chrome/browser/chromeos/login/mock_user_image_manager.h @@ -16,14 +16,13 @@ namespace chromeos { class MockUserImageManager : public UserImageManager { public: - MockUserImageManager(); + explicit MockUserImageManager(const std::string& user_id); virtual ~MockUserImageManager(); - MOCK_METHOD2(SaveUserDefaultImageIndex, void(const std::string&, int)); - MOCK_METHOD2(SaveUserImage, void(const std::string&, const UserImage&)); - MOCK_METHOD2(SaveUserImageFromFile, void(const std::string&, - const base::FilePath&)); - MOCK_METHOD1(SaveUserImageFromProfileImage, void(const std::string&)); + MOCK_METHOD1(SaveUserDefaultImageIndex, void(int)); + MOCK_METHOD1(SaveUserImage, void(const UserImage&)); + MOCK_METHOD1(SaveUserImageFromFile, void(const base::FilePath&)); + MOCK_METHOD0(SaveUserImageFromProfileImage, void()); MOCK_METHOD1(DownloadProfileImage, void(const std::string&)); MOCK_CONST_METHOD0(DownloadedProfileImage, const gfx::ImageSkia& (void)); diff --git a/chrome/browser/chromeos/login/mock_user_manager.cc b/chrome/browser/chromeos/login/mock_user_manager.cc index 31a24e7..6988160 100644 --- a/chrome/browser/chromeos/login/mock_user_manager.cc +++ b/chrome/browser/chromeos/login/mock_user_manager.cc @@ -52,8 +52,9 @@ User* MockUserManager::GetUserByProfile(Profile* profile) const { return user_list_.empty() ? NULL : user_list_.front(); } -UserImageManager* MockUserManager::GetUserImageManager() { - return user_image_manager_.get(); +UserImageManager* MockUserManager::GetUserImageManager( + const std::string& user_id) { + return NULL; } SupervisedUserManager* MockUserManager::GetSupervisedUserManager() { diff --git a/chrome/browser/chromeos/login/mock_user_manager.h b/chrome/browser/chromeos/login/mock_user_manager.h index e6242e7..346f090 100644 --- a/chrome/browser/chromeos/login/mock_user_manager.h +++ b/chrome/browser/chromeos/login/mock_user_manager.h @@ -97,7 +97,8 @@ class MockUserManager : public UserManager { virtual const User* GetPrimaryUser() const OVERRIDE; virtual User* GetUserByProfile(Profile* profile) const OVERRIDE; - virtual UserImageManager* GetUserImageManager() OVERRIDE; + virtual UserImageManager* GetUserImageManager( + const std::string& user_id) OVERRIDE; virtual SupervisedUserManager* GetSupervisedUserManager() OVERRIDE; virtual UserFlow* GetCurrentUserFlow() const OVERRIDE; diff --git a/chrome/browser/chromeos/login/screens/user_image_screen.cc b/chrome/browser/chromeos/login/screens/user_image_screen.cc index 2b2cb3a..23e0a0a 100644 --- a/chrome/browser/chromeos/login/screens/user_image_screen.cc +++ b/chrome/browser/chromeos/login/screens/user_image_screen.cc @@ -141,8 +141,7 @@ void UserImageScreen::OnInitialSync(bool local_image_updated) { DCHECK(sync_timer_); if (!local_image_updated) { sync_timer_.reset(); - UserManager::Get()->GetUserImageManager()->GetSyncObserver()-> - RemoveObserver(this); + GetSyncObserver()->RemoveObserver(this); if (is_screen_ready_) HideCurtain(); return; @@ -152,8 +151,7 @@ void UserImageScreen::OnInitialSync(bool local_image_updated) { void UserImageScreen::OnSyncTimeout() { sync_timer_.reset(); - UserManager::Get()->GetUserImageManager()->GetSyncObserver()-> - RemoveObserver(this); + GetSyncObserver()->RemoveObserver(this); if (is_screen_ready_) HideCurtain(); } @@ -193,9 +191,7 @@ void UserImageScreen::OnImageSelected(const std::string& image_type, } void UserImageScreen::OnImageAccepted() { - UserManager* user_manager = UserManager::Get(); - UserImageManager* image_manager = user_manager->GetUserImageManager(); - std::string user_id = GetUser()->email(); + UserImageManager* image_manager = GetUserImageManager(); int uma_index = 0; switch (selected_image_) { case User::kExternalImageIndex: @@ -204,17 +200,16 @@ void UserImageScreen::OnImageAccepted() { accept_photo_after_decoding_ = true; return; } - image_manager-> - SaveUserImage(user_id, UserImage::CreateAndEncode(user_photo_)); + image_manager->SaveUserImage(UserImage::CreateAndEncode(user_photo_)); uma_index = kHistogramImageFromCamera; break; case User::kProfileImageIndex: - image_manager->SaveUserImageFromProfileImage(user_id); + image_manager->SaveUserImageFromProfileImage(); uma_index = kHistogramImageFromProfile; break; default: DCHECK(selected_image_ >= 0 && selected_image_ < kDefaultImagesCount); - image_manager->SaveUserDefaultImageIndex(user_id, selected_image_); + image_manager->SaveUserDefaultImageIndex(selected_image_); uma_index = GetDefaultImageHistogramValue(selected_image_); break; } @@ -265,9 +260,15 @@ void UserImageScreen::PrepareToShow() { const User* UserImageScreen::GetUser() { if (user_id_.empty()) return UserManager::Get()->GetLoggedInUser(); - const User* user = UserManager::Get()->FindUser(user_id_); - DCHECK(user); - return user; + return UserManager::Get()->FindUser(user_id_); +} + +UserImageManager* UserImageScreen::GetUserImageManager() { + return UserManager::Get()->GetUserImageManager(GetUser()->email()); +} + +UserImageSyncObserver* UserImageScreen::GetSyncObserver() { + return GetUserImageManager()->GetSyncObserver(); } void UserImageScreen::Show() { @@ -304,8 +305,7 @@ void UserImageScreen::Show() { } if (GetUser()->CanSyncImage()) { - if (UserImageSyncObserver* sync_observer = - UserManager::Get()->GetUserImageManager()->GetSyncObserver()) { + if (UserImageSyncObserver* sync_observer = GetSyncObserver()) { // We have synced image already. if (sync_observer->is_synced()) { ExitScreen(); @@ -328,8 +328,7 @@ void UserImageScreen::Show() { if (profile_picture_enabled_) { // Start fetching the profile image. - UserManager::Get()->GetUserImageManager()-> - DownloadProfileImage(kProfileDownloadReason); + GetUserImageManager()->DownloadProfileImage(kProfileDownloadReason); } } @@ -392,9 +391,7 @@ std::string UserImageScreen::profile_picture_data_url() { void UserImageScreen::ExitScreen() { policy_registrar_.reset(); sync_timer_.reset(); - UserImageSyncObserver* sync_observer = - UserManager::Get()->GetUserImageManager()->GetSyncObserver(); - if (sync_observer) + if (UserImageSyncObserver* sync_observer = GetSyncObserver()) sync_observer->RemoveObserver(this); get_screen_observer()->OnExit(ScreenObserver::USER_IMAGE_SELECTED); } diff --git a/chrome/browser/chromeos/login/screens/user_image_screen.h b/chrome/browser/chromeos/login/screens/user_image_screen.h index be240f3..8840719 100644 --- a/chrome/browser/chromeos/login/screens/user_image_screen.h +++ b/chrome/browser/chromeos/login/screens/user_image_screen.h @@ -89,8 +89,15 @@ class UserImageScreen: public WizardScreen, void OnUserImagePolicyChanged(const base::Value* previous, const base::Value* current); + // Returns current user. const User* GetUser(); + // Returns UserImageManager for the current user. + UserImageManager* GetUserImageManager(); + + // Returns UserImageSyncObserver for the current user. + UserImageSyncObserver* GetSyncObserver(); + // Called when the camera presence check has been completed. void OnCameraPresenceCheckDone(); diff --git a/chrome/browser/chromeos/login/user_image_manager.cc b/chrome/browser/chromeos/login/user_image_manager.cc index 84699cc..3e5e625 100644 --- a/chrome/browser/chromeos/login/user_image_manager.cc +++ b/chrome/browser/chromeos/login/user_image_manager.cc @@ -6,7 +6,9 @@ namespace chromeos { -UserImageManager::~UserImageManager() { -} +UserImageManager::UserImageManager(const std::string& user_id) + : user_id_(user_id) {} + +UserImageManager::~UserImageManager() {} } // namespace chromeos diff --git a/chrome/browser/chromeos/login/user_image_manager.h b/chrome/browser/chromeos/login/user_image_manager.h index bd9c38d..ad13a1e 100644 --- a/chrome/browser/chromeos/login/user_image_manager.h +++ b/chrome/browser/chromeos/login/user_image_manager.h @@ -25,64 +25,81 @@ class UserImage; class UserImageSyncObserver; // Base class that provides a mechanism for updating user images. +// There is an instance of this class for each user in the system. class UserImageManager { public: // Registers user image manager preferences. static void RegisterPrefs(PrefRegistrySimple* registry); + explicit UserImageManager(const std::string& user_id); virtual ~UserImageManager(); // Loads user image data from Local State. - virtual void LoadUserImages(const UserList& users) = 0; + virtual void LoadUserImage() = 0; - // Indicates that a user with the given |user_id| has just logged in. - virtual void UserLoggedIn(const std::string& user_id, - bool user_is_new, - bool user_is_local) = 0; + // Indicates that a user has just logged in. + virtual void UserLoggedIn(bool user_is_new, bool user_is_local) = 0; // Sets user image to the default image with index |image_index|, sends // LOGIN_USER_IMAGE_CHANGED notification and updates Local State. - virtual void SaveUserDefaultImageIndex(const std::string& user_id, - int image_index) = 0; + virtual void SaveUserDefaultImageIndex(int image_index) = 0; // Saves image to file, sends LOGIN_USER_IMAGE_CHANGED notification and // updates Local State. - virtual void SaveUserImage(const std::string& user_id, - const UserImage& user_image) = 0; + virtual void SaveUserImage(const UserImage& user_image) = 0; // Tries to load user image from disk; if successful, sets it for the user, // sends LOGIN_USER_IMAGE_CHANGED notification and updates Local State. - virtual void SaveUserImageFromFile(const std::string& user_id, - const base::FilePath& path) = 0; + virtual void SaveUserImageFromFile(const base::FilePath& path) = 0; - // Sets profile image as user image for |user_id|, sends - // LOGIN_USER_IMAGE_CHANGED notification and updates Local State. If the user - // is not logged-in or the last |DownloadProfileImage| call has failed, a - // default grey avatar will be used until the user logs in and profile image - // is downloaded successfully. - virtual void SaveUserImageFromProfileImage(const std::string& user_id) = 0; + // Sets profile image as user image for the user, sends + // LOGIN_USER_IMAGE_CHANGED notification and updates Local State. If + // the user is not logged-in or the last |DownloadProfileImage| call + // has failed, a default grey avatar will be used until the user logs + // in and profile image is downloaded successfully. + virtual void SaveUserImageFromProfileImage() = 0; // Deletes user image and the corresponding image file. - virtual void DeleteUserImage(const std::string& user_id) = 0; + virtual void DeleteUserImage() = 0; - // Starts downloading the profile image for the logged-in user. - // If user's image index is |kProfileImageIndex|, newly downloaded image - // is immediately set as user's current picture. - // |reason| is an arbitrary string (used to report UMA histograms with - // download times). + // Starts downloading the profile image for the user. If user's image + // index is |kProfileImageIndex|, newly downloaded image is immediately + // set as user's current picture. |reason| is an arbitrary string + // (used to report UMA histograms with download times). virtual void DownloadProfileImage(const std::string& reason) = 0; // Returns the result of the last successful profile image download, if any. // Otherwise, returns an empty bitmap. virtual const gfx::ImageSkia& DownloadedProfileImage() const = 0; - // Returns sync observer attached to current user. Returns NULL if current + // Returns sync observer attached to the user. Returns NULL if current // user can't sync images or user is not logged in. virtual UserImageSyncObserver* GetSyncObserver() const = 0; // Unregisters preference observers before browser process shutdown. // Also cancels any profile image download in progress. virtual void Shutdown() = 0; + + // Invoked when an external data reference is set for the user. + virtual void OnExternalDataSet(const std::string& policy) = 0; + + // Invoked when the external data reference is cleared for the user. + virtual void OnExternalDataCleared(const std::string& policy) = 0; + + // Invoked when the external data referenced for the user has been + // fetched. Failed fetches are retried and the method is called only + // when a fetch eventually succeeds. If a fetch fails permanently + // (e.g. because the external data reference specifies an invalid URL), + // the method is not called at all. + virtual void OnExternalDataFetched(const std::string& policy, + scoped_ptr<std::string> data) = 0; + + protected: + const std::string& user_id() const { return user_id_; } + + // ID of user which images are managed by current instance of + // UserImageManager. + const std::string user_id_; }; } // namespace chromeos diff --git a/chrome/browser/chromeos/login/user_image_manager_browsertest.cc b/chrome/browser/chromeos/login/user_image_manager_browsertest.cc index ab2c44b..df96eb6 100644 --- a/chrome/browser/chromeos/login/user_image_manager_browsertest.cc +++ b/chrome/browser/chromeos/login/user_image_manager_browsertest.cc @@ -213,16 +213,17 @@ class UserImageManagerTest : public LoginManagerTest, return user_data_dir_.Append(username).AddExtension(extension); } - // Completes the download of all non-image profile data for the currently - // logged-in user. This method must only be called after a profile data - // download has been started. - // |url_fetcher_factory| will capture the net::TestURLFetcher created by the - // ProfileDownloader to download the profile image. + // Completes the download of all non-image profile data for the user + // |username|. This method must only be called after a profile data + // download has been started. |url_fetcher_factory| will capture + // the net::TestURLFetcher created by the ProfileDownloader to + // download the profile image. void CompleteProfileMetadataDownload( + const std::string& username, net::TestURLFetcherFactory* url_fetcher_factory) { ProfileDownloader* profile_downloader = reinterpret_cast<UserImageManagerImpl*>( - UserManager::Get()->GetUserImageManager())-> + UserManager::Get()->GetUserImageManager(username))-> profile_downloader_.get(); ASSERT_TRUE(profile_downloader); @@ -272,10 +273,9 @@ class UserImageManagerTest : public LoginManagerTest, const User* user = UserManager::Get()->GetLoggedInUser(); ASSERT_TRUE(user); - const std::map<std::string, linked_ptr<UserImageManagerImpl::Job> >& - job_map = reinterpret_cast<UserImageManagerImpl*>( - UserManager::Get()->GetUserImageManager())->jobs_; - if (job_map.find(user->email()) != job_map.end()) { + UserImageManagerImpl* uim = reinterpret_cast<UserImageManagerImpl*>( + UserManager::Get()->GetUserImageManager(user->email())); + if (uim->job_.get()) { run_loop_.reset(new base::RunLoop); run_loop_->Run(); } @@ -398,9 +398,8 @@ IN_PROC_BROWSER_TEST_F(UserImageManagerTest, SaveUserDefaultImageIndex) { GetDefaultImage(kFirstDefaultImageIndex); UserImageManager* user_image_manager = - UserManager::Get()->GetUserImageManager(); - user_image_manager->SaveUserDefaultImageIndex(kTestUser1, - kFirstDefaultImageIndex); + UserManager::Get()->GetUserImageManager(kTestUser1); + user_image_manager->SaveUserDefaultImageIndex(kFirstDefaultImageIndex); EXPECT_TRUE(user->HasDefaultImage()); EXPECT_EQ(kFirstDefaultImageIndex, user->image_index()); @@ -427,9 +426,8 @@ IN_PROC_BROWSER_TEST_F(UserImageManagerTest, SaveUserImage) { run_loop_.reset(new base::RunLoop); UserImageManager* user_image_manager = - UserManager::Get()->GetUserImageManager(); - user_image_manager->SaveUserImage(kTestUser1, - UserImage::CreateAndEncode(custom_image)); + UserManager::Get()->GetUserImageManager(kTestUser1); + user_image_manager->SaveUserImage(UserImage::CreateAndEncode(custom_image)); run_loop_->Run(); EXPECT_FALSE(user->HasDefaultImage()); @@ -466,8 +464,8 @@ IN_PROC_BROWSER_TEST_F(UserImageManagerTest, SaveUserImageFromFile) { run_loop_.reset(new base::RunLoop); UserImageManager* user_image_manager = - UserManager::Get()->GetUserImageManager(); - user_image_manager->SaveUserImageFromFile(kTestUser1, custom_image_path); + UserManager::Get()->GetUserImageManager(kTestUser1); + user_image_manager->SaveUserImageFromFile(custom_image_path); run_loop_->Run(); EXPECT_FALSE(user->HasDefaultImage()); @@ -503,12 +501,12 @@ IN_PROC_BROWSER_TEST_F(UserImageManagerTest, SaveUserImageFromProfileImage) { run_loop_.reset(new base::RunLoop); UserImageManager* user_image_manager = - UserManager::Get()->GetUserImageManager(); - user_image_manager->SaveUserImageFromProfileImage(kTestUser1); + UserManager::Get()->GetUserImageManager(kTestUser1); + user_image_manager->SaveUserImageFromProfileImage(); run_loop_->Run(); net::TestURLFetcherFactory url_fetcher_factory; - CompleteProfileMetadataDownload(&url_fetcher_factory); + CompleteProfileMetadataDownload(kTestUser1, &url_fetcher_factory); CompleteProfileImageDownload(&url_fetcher_factory); const gfx::ImageSkia& profile_image = @@ -553,15 +551,14 @@ IN_PROC_BROWSER_TEST_F(UserImageManagerTest, run_loop_.reset(new base::RunLoop); UserImageManager* user_image_manager = - UserManager::Get()->GetUserImageManager(); - user_image_manager->SaveUserImageFromProfileImage(kTestUser1); + UserManager::Get()->GetUserImageManager(kTestUser1); + user_image_manager->SaveUserImageFromProfileImage(); run_loop_->Run(); net::TestURLFetcherFactory url_fetcher_factory; - CompleteProfileMetadataDownload(&url_fetcher_factory); + CompleteProfileMetadataDownload(kTestUser1, &url_fetcher_factory); - user_image_manager->SaveUserDefaultImageIndex(kTestUser1, - kFirstDefaultImageIndex); + user_image_manager->SaveUserDefaultImageIndex(kFirstDefaultImageIndex); CompleteProfileImageDownload(&url_fetcher_factory); @@ -728,9 +725,8 @@ IN_PROC_BROWSER_TEST_F(UserImageManagerPolicyTest, SetAndClear) { GetDefaultImage(kFirstDefaultImageIndex); UserImageManager* user_image_manager = - UserManager::Get()->GetUserImageManager(); - user_image_manager->SaveUserDefaultImageIndex(kTestUser1, - kFirstDefaultImageIndex); + UserManager::Get()->GetUserImageManager(kTestUser1); + user_image_manager->SaveUserDefaultImageIndex(kFirstDefaultImageIndex); EXPECT_TRUE(user->HasDefaultImage()); EXPECT_EQ(kFirstDefaultImageIndex, user->image_index()); @@ -762,9 +758,8 @@ IN_PROC_BROWSER_TEST_F(UserImageManagerPolicyTest, PolicyOverridesUser) { GetDefaultImage(kFirstDefaultImageIndex); UserImageManager* user_image_manager = - UserManager::Get()->GetUserImageManager(); - user_image_manager->SaveUserDefaultImageIndex(kTestUser1, - kFirstDefaultImageIndex); + UserManager::Get()->GetUserImageManager(kTestUser1); + user_image_manager->SaveUserDefaultImageIndex(kFirstDefaultImageIndex); EXPECT_TRUE(user->HasDefaultImage()); EXPECT_EQ(kFirstDefaultImageIndex, user->image_index()); @@ -846,9 +841,8 @@ IN_PROC_BROWSER_TEST_F(UserImageManagerPolicyTest, UserDoesNotOverridePolicy) { // Choose a different user image. Verify that the user image does not change // as policy takes precedence. UserImageManager* user_image_manager = - UserManager::Get()->GetUserImageManager(); - user_image_manager->SaveUserDefaultImageIndex(kTestUser1, - kFirstDefaultImageIndex); + UserManager::Get()->GetUserImageManager(kTestUser1); + user_image_manager->SaveUserDefaultImageIndex(kFirstDefaultImageIndex); EXPECT_FALSE(user->HasDefaultImage()); EXPECT_EQ(User::kExternalImageIndex, user->image_index()); diff --git a/chrome/browser/chromeos/login/user_image_manager_impl.cc b/chrome/browser/chromeos/login/user_image_manager_impl.cc index 4fbb9bd..f03e5ec 100644 --- a/chrome/browser/chromeos/login/user_image_manager_impl.cc +++ b/chrome/browser/chromeos/login/user_image_manager_impl.cc @@ -18,10 +18,10 @@ #include "base/prefs/scoped_user_pref_update.h" #include "base/rand_util.h" #include "base/sequenced_task_runner.h" -#include "base/stl_util.h" #include "base/task_runner_util.h" #include "base/threading/sequenced_worker_pool.h" #include "base/time/time.h" +#include "base/values.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/login/default_user_images.h" @@ -201,36 +201,36 @@ void UserImageManager::RegisterPrefs(PrefRegistrySimple* registry) { // Only one of the Load*() and Set*() methods may be called per Job. class UserImageManagerImpl::Job { public: - // The |Job| will update the |user| object for |user_id|. - Job(UserImageManagerImpl* parent, const std::string& user_id); + // The |Job| will update the user object corresponding to |parent|. + explicit Job(UserImageManagerImpl* parent); ~Job(); - // Loads the image at |image_path| or one of the default images, depending on - // |image_index|, and updates the |user| object for |user_id_| with the new - // image. + // Loads the image at |image_path| or one of the default images, + // depending on |image_index|, and updates the user object with the + // new image. void LoadImage(base::FilePath image_path, const int image_index, const GURL& image_url); - // Sets the user image for |user_id_| in local state to the default image - // indicated by |default_image_index|. Also updates the |user| object for - // |user_id_| with the new image. + // Sets the user image in local state to the default image indicated + // by |default_image_index|. Also updates the user object with the + // new image. void SetToDefaultImage(int default_image_index); - // Saves the |user_image| to disk and sets the user image for |user_id_| in - // local state to that image. Also updates the |user| object for |user_id_| - // with the new image. + // Saves the |user_image| to disk and sets the user image in local + // state to that image. Also updates the user with the new image. void SetToImage(int image_index, const UserImage& user_image); - // Decodes the JPEG image |data|, crops and resizes the image, saves it to - // disk and sets the user image for |user_id_| in local state to that image. - // Also updates the |user| object for |user_id_| with the new image. + // Decodes the JPEG image |data|, crops and resizes the image, saves + // it to disk and sets the user image in local state to that image. + // Also updates the user object with the new image. void SetToImageData(scoped_ptr<std::string> data); - // Loads the image at |path|, transcodes it to JPEG format, saves the image to - // disk and sets the user image for |user_id_| in local state to that image. - // If |resize| is true, the image is cropped and resized before transcoding. - // Also updates the |user| object for |user_id_| with the new image. + // Loads the image at |path|, transcodes it to JPEG format, saves + // the image to disk and sets the user image in local state to that + // image. If |resize| is true, the image is cropped and resized + // before transcoding. Also updates the user object with the new + // image. void SetToPath(const base::FilePath& path, int image_index, const GURL& image_url, @@ -240,31 +240,33 @@ class UserImageManagerImpl::Job { // Called back after an image has been loaded from disk. void OnLoadImageDone(bool save, const UserImage& user_image); - // Updates the |user| object for |user_id_| with |user_image_|. + // Updates the user object with |user_image_|. void UpdateUser(); // Saves |user_image_| to disk in JPEG format. Local state will be updated // when a callback indicates that the image has been saved. void SaveImageAndUpdateLocalState(); - // Called back after the |user_image_| has been saved to disk. Updates the - // user image information for |user_id_| in local state. The information is - // only updated if |success| is true (indicating that the image was saved - // successfully) or the user image is the profile image (indicating that even - // if the image could not be saved because it is not available right now, it - // will be downloaded eventually). + // Called back after the |user_image_| has been saved to + // disk. Updates the user image information in local state. The + // information is only updated if |success| is true (indicating that + // the image was saved successfully) or the user image is the + // profile image (indicating that even if the image could not be + // saved because it is not available right now, it will be + // downloaded eventually). void OnSaveImageDone(bool success); - // Updates the user image for |user_id_| in local state, setting it to - // one of the default images or the saved |user_image_|, depending on + // Updates the user image in local state, setting it to one of the + // default images or the saved |user_image_|, depending on // |image_index_|. void UpdateLocalState(); // Notifies the |parent_| that the Job is done. void NotifyJobDone(); + const std::string& user_id() const { return parent_->user_id(); } + UserImageManagerImpl* parent_; - const std::string user_id_; // Whether one of the Load*() or Set*() methods has been run already. bool run_; @@ -280,10 +282,8 @@ class UserImageManagerImpl::Job { DISALLOW_COPY_AND_ASSIGN(Job); }; -UserImageManagerImpl::Job::Job(UserImageManagerImpl* parent, - const std::string& user_id) +UserImageManagerImpl::Job::Job(UserImageManagerImpl* parent) : parent_(parent), - user_id_(user_id), run_(false), weak_factory_(this) { } @@ -406,7 +406,7 @@ void UserImageManagerImpl::Job::OnLoadImageDone(bool save, } void UserImageManagerImpl::Job::UpdateUser() { - User* user = parent_->user_manager_->FindUserAndModify(user_id_); + User* user = parent_->user_manager_->FindUserAndModify(user_id()); if (!user) return; @@ -416,13 +416,13 @@ void UserImageManagerImpl::Job::UpdateUser() { user->SetStubImage(image_index_, false); user->SetImageURL(image_url_); - parent_->OnJobChangedUserImage(user); + parent_->OnJobChangedUserImage(); } void UserImageManagerImpl::Job::SaveImageAndUpdateLocalState() { base::FilePath user_data_dir; PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); - image_path_ = user_data_dir.Append(user_id_ + kSafeImagePathExtension); + image_path_ = user_data_dir.Append(user_id() + kSafeImagePathExtension); base::PostTaskAndReplyWithResult( parent_->background_task_runner_, @@ -440,7 +440,7 @@ void UserImageManagerImpl::Job::OnSaveImageDone(bool success) { void UserImageManagerImpl::Job::UpdateLocalState() { // Ignore if data stored or cached outside the user's cryptohome is to be // treated as ephemeral. - if (parent_->user_manager_->IsUserNonCryptohomeDataEphemeral(user_id_)) + if (parent_->user_manager_->IsUserNonCryptohomeDataEphemeral(user_id())) return; scoped_ptr<base::DictionaryValue> entry(new base::DictionaryValue); @@ -450,20 +450,24 @@ void UserImageManagerImpl::Job::UpdateLocalState() { entry->Set(kImageURLNodeName, new base::StringValue(image_url_.spec())); DictionaryPrefUpdate update(g_browser_process->local_state(), kUserImageProperties); - update->SetWithoutPathExpansion(user_id_, entry.release()); + update->SetWithoutPathExpansion(user_id(), entry.release()); parent_->user_manager_->NotifyLocalStateChanged(); } void UserImageManagerImpl::Job::NotifyJobDone() { - parent_->OnJobDone(user_id_); + parent_->OnJobDone(); } -UserImageManagerImpl::UserImageManagerImpl(CrosSettings* cros_settings, +UserImageManagerImpl::UserImageManagerImpl(const std::string& user_id, + CrosSettings* cros_settings, UserManager* user_manager) - : user_manager_(user_manager), + : UserImageManager(user_id), + user_manager_(user_manager), downloading_profile_image_(false), profile_image_requested_(false), + has_managed_image_(false), + user_needs_migration_(false), weak_factory_(this) { base::SequencedWorkerPool* blocking_pool = content::BrowserThread::GetBlockingPool(); @@ -475,20 +479,11 @@ UserImageManagerImpl::UserImageManagerImpl(CrosSettings* cros_settings, background_task_runner_); unsafe_image_loader_ = new UserImageLoader(ImageDecoder::DEFAULT_CODEC, background_task_runner_); - policy_observer_.reset(new policy::CloudExternalDataPolicyObserver( - cros_settings, - user_manager, - g_browser_process->browser_policy_connector()-> - GetDeviceLocalAccountPolicyService(), - policy::key::kUserAvatarImage, - this)); - policy_observer_->Init(); } -UserImageManagerImpl::~UserImageManagerImpl() { -} +UserImageManagerImpl::~UserImageManagerImpl() {} -void UserImageManagerImpl::LoadUserImages(const UserList& users) { +void UserImageManagerImpl::LoadUserImage() { PrefService* local_state = g_browser_process->local_state(); const base::DictionaryValue* prefs_images_unsafe = local_state->GetDictionary(kUserImages); @@ -496,106 +491,98 @@ void UserImageManagerImpl::LoadUserImages(const UserList& users) { local_state->GetDictionary(kUserImageProperties); if (!prefs_images && !prefs_images_unsafe) return; + User* user = GetUserAndModify(); + bool needs_migration = false; - for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) { - User* user = *it; - const std::string& user_id = user->email(); - bool needs_migration = false; - - // If entries are found in both |prefs_images_unsafe| and |prefs_images|, - // |prefs_images| is honored for now but |prefs_images_unsafe| will be - // migrated, overwriting the |prefs_images| entry, when the user logs in. - const base::DictionaryValue* image_properties = NULL; - if (prefs_images_unsafe) { - needs_migration = prefs_images_unsafe->GetDictionaryWithoutPathExpansion( - user_id, &image_properties); - if (needs_migration) - users_to_migrate_.insert(user_id); - } - if (prefs_images) { - prefs_images->GetDictionaryWithoutPathExpansion(user_id, - &image_properties); - } + // If entries are found in both |prefs_images_unsafe| and |prefs_images|, + // |prefs_images| is honored for now but |prefs_images_unsafe| will be + // migrated, overwriting the |prefs_images| entry, when the user logs in. + const base::DictionaryValue* image_properties = NULL; + if (prefs_images_unsafe) { + needs_migration = prefs_images_unsafe->GetDictionaryWithoutPathExpansion( + user_id(), &image_properties); + if (needs_migration) + user_needs_migration_ = true; + } + if (prefs_images) { + prefs_images->GetDictionaryWithoutPathExpansion(user_id(), + &image_properties); + } - // If the user image for |user_id| is managed by policy and the policy-set - // image is being loaded and persisted right now, let that job continue. It - // will update the user image when done. - if (IsUserImageManaged(user_id) && ContainsKey(jobs_, user_id)) - continue; + // If the user image for |user_id| is managed by policy and the policy-set + // image is being loaded and persisted right now, let that job continue. It + // will update the user image when done. + if (IsUserImageManaged() && job_.get()) + return; - if (!image_properties) { - SetInitialUserImage(user_id); - continue; - } + if (!image_properties) { + SetInitialUserImage(); + return; + } - int image_index = User::kInvalidImageIndex; - image_properties->GetInteger(kImageIndexNodeName, &image_index); - if (image_index >= 0 && image_index < kDefaultImagesCount) { - user->SetImage(UserImage(GetDefaultImage(image_index)), - image_index); - continue; - } + int image_index = User::kInvalidImageIndex; + image_properties->GetInteger(kImageIndexNodeName, &image_index); + if (image_index >= 0 && image_index < kDefaultImagesCount) { + user->SetImage(UserImage(GetDefaultImage(image_index)), + image_index); + return; + } - if (image_index != User::kExternalImageIndex && - image_index != User::kProfileImageIndex) { - NOTREACHED(); - continue; - } + if (image_index != User::kExternalImageIndex && + image_index != User::kProfileImageIndex) { + NOTREACHED(); + return; + } - std::string image_url_string; - image_properties->GetString(kImageURLNodeName, &image_url_string); - GURL image_url(image_url_string); - std::string image_path; - image_properties->GetString(kImagePathNodeName, &image_path); - - user->SetImageURL(image_url); - DCHECK(!image_path.empty() || image_index == User::kProfileImageIndex); - if (image_path.empty() || needs_migration) { - // Use a stub image (gray avatar) if either of the following is true: - // * The profile image is to be used but has not been downloaded yet. The - // profile image will be downloaded after login. - // * The image needs migration. Migration will be performed after login. - user->SetStubImage(image_index, true); - continue; - } + std::string image_url_string; + image_properties->GetString(kImageURLNodeName, &image_url_string); + GURL image_url(image_url_string); + std::string image_path; + image_properties->GetString(kImagePathNodeName, &image_path); - linked_ptr<Job>& job = jobs_[user_id]; - job.reset(new Job(this, user_id)); - job->LoadImage(base::FilePath(image_path), image_index, image_url); + user->SetImageURL(image_url); + DCHECK(!image_path.empty() || image_index == User::kProfileImageIndex); + if (image_path.empty() || needs_migration) { + // Use a stub image (gray avatar) if either of the following is true: + // * The profile image is to be used but has not been downloaded yet. The + // profile image will be downloaded after login. + // * The image needs migration. Migration will be performed after login. + user->SetStubImage(image_index, true); + return; } + + job_.reset(new Job(this)); + job_->LoadImage(base::FilePath(image_path), image_index, image_url); } -void UserImageManagerImpl::UserLoggedIn(const std::string& user_id, - bool user_is_new, +void UserImageManagerImpl::UserLoggedIn(bool user_is_new, bool user_is_local) { - User* user = user_manager_->GetLoggedInUser(); + const User* user = GetUser(); if (user_is_new) { if (!user_is_local) - SetInitialUserImage(user_id); + SetInitialUserImage(); } else { UMA_HISTOGRAM_ENUMERATION("UserImage.LoggedIn", ImageIndexToHistogramIndex(user->image_index()), kHistogramImagesCount); - if (!IsUserImageManaged(user_id) && - ContainsKey(users_to_migrate_, user_id)) { + if (!IsUserImageManaged() && user_needs_migration_) { const base::DictionaryValue* prefs_images_unsafe = g_browser_process->local_state()->GetDictionary(kUserImages); const base::DictionaryValue* image_properties = NULL; if (prefs_images_unsafe->GetDictionaryWithoutPathExpansion( - user_id, &image_properties)) { + user_id(), &image_properties)) { std::string image_path; image_properties->GetString(kImagePathNodeName, &image_path); - linked_ptr<Job>& job = jobs_[user_id]; - job.reset(new Job(this, user_id)); + job_.reset(new Job(this)); if (!image_path.empty()) { VLOG(0) << "Loading old user image, then migrating it."; - job->SetToPath(base::FilePath(image_path), - user->image_index(), - user->image_url(), - false); + job_->SetToPath(base::FilePath(image_path), + user->image_index(), + user->image_url(), + false); } else { - job->SetToDefaultImage(user->image_index()); + job_->SetToDefaultImage(user->image_index()); } } } @@ -606,7 +593,7 @@ void UserImageManagerImpl::UserLoggedIn(const std::string& user_id, profile_image_url_ = GURL(); profile_image_requested_ = false; - if (user_manager_->IsLoggedInAsRegularUser()) { + if (IsUserLoggedInAndRegular()) { TryToInitDownloadedProfileImage(); // Schedule an initial download of the profile data (full name and @@ -635,55 +622,47 @@ void UserImageManagerImpl::UserLoggedIn(const std::string& user_id, TryToCreateImageSyncObserver(); } -void UserImageManagerImpl::SaveUserDefaultImageIndex(const std::string& user_id, - int default_image_index) { - if (IsUserImageManaged(user_id)) +void UserImageManagerImpl::SaveUserDefaultImageIndex(int default_image_index) { + if (IsUserImageManaged()) return; - linked_ptr<Job>& job = jobs_[user_id]; - job.reset(new Job(this, user_id)); - job->SetToDefaultImage(default_image_index); + job_.reset(new Job(this)); + job_->SetToDefaultImage(default_image_index); } -void UserImageManagerImpl::SaveUserImage(const std::string& user_id, - const UserImage& user_image) { - if (IsUserImageManaged(user_id)) +void UserImageManagerImpl::SaveUserImage(const UserImage& user_image) { + if (IsUserImageManaged()) return; - linked_ptr<Job>& job = jobs_[user_id]; - job.reset(new Job(this, user_id)); - job->SetToImage(User::kExternalImageIndex, user_image); + job_.reset(new Job(this)); + job_->SetToImage(User::kExternalImageIndex, user_image); } -void UserImageManagerImpl::SaveUserImageFromFile(const std::string& user_id, - const base::FilePath& path) { - if (IsUserImageManaged(user_id)) +void UserImageManagerImpl::SaveUserImageFromFile(const base::FilePath& path) { + if (IsUserImageManaged()) return; - linked_ptr<Job>& job = jobs_[user_id]; - job.reset(new Job(this, user_id)); - job->SetToPath(path, User::kExternalImageIndex, GURL(), true); + job_.reset(new Job(this)); + job_->SetToPath(path, User::kExternalImageIndex, GURL(), true); } -void UserImageManagerImpl::SaveUserImageFromProfileImage( - const std::string& user_id) { - if (IsUserImageManaged(user_id)) +void UserImageManagerImpl::SaveUserImageFromProfileImage() { + if (IsUserImageManaged()) return; // Use the profile image if it has been downloaded already. Otherwise, use a // stub image (gray avatar). - linked_ptr<Job>& job = jobs_[user_id]; - job.reset(new Job(this, user_id)); - job->SetToImage(User::kProfileImageIndex, - downloaded_profile_image_.isNull() ? - UserImage() : - UserImage::CreateAndEncode(downloaded_profile_image_)); + job_.reset(new Job(this)); + job_->SetToImage(User::kProfileImageIndex, + downloaded_profile_image_.isNull() ? + UserImage() : + UserImage::CreateAndEncode(downloaded_profile_image_)); // If no profile image has been downloaded yet, ensure that a download is // started. if (downloaded_profile_image_.isNull()) DownloadProfileData(kProfileDownloadReasonProfileImageChosen); } -void UserImageManagerImpl::DeleteUserImage(const std::string& user_id) { - jobs_.erase(user_id); - DeleteUserImageAndLocalStateEntry(user_id, kUserImages); - DeleteUserImageAndLocalStateEntry(user_id, kUserImageProperties); +void UserImageManagerImpl::DeleteUserImage() { + job_.reset(); + DeleteUserImageAndLocalStateEntry(kUserImages); + DeleteUserImageAndLocalStateEntry(kUserImageProperties); } void UserImageManagerImpl::DownloadProfileImage(const std::string& reason) { @@ -702,41 +681,36 @@ UserImageSyncObserver* UserImageManagerImpl::GetSyncObserver() const { void UserImageManagerImpl::Shutdown() { profile_downloader_.reset(); user_image_sync_observer_.reset(); - policy_observer_.reset(); } -void UserImageManagerImpl::OnExternalDataSet(const std::string& policy, - const std::string& user_id) { +void UserImageManagerImpl::OnExternalDataSet(const std::string& policy) { DCHECK_EQ(policy::key::kUserAvatarImage, policy); - if (IsUserImageManaged(user_id)) + if (IsUserImageManaged()) return; - users_with_managed_images_.insert(user_id); - jobs_.erase(user_id); + has_managed_image_ = true; + job_.reset(); - const User* logged_in_user = user_manager_->GetLoggedInUser(); + const User* user = GetUser(); // If the user image for the currently logged-in user became managed, stop the // sync observer so that the policy-set image does not get synced out. - if (logged_in_user && logged_in_user->email() == user_id) + if (user && user->is_logged_in()) user_image_sync_observer_.reset(); } -void UserImageManagerImpl::OnExternalDataCleared(const std::string& policy, - const std::string& user_id) { +void UserImageManagerImpl::OnExternalDataCleared(const std::string& policy) { DCHECK_EQ(policy::key::kUserAvatarImage, policy); - users_with_managed_images_.erase(user_id); + has_managed_image_ = false; TryToCreateImageSyncObserver(); } void UserImageManagerImpl::OnExternalDataFetched(const std::string& policy, - const std::string& user_id, scoped_ptr<std::string> data) { DCHECK_EQ(policy::key::kUserAvatarImage, policy); - DCHECK(IsUserImageManaged(user_id)); + DCHECK(IsUserImageManaged()); if (data) { - linked_ptr<Job>& job = jobs_[user_id]; - job.reset(new Job(this, user_id)); - job->SetToImageData(data.Pass()); + job_.reset(new Job(this)); + job_->SetToImageData(data.Pass()); } } @@ -745,10 +719,6 @@ void UserImageManagerImpl::IgnoreProfileDataDownloadDelayForTesting() { g_ignore_profile_data_download_delay_ = true; } -void UserImageManagerImpl::StopPolicyObserverForTesting() { - policy_observer_.reset(); -} - bool UserImageManagerImpl::NeedsProfilePicture() const { return downloading_profile_image_; } @@ -758,7 +728,7 @@ int UserImageManagerImpl::GetDesiredImageSideLength() const { } Profile* UserImageManagerImpl::GetBrowserProfile() { - return ProfileManager::GetDefaultProfile(); + return user_manager_->GetProfileByUser(GetUser()); } std::string UserImageManagerImpl::GetCachedPictureURL() const { @@ -772,11 +742,8 @@ void UserImageManagerImpl::OnProfileDownloadSuccess( profile_downloader_.release()); DCHECK_EQ(downloader, profile_downloader.get()); - const User* user = user_manager_->GetLoggedInUser(); - const std::string& user_id = user->email(); - user_manager_->UpdateUserAccountData( - user_id, + user_id(), UserManager::UserAccountData(downloader->GetProfileFullName(), downloader->GetProfileGivenName(), downloader->GetProfileLocale())); @@ -828,13 +795,14 @@ void UserImageManagerImpl::OnProfileDownloadSuccess( downloader->GetProfilePicture()); profile_image_url_ = GURL(downloader->GetProfilePictureURL()); + const User* user = GetUser(); if (user->image_index() == User::kProfileImageIndex) { VLOG(1) << "Updating profile image for logged-in user."; UMA_HISTOGRAM_ENUMERATION("UserImage.ProfileDownloadResult", kDownloadSuccessChanged, kDownloadResultsCount); // This will persist |downloaded_profile_image_| to disk. - SaveUserImageFromProfileImage(user_id); + SaveUserImageFromProfileImage(); } content::NotificationService::current()->Notify( @@ -876,20 +844,18 @@ void UserImageManagerImpl::OnProfileDownloadFailure( content::NotificationService::NoDetails()); } -bool UserImageManagerImpl::IsUserImageManaged( - const std::string& user_id) const { - return ContainsKey(users_with_managed_images_, user_id); +bool UserImageManagerImpl::IsUserImageManaged() const { + return has_managed_image_; } -void UserImageManagerImpl::SetInitialUserImage(const std::string& user_id) { +void UserImageManagerImpl::SetInitialUserImage() { // Choose a random default image. - SaveUserDefaultImageIndex(user_id, - base::RandInt(kFirstDefaultImageIndex, + SaveUserDefaultImageIndex(base::RandInt(kFirstDefaultImageIndex, kDefaultImagesCount - 1)); } void UserImageManagerImpl::TryToInitDownloadedProfileImage() { - const User* user = user_manager_->GetLoggedInUser(); + const User* user = GetUser(); if (user->image_index() == User::kProfileImageIndex && downloaded_profile_image_.isNull() && !user->image_is_stub()) { @@ -903,15 +869,15 @@ void UserImageManagerImpl::TryToInitDownloadedProfileImage() { } bool UserImageManagerImpl::NeedProfileImage() const { - return user_manager_->IsLoggedInAsRegularUser() && - (user_manager_->GetLoggedInUser()->image_index() == - User::kProfileImageIndex || - profile_image_requested_); + const User* user = GetUser(); + return IsUserLoggedInAndRegular() && + (user->image_index() == User::kProfileImageIndex || + profile_image_requested_); } void UserImageManagerImpl::DownloadProfileData(const std::string& reason) { // GAIA profiles exist for regular users only. - if (!user_manager_->IsLoggedInAsRegularUser()) + if (!IsUserLoggedInAndRegular()) return; // If a download is already in progress, allow it to continue, with one @@ -931,12 +897,11 @@ void UserImageManagerImpl::DownloadProfileData(const std::string& reason) { } void UserImageManagerImpl::DeleteUserImageAndLocalStateEntry( - const std::string& user_id, const char* prefs_dict_root) { DictionaryPrefUpdate update(g_browser_process->local_state(), prefs_dict_root); const base::DictionaryValue* image_properties; - if (!update->GetDictionaryWithoutPathExpansion(user_id, &image_properties)) + if (!update->GetDictionaryWithoutPathExpansion(user_id(), &image_properties)) return; std::string image_path; @@ -948,40 +913,35 @@ void UserImageManagerImpl::DeleteUserImageAndLocalStateEntry( base::FilePath(image_path), false)); } - update->RemoveWithoutPathExpansion(user_id, NULL); + update->RemoveWithoutPathExpansion(user_id(), NULL); } -void UserImageManagerImpl::OnJobChangedUserImage(const User* user) { - if (user == user_manager_->GetLoggedInUser()) +void UserImageManagerImpl::OnJobChangedUserImage() { + if (GetUser()->is_logged_in()) TryToInitDownloadedProfileImage(); content::NotificationService::current()->Notify( chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED, content::Source<UserImageManagerImpl>(this), - content::Details<const User>(user)); + content::Details<const User>(GetUser())); } -void UserImageManagerImpl::OnJobDone(const std::string& user_id) { - std::map<std::string, linked_ptr<Job> >::iterator it = - jobs_.find(user_id); - if (it != jobs_.end()) { - base::MessageLoopProxy::current()->DeleteSoon(FROM_HERE, - it->second.release()); - jobs_.erase(it); - } else { +void UserImageManagerImpl::OnJobDone() { + if (job_.get()) + base::MessageLoopProxy::current()->DeleteSoon(FROM_HERE, job_.release()); + else NOTREACHED(); - } - if (!ContainsKey(users_to_migrate_, user_id)) + if (!user_needs_migration_) return; // Migration completed for |user_id|. - users_to_migrate_.erase(user_id); + user_needs_migration_ = false; const base::DictionaryValue* prefs_images_unsafe = g_browser_process->local_state()->GetDictionary(kUserImages); const base::DictionaryValue* image_properties = NULL; if (!prefs_images_unsafe->GetDictionaryWithoutPathExpansion( - user_id, &image_properties)) { + user_id(), &image_properties)) { NOTREACHED(); return; } @@ -1006,32 +966,45 @@ void UserImageManagerImpl::OnJobDone(const std::string& user_id) { base::FilePath(image_path), false), base::Bind(&UserImageManagerImpl::UpdateLocalStateAfterMigration, - weak_factory_.GetWeakPtr(), - user_id)); + weak_factory_.GetWeakPtr())); } else { // If no old image exists, remove |user_id| from the old prefs dictionary. - UpdateLocalStateAfterMigration(user_id); + UpdateLocalStateAfterMigration(); } } -void UserImageManagerImpl::UpdateLocalStateAfterMigration( - const std::string& user_id) { +void UserImageManagerImpl::UpdateLocalStateAfterMigration() { DictionaryPrefUpdate update(g_browser_process->local_state(), kUserImages); - update->RemoveWithoutPathExpansion(user_id, NULL); + update->RemoveWithoutPathExpansion(user_id(), NULL); } void UserImageManagerImpl::TryToCreateImageSyncObserver() { - const User* user = user_manager_->GetLoggedInUser(); + const User* user = GetUser(); // If the currently logged-in user's user image is managed, the sync observer // must not be started so that the policy-set image does not get synced out. if (!user_image_sync_observer_ && user && user->CanSyncImage() && - !IsUserImageManaged(user->email()) && + !IsUserImageManaged() && !CommandLine::ForCurrentProcess()->HasSwitch( chromeos::switches::kDisableUserImageSync)) { user_image_sync_observer_.reset(new UserImageSyncObserver(user)); } } +const User* UserImageManagerImpl::GetUser() const { + return user_manager_->FindUser(user_id()); +} + +User* UserImageManagerImpl::GetUserAndModify() const { + return user_manager_->FindUserAndModify(user_id()); +} + +bool UserImageManagerImpl::IsUserLoggedInAndRegular() const { + const User* user = GetUser(); + if (!user) + return false; + return user->is_logged_in() && user->GetType() == User::USER_TYPE_REGULAR; +} + } // namespace chromeos diff --git a/chrome/browser/chromeos/login/user_image_manager_impl.h b/chrome/browser/chromeos/login/user_image_manager_impl.h index e587151..c75555a 100644 --- a/chrome/browser/chromeos/login/user_image_manager_impl.h +++ b/chrome/browser/chromeos/login/user_image_manager_impl.h @@ -11,7 +11,6 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" -#include "base/memory/linked_ptr.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" @@ -21,7 +20,6 @@ #include "chrome/browser/chromeos/login/user.h" #include "chrome/browser/chromeos/login/user_image_loader.h" #include "chrome/browser/chromeos/login/user_image_manager.h" -#include "chrome/browser/chromeos/policy/cloud_external_data_policy_observer.h" #include "chrome/browser/profiles/profile_downloader_delegate.h" #include "ui/gfx/image/image_skia.h" @@ -41,42 +39,32 @@ class UserManager; class UserImageManagerImpl : public UserImageManager, - public ProfileDownloaderDelegate, - public policy::CloudExternalDataPolicyObserver::Delegate { + public ProfileDownloaderDelegate { public: - UserImageManagerImpl(CrosSettings* cros_settings, UserManager* user_manager); - // UserImageManager: + UserImageManagerImpl(const std::string& user_id, + CrosSettings* cros_settings, + UserManager* user_manager); virtual ~UserImageManagerImpl(); - virtual void LoadUserImages(const UserList& users) OVERRIDE; - virtual void UserLoggedIn(const std::string& user_id, - bool user_is_new, - bool user_is_local) OVERRIDE; - virtual void SaveUserDefaultImageIndex(const std::string& user_id, - int default_image_index) OVERRIDE; - virtual void SaveUserImage(const std::string& user_id, - const UserImage& user_image) OVERRIDE; - virtual void SaveUserImageFromFile(const std::string& user_id, - const base::FilePath& path) OVERRIDE; - virtual void SaveUserImageFromProfileImage( - const std::string& user_id) OVERRIDE; - virtual void DeleteUserImage(const std::string& user_id) OVERRIDE; + + virtual void LoadUserImage() OVERRIDE; + virtual void UserLoggedIn(bool user_is_new, bool user_is_local) OVERRIDE; + virtual void SaveUserDefaultImageIndex(int default_image_index) OVERRIDE; + virtual void SaveUserImage(const UserImage& user_image) OVERRIDE; + virtual void SaveUserImageFromFile(const base::FilePath& path) OVERRIDE; + virtual void SaveUserImageFromProfileImage() OVERRIDE; + virtual void DeleteUserImage() OVERRIDE; virtual void DownloadProfileImage(const std::string& reason) OVERRIDE; virtual const gfx::ImageSkia& DownloadedProfileImage() const OVERRIDE; virtual UserImageSyncObserver* GetSyncObserver() const OVERRIDE; virtual void Shutdown() OVERRIDE; - // policy::CloudExternalDataPolicyObserver::Delegate: - virtual void OnExternalDataSet(const std::string& policy, - const std::string& user_id) OVERRIDE; - virtual void OnExternalDataCleared(const std::string& policy, - const std::string& user_id) OVERRIDE; + virtual void OnExternalDataSet(const std::string& policy) OVERRIDE; + virtual void OnExternalDataCleared(const std::string& policy) OVERRIDE; virtual void OnExternalDataFetched(const std::string& policy, - const std::string& user_id, scoped_ptr<std::string> data) OVERRIDE; static void IgnoreProfileDataDownloadDelayForTesting(); - void StopPolicyObserverForTesting(); private: friend class UserImageManagerTest; @@ -104,13 +92,13 @@ class UserImageManagerImpl ProfileDownloader* downloader, ProfileDownloaderDelegate::FailureReason reason) OVERRIDE; - // Returns true if the user image for |user_id| is managed by policy and the - // user is not allowed to change it. - bool IsUserImageManaged(const std::string& user_id) const; + // Returns true if the user image for the user is managed by + // policy and the user is not allowed to change it. + bool IsUserImageManaged() const; // Randomly chooses one of the default images for the specified user, sends a // LOGIN_USER_IMAGE_CHANGED notification and updates local state. - void SetInitialUserImage(const std::string& user_id); + void SetInitialUserImage(); // Initializes the |downloaded_profile_image_| for the currently logged-in // user to a profile image that had been downloaded and saved before if such @@ -130,28 +118,38 @@ class UserImageManagerImpl // with download times). void DownloadProfileData(const std::string& reason); - // Removes |user_id| from the dictionary |prefs_dict_root| in local state and - // deletes the image file that the dictionary referenced for that user. - void DeleteUserImageAndLocalStateEntry(const std::string& user_id, - const char* prefs_dict_root); + // Removes ther user from the dictionary |prefs_dict_root| in + // local state and deletes the image file that the dictionary + // referenced for that user. + void DeleteUserImageAndLocalStateEntry(const char* prefs_dict_root); - // Called when a Job updates the copy of the user image held in memory by - // |user|. Allows |this| to update |downloaded_profile_image_| and send a - // NOTIFICATION_LOGIN_USER_IMAGE_CHANGED notification. - void OnJobChangedUserImage(const User* user); + // Called when a Job updates the copy of the user image held in + // memory. Allows |this| to update |downloaded_profile_image_| and + // send a NOTIFICATION_LOGIN_USER_IMAGE_CHANGED notification. + void OnJobChangedUserImage(); - // Called when a Job for |user_id| finishes. If a migration was required for - // the user, the migration is now complete and the old image file for that - // user, if any, is deleted. - void OnJobDone(const std::string& user_id); + // Called when a Job for the user finishes. If a migration was + // required for the user, the migration is now complete and the old + // image file for that user, if any, is deleted. + void OnJobDone(); - // Completes migration by removing |user_id| from the old prefs dictionary. - void UpdateLocalStateAfterMigration(const std::string& user_id); + // Completes migration by removing the user from the old prefs + // dictionary. + void UpdateLocalStateAfterMigration(); // Create a sync observer if a user is logged in, the user's user image is // allowed to be synced and no sync observer exists yet. void TryToCreateImageSyncObserver(); + // Returns immutable version of user with |user_id_|. + const User* GetUser() const; + + // Returns mutable version of user with |user_id_|. + User* GetUserAndModify() const; + + // Returns true if user with |user_id_| is logged in and a regular user. + bool IsUserLoggedInAndRegular() const; + // The user manager. UserManager* user_manager_; @@ -175,7 +173,7 @@ class UserImageManagerImpl // currently in progress and |downloading_profile_image_| is true. base::TimeTicks profile_image_load_start_time_; - // Downloader for the current user's profile data. NULL when no download is + // Downloader for the user's profile data. NULL when no download is // currently in progress. scoped_ptr<ProfileDownloader> profile_downloader_; @@ -204,25 +202,18 @@ class UserImageManagerImpl // stays up to date. base::RepeatingTimer<UserImageManagerImpl> profile_download_periodic_timer_; - // Users whose user images need to be migrated from the old dictionary pref to - // the new dictionary pref, converting any non-default images to JPEG format. - std::set<std::string> users_to_migrate_; - // Sync observer for the currently logged-in user. scoped_ptr<UserImageSyncObserver> user_image_sync_observer_; - // Observer for the policy that can be used to manage user images. - scoped_ptr<policy::CloudExternalDataPolicyObserver> policy_observer_; - // Background task runner on which Jobs perform file I/O and the image // decoders run. scoped_refptr<base::SequencedTaskRunner> background_task_runner_; - // The currently running jobs. - std::map<std::string, linked_ptr<Job> > jobs_; + // The currently running job. + scoped_ptr<Job> job_; - // List of user_ids whose user image is managed by policy. - std::set<std::string> users_with_managed_images_; + bool has_managed_image_; + bool user_needs_migration_; base::WeakPtrFactory<UserImageManagerImpl> weak_factory_; diff --git a/chrome/browser/chromeos/login/user_image_sync_observer.cc b/chrome/browser/chromeos/login/user_image_sync_observer.cc index 0d3128b..c699a60 100644 --- a/chrome/browser/chromeos/login/user_image_sync_observer.cc +++ b/chrome/browser/chromeos/login/user_image_sync_observer.cc @@ -171,7 +171,7 @@ void UserImageSyncObserver::UpdateSyncedImageFromLocal() { DictionaryPrefUpdate update(prefs_, kUserImageInfo); base::DictionaryValue* dict = update.Get(); dict->SetInteger(kImageIndex, local_index); - LOG(INFO) << "Saved avatar index " << local_index << " to sync."; + VLOG(1) << "Saved avatar index " << local_index << " to sync."; } void UserImageSyncObserver::UpdateLocalImageFromSynced() { @@ -180,13 +180,14 @@ void UserImageSyncObserver::UpdateLocalImageFromSynced() { int local_index = user_->image_index(); if ((synced_index == local_index) || !IsIndexSupported(synced_index)) return; - UserImageManager* image_manager = UserManager::Get()->GetUserImageManager(); + UserImageManager* image_manager = + UserManager::Get()->GetUserImageManager(user_->email()); if (synced_index == User::kProfileImageIndex) { - image_manager->SaveUserImageFromProfileImage(user_->email()); + image_manager->SaveUserImageFromProfileImage(); } else { - image_manager->SaveUserDefaultImageIndex(user_->email(), synced_index); + image_manager->SaveUserDefaultImageIndex(synced_index); } - LOG(INFO) << "Loaded avatar index " << synced_index << " from sync."; + VLOG(1) << "Loaded avatar index " << synced_index << " from sync."; } bool UserImageSyncObserver::GetSyncedImageIndex(int* index) { diff --git a/chrome/browser/chromeos/login/user_manager.h b/chrome/browser/chromeos/login/user_manager.h index c52e6f9..d28a12a 100644 --- a/chrome/browser/chromeos/login/user_manager.h +++ b/chrome/browser/chromeos/login/user_manager.h @@ -122,7 +122,7 @@ class UserManager { virtual ~UserManager(); - virtual UserImageManager* GetUserImageManager() = 0; + virtual UserImageManager* GetUserImageManager(const std::string& user_id) = 0; virtual SupervisedUserManager* GetSupervisedUserManager() = 0; // Returns a list of users who have logged into this device previously. This diff --git a/chrome/browser/chromeos/login/user_manager_impl.cc b/chrome/browser/chromeos/login/user_manager_impl.cc index 3bbeddf4e..9264644 100644 --- a/chrome/browser/chromeos/login/user_manager_impl.cc +++ b/chrome/browser/chromeos/login/user_manager_impl.cc @@ -189,7 +189,6 @@ UserManagerImpl::UserManagerImpl() is_current_user_new_(false), is_current_user_ephemeral_regular_user_(false), ephemeral_users_enabled_(false), - user_image_manager_(new UserImageManagerImpl(cros_settings_, this)), supervised_user_manager_(new SupervisedUserManagerImpl(this)), manager_creation_time_(base::TimeTicks::Now()), multi_profile_first_run_notification_( @@ -214,6 +213,15 @@ UserManagerImpl::UserManagerImpl() base::Unretained(this))); multi_profile_user_controller_.reset(new MultiProfileUserController( this, g_browser_process->local_state())); + policy_observer_.reset(new policy::CloudExternalDataPolicyObserver( + cros_settings_, + this, + g_browser_process->browser_policy_connector()-> + GetDeviceLocalAccountPolicyService(), + policy::key::kUserAvatarImage, + this)); + policy_observer_->Init(); + UpdateLoginState(); } @@ -242,12 +250,26 @@ void UserManagerImpl::Shutdown() { if (device_local_account_policy_service_) device_local_account_policy_service_->RemoveObserver(this); - user_image_manager_->Shutdown(); + for (UserImageManagerMap::iterator it = user_image_managers_.begin(), + ie = user_image_managers_.end(); + it != ie; ++it) { + it->second->Shutdown(); + } multi_profile_user_controller_.reset(); + policy_observer_.reset(); } -UserImageManager* UserManagerImpl::GetUserImageManager() { - return user_image_manager_.get(); +UserImageManager* UserManagerImpl::GetUserImageManager( + const std::string& user_id) { + UserImageManagerMap::iterator ui = user_image_managers_.find(user_id); + if (ui != user_image_managers_.end()) + return ui->second.get(); + linked_ptr<UserImageManagerImpl> mgr(new UserImageManagerImpl( + user_id, + cros_settings_, + this)); + user_image_managers_[user_id] = mgr; + return mgr.get(); } SupervisedUserManager* UserManagerImpl::GetSupervisedUserManager() { @@ -784,6 +806,10 @@ bool UserManagerImpl::RespectLocalePreference( return true; } +void UserManagerImpl::StopPolicyObserverForTesting() { + policy_observer_.reset(); +} + void UserManagerImpl::Observe(int type, const content::NotificationSource& source, const content::NotificationDetails& details) { @@ -826,6 +852,22 @@ void UserManagerImpl::Observe(int type, } } +void UserManagerImpl::OnExternalDataSet(const std::string& policy, + const std::string& user_id) { + GetUserImageManager(user_id)->OnExternalDataSet(policy); +} + +void UserManagerImpl::OnExternalDataCleared(const std::string& policy, + const std::string& user_id) { + GetUserImageManager(user_id)->OnExternalDataCleared(policy); +} + +void UserManagerImpl::OnExternalDataFetched(const std::string& policy, + const std::string& user_id, + scoped_ptr<std::string> data) { + GetUserImageManager(user_id)->OnExternalDataFetched(policy, data.Pass()); +} + void UserManagerImpl::OnPolicyUpdated(const std::string& user_id) { UpdatePublicAccountDisplayName(user_id); NotifyUserListChanged(); @@ -1083,7 +1125,10 @@ void UserManagerImpl::EnsureUsersLoaded() { } user_loading_stage_ = STAGE_LOADED; - user_image_manager_->LoadUserImages(users_); + for (UserList::iterator ui = users_.begin(), ue = users_.end(); + ui != ue; ++ui) { + GetUserImageManager((*ui)->email())->LoadUserImage(); + } } void UserManagerImpl::RetrieveTrustedDevicePolicies() { @@ -1208,7 +1253,7 @@ void UserManagerImpl::RegularUserLoggedIn(const std::string& user_id) { AddUserRecord(active_user_); - user_image_manager_->UserLoggedIn(user_id, is_current_user_new_, false); + GetUserImageManager(user_id)->UserLoggedIn(is_current_user_new_, false); WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded(); @@ -1222,7 +1267,7 @@ void UserManagerImpl::RegularUserLoggedInAsEphemeral( is_current_user_new_ = true; is_current_user_ephemeral_regular_user_ = true; active_user_ = User::CreateRegularUser(user_id); - user_image_manager_->UserLoggedIn(user_id, is_current_user_new_, false); + GetUserImageManager(user_id)->UserLoggedIn(is_current_user_new_, false); WallpaperManager::Get()->SetInitialUserWallpaper(user_id, false); } @@ -1259,7 +1304,7 @@ void UserManagerImpl::LocallyManagedUserLoggedIn( active_user_->GetDisplayName()); } - user_image_manager_->UserLoggedIn(user_id, is_current_user_new_, true); + GetUserImageManager(user_id)->UserLoggedIn(is_current_user_new_, true); WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded(); // Make sure that new data is persisted to Local State. @@ -1272,7 +1317,7 @@ void UserManagerImpl::PublicAccountUserLoggedIn(User* user) { // The UserImageManager chooses a random avatar picture when a user logs in // for the first time. Tell the UserImageManager that this user is not new to // prevent the avatar from getting changed. - user_image_manager_->UserLoggedIn(user->email(), false, true); + GetUserImageManager(user->email())->UserLoggedIn(false, true); WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded(); } @@ -1324,9 +1369,9 @@ void UserManagerImpl::RetailModeUserLoggedIn() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); is_current_user_new_ = true; active_user_ = User::CreateRetailModeUser(); - user_image_manager_->UserLoggedIn(UserManager::kRetailModeUserName, - is_current_user_new_, - true); + GetUserImageManager(UserManager::kRetailModeUserName)->UserLoggedIn( + is_current_user_new_, + true); WallpaperManager::Get()->SetInitialUserWallpaper( UserManager::kRetailModeUserName, false); } @@ -1362,7 +1407,7 @@ void UserManagerImpl::UpdateOwnership() { void UserManagerImpl::RemoveNonCryptohomeData(const std::string& user_id) { WallpaperManager::Get()->RemoveUserWallpaperInfo(user_id); - user_image_manager_->DeleteUserImage(user_id); + GetUserImageManager(user_id)->DeleteUserImage(); PrefService* prefs = g_browser_process->local_state(); DictionaryPrefUpdate prefs_oauth_update(prefs, kUserOAuthTokenStatus); @@ -1487,14 +1532,14 @@ bool UserManagerImpl::UpdateAndCleanUpPublicAccounts( ListPrefUpdate prefs_public_accounts_update(g_browser_process->local_state(), kPublicAccounts); prefs_public_accounts_update->Clear(); - for (std::vector<std::string>::const_iterator - it = new_public_accounts.begin(); + for (std::vector<std::string>::const_iterator it = + new_public_accounts.begin(); it != new_public_accounts.end(); ++it) { prefs_public_accounts_update->AppendString(*it); } // Remove the old public accounts from the user list. - for (UserList::iterator it = users_.begin(); it != users_.end(); ) { + for (UserList::iterator it = users_.begin(); it != users_.end();) { if ((*it)->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT) { if (*it != GetLoggedInUser()) delete *it; @@ -1505,8 +1550,8 @@ bool UserManagerImpl::UpdateAndCleanUpPublicAccounts( } // Add the new public accounts to the front of the user list. - for (std::vector<std::string>::const_reverse_iterator - it = new_public_accounts.rbegin(); + for (std::vector<std::string>::const_reverse_iterator it = + new_public_accounts.rbegin(); it != new_public_accounts.rend(); ++it) { if (IsLoggedInAsPublicAccount() && *it == GetActiveUser()->email()) users_.insert(users_.begin(), GetLoggedInUser()); @@ -1515,8 +1560,11 @@ bool UserManagerImpl::UpdateAndCleanUpPublicAccounts( UpdatePublicAccountDisplayName(*it); } - user_image_manager_->LoadUserImages( - UserList(users_.begin(), users_.begin() + new_public_accounts.size())); + for (UserList::iterator ui = users_.begin(), + ue = users_.begin() + new_public_accounts.size(); + ui != ue; ++ui) { + GetUserImageManager((*ui)->email())->LoadUserImage(); + } // Remove data belonging to public accounts that are no longer found on the // user list. diff --git a/chrome/browser/chromeos/login/user_manager_impl.h b/chrome/browser/chromeos/login/user_manager_impl.h index 7a397e2..a901075 100644 --- a/chrome/browser/chromeos/login/user_manager_impl.h +++ b/chrome/browser/chromeos/login/user_manager_impl.h @@ -10,6 +10,8 @@ #include <vector> #include "base/basictypes.h" +#include "base/containers/hash_tables.h" +#include "base/memory/linked_ptr.h" #include "base/memory/scoped_ptr.h" #include "base/observer_list.h" #include "base/synchronization/lock.h" @@ -20,6 +22,7 @@ #include "chrome/browser/chromeos/login/user_image_manager_impl.h" #include "chrome/browser/chromeos/login/user_manager.h" #include "chrome/browser/chromeos/login/wallpaper_manager.h" +#include "chrome/browser/chromeos/policy/cloud_external_data_policy_observer.h" #include "chrome/browser/chromeos/policy/device_local_account_policy_service.h" #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/chromeos/settings/device_settings_service.h" @@ -51,6 +54,7 @@ class UserManagerImpl : public UserManager, public LoginUtils::Delegate, public content::NotificationObserver, + public policy::CloudExternalDataPolicyObserver::Delegate, public policy::DeviceLocalAccountPolicyService::Observer, public MultiProfileUserControllerDelegate { public: @@ -58,7 +62,8 @@ class UserManagerImpl // UserManager implementation: virtual void Shutdown() OVERRIDE; - virtual UserImageManager* GetUserImageManager() OVERRIDE; + virtual UserImageManager* GetUserImageManager( + const std::string& user_id) OVERRIDE; virtual SupervisedUserManager* GetSupervisedUserManager() OVERRIDE; virtual const UserList& GetUsers() const OVERRIDE; virtual UserList GetUsersAdmittedForMultiProfile() const OVERRIDE; @@ -143,6 +148,15 @@ class UserManagerImpl const content::NotificationSource& source, const content::NotificationDetails& details) OVERRIDE; + // policy::CloudExternalDataPolicyObserver::Delegate: + virtual void OnExternalDataSet(const std::string& policy, + const std::string& user_id) OVERRIDE; + virtual void OnExternalDataCleared(const std::string& policy, + const std::string& user_id) OVERRIDE; + virtual void OnExternalDataFetched(const std::string& policy, + const std::string& user_id, + scoped_ptr<std::string> data) OVERRIDE; + // policy::DeviceLocalAccountPolicyService::Observer implementation. virtual void OnPolicyUpdated(const std::string& user_id) OVERRIDE; virtual void OnDeviceLocalAccountsChanged() OVERRIDE; @@ -152,6 +166,8 @@ class UserManagerImpl const User* user, scoped_ptr<locale_util::SwitchLanguageCallback> callback) const OVERRIDE; + void StopPolicyObserverForTesting(); + private: friend class extensions::ExternalComponentLoaderTest; friend class SupervisedUserManagerImpl; @@ -160,6 +176,9 @@ class UserManagerImpl friend class UserManagerTest; friend class WallpaperManagerTest; + typedef base::hash_map<std::string, + linked_ptr<UserImageManager> > UserImageManagerMap; + // Stages of loading user list from preferences. Some methods can have // different behavior depending on stage. enum UserLoadStage { @@ -414,8 +433,8 @@ class UserManagerImpl ObserverList<UserManager::UserSessionStateObserver> session_state_observer_list_; - // User avatar manager. - scoped_ptr<UserImageManagerImpl> user_image_manager_; + // User avatar managers. + UserImageManagerMap user_image_managers_; // Supervised user manager. scoped_ptr<SupervisedUserManagerImpl> supervised_user_manager_; @@ -448,6 +467,9 @@ class UserManagerImpl scoped_ptr<MultiProfileFirstRunNotification> multi_profile_first_run_notification_; + // Observer for the policy that can be used to manage user images. + scoped_ptr<policy::CloudExternalDataPolicyObserver> policy_observer_; + DISALLOW_COPY_AND_ASSIGN(UserManagerImpl); }; diff --git a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc index 2744cce..2e90224 100644 --- a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc +++ b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc @@ -42,6 +42,7 @@ #include "chrome/browser/chromeos/login/user_image_manager_impl.h" #include "chrome/browser/chromeos/login/user_image_manager_test_util.h" #include "chrome/browser/chromeos/login/user_manager.h" +#include "chrome/browser/chromeos/login/user_manager_impl.h" #include "chrome/browser/chromeos/login/webui_login_view.h" #include "chrome/browser/chromeos/login/wizard_controller.h" #include "chrome/browser/chromeos/policy/cloud_external_data_manager_base_test_util.h" @@ -835,16 +836,14 @@ IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DISABLED_ExtensionsCached) { EXPECT_FALSE(PathExists(cached_extension)); } -// http://crbug.com/330454 -IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DISABLED_ExternalData) { - // chromeos::UserImageManagerImpl requests an external data fetch whenever the - // key::kUserAvatarImage policy is set. Since this test wants to verify that - // the underlying policy subsystem will start a fetch without this request as - // well, the chromeos::UserImageManagerImpl must be prevented from seeing the - // policy change. - reinterpret_cast<chromeos::UserImageManagerImpl*>( - chromeos::UserManager::Get()->GetUserImageManager())-> - StopPolicyObserverForTesting(); +IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, ExternalData) { + // chromeos::UserManager requests an external data fetch whenever + // the key::kUserAvatarImage policy is set. Since this test wants to + // verify that the underlying policy subsystem will start a fetch + // without this request as well, the chromeos::UserManager must be + // prevented from seeing the policy change. + reinterpret_cast<chromeos::UserManagerImpl*>(chromeos::UserManager::Get())-> + StopPolicyObserverForTesting(); UploadDeviceLocalAccountPolicy(); AddPublicSessionToDevicePolicy(kAccountId1); diff --git a/chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.cc index e800749..b8f46fd 100644 --- a/chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.cc +++ b/chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.cc @@ -270,8 +270,7 @@ void ChangePictureOptionsHandler::SendProfileImage(const gfx::ImageSkia& image, void ChangePictureOptionsHandler::UpdateProfileImage() { UserImageManager* user_image_manager = - UserManager::Get()->GetUserImageManager(); - + UserManager::Get()->GetUserImageManager(GetUser()->email()); // If we have a downloaded profile image and haven't sent it in // |SendSelectedImage|, send it now (without selecting). if (previous_image_index_ != User::kProfileImageIndex && @@ -301,9 +300,8 @@ void ChangePictureOptionsHandler::HandleSelectImage( DCHECK(!image_url.empty()); DCHECK(!image_type.empty()); - const User* user = GetUser(); UserImageManager* user_image_manager = - UserManager::Get()->GetUserImageManager(); + UserManager::Get()->GetUserImageManager(GetUser()->email()); int image_index = User::kInvalidImageIndex; bool waiting_for_camera_photo = false; @@ -311,7 +309,7 @@ void ChangePictureOptionsHandler::HandleSelectImage( // Previous image (from camera or manually uploaded) re-selected. DCHECK(!previous_image_.isNull()); user_image_manager->SaveUserImage( - user->email(), UserImage::CreateAndEncode(previous_image_)); + UserImage::CreateAndEncode(previous_image_)); UMA_HISTOGRAM_ENUMERATION("UserImage.ChangeChoice", kHistogramImageOld, @@ -320,7 +318,7 @@ void ChangePictureOptionsHandler::HandleSelectImage( } else if (image_type == "default" && IsDefaultImageUrl(image_url, &image_index)) { // One of the default user images. - user_image_manager->SaveUserDefaultImageIndex(user->email(), image_index); + user_image_manager->SaveUserDefaultImageIndex(image_index); UMA_HISTOGRAM_ENUMERATION("UserImage.ChangeChoice", GetDefaultImageHistogramValue(image_index), @@ -337,7 +335,7 @@ void ChangePictureOptionsHandler::HandleSelectImage( } } else if (image_type == "profile") { // Profile image selected. Could be previous (old) user image. - user_image_manager->SaveUserImageFromProfileImage(user->email()); + user_image_manager->SaveUserImageFromProfileImage(); if (previous_image_index_ == User::kProfileImageIndex) { UMA_HISTOGRAM_ENUMERATION("UserImage.ChangeChoice", @@ -363,8 +361,8 @@ void ChangePictureOptionsHandler::FileSelected(const base::FilePath& path, int index, void* params) { UserManager* user_manager = UserManager::Get(); - user_manager->GetUserImageManager()->SaveUserImageFromFile(GetUser()->email(), - path); + user_manager->GetUserImageManager(GetUser()->email())-> + SaveUserImageFromFile(path); UMA_HISTOGRAM_ENUMERATION( "UserImage.ChangeChoice", kHistogramImageFromFile, kHistogramImagesCount); VLOG(1) << "Selected image from file"; @@ -373,8 +371,8 @@ void ChangePictureOptionsHandler::FileSelected(const base::FilePath& path, void ChangePictureOptionsHandler::SetImageFromCamera( const gfx::ImageSkia& photo) { UserManager* user_manager = UserManager::Get(); - user_manager->GetUserImageManager()->SaveUserImage( - GetUser()->email(), UserImage::CreateAndEncode(photo)); + user_manager->GetUserImageManager(GetUser()->email())->SaveUserImage( + UserImage::CreateAndEncode(photo)); UMA_HISTOGRAM_ENUMERATION("UserImage.ChangeChoice", kHistogramImageFromCamera, kHistogramImagesCount); |