Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 #ifndef CHROME_BROWSER_CHROMEOS_LOGIN_USER_IMAGE_MANAGER_IMPL_H_ | 5 #ifndef CHROME_BROWSER_CHROMEOS_LOGIN_USER_IMAGE_MANAGER_IMPL_H_ |
| 6 #define CHROME_BROWSER_CHROMEOS_LOGIN_USER_IMAGE_MANAGER_IMPL_H_ | 6 #define CHROME_BROWSER_CHROMEOS_LOGIN_USER_IMAGE_MANAGER_IMPL_H_ |
| 7 | 7 |
| 8 #include <map> | |
| 8 #include <set> | 9 #include <set> |
| 9 #include <string> | 10 #include <string> |
| 10 | 11 |
| 11 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
| 13 #include "base/memory/linked_ptr.h" | |
| 12 #include "base/memory/ref_counted.h" | 14 #include "base/memory/ref_counted.h" |
| 13 #include "base/memory/scoped_ptr.h" | 15 #include "base/memory/scoped_ptr.h" |
| 16 #include "base/memory/weak_ptr.h" | |
| 14 #include "base/time/time.h" | 17 #include "base/time/time.h" |
| 15 #include "base/timer/timer.h" | 18 #include "base/timer/timer.h" |
| 19 #include "base/values.h" | |
| 16 #include "chrome/browser/chromeos/login/user.h" | 20 #include "chrome/browser/chromeos/login/user.h" |
| 17 #include "chrome/browser/chromeos/login/user_image_loader.h" | 21 #include "chrome/browser/chromeos/login/user_image_loader.h" |
| 18 #include "chrome/browser/chromeos/login/user_image_manager.h" | 22 #include "chrome/browser/chromeos/login/user_image_manager.h" |
| 19 #include "chrome/browser/profiles/profile_downloader_delegate.h" | 23 #include "chrome/browser/profiles/profile_downloader_delegate.h" |
| 20 #include "ui/gfx/image/image_skia.h" | 24 #include "ui/gfx/image/image_skia.h" |
| 21 | 25 |
| 22 class ProfileDownloader; | 26 class ProfileDownloader; |
| 23 class UserImage; | 27 class UserImage; |
| 24 | 28 |
| 25 namespace base { | 29 namespace base { |
| 26 class FilePath; | 30 class FilePath; |
| 31 class SequencedTaskRunner; | |
| 27 } | 32 } |
| 28 | 33 |
| 29 namespace chromeos { | 34 namespace chromeos { |
| 30 class UserImageSyncObserver; | 35 class UserImageSyncObserver; |
| 31 } | 36 } |
| 32 | 37 |
| 33 namespace chromeos { | 38 namespace chromeos { |
| 34 | 39 |
| 35 class UserImageManagerImpl : public UserImageManager, | 40 class UserImageManagerImpl : public UserImageManager, |
| 36 public ProfileDownloaderDelegate { | 41 public ProfileDownloaderDelegate { |
| 37 public: | 42 public: |
| 38 UserImageManagerImpl(); | 43 UserImageManagerImpl(); |
| 39 | 44 |
| 40 // UserImageManager implemenation: | 45 // UserImageManager: |
| 41 virtual ~UserImageManagerImpl(); | 46 virtual ~UserImageManagerImpl(); |
| 42 virtual void LoadUserImages(const UserList& users) OVERRIDE; | 47 virtual void LoadUserImages(const UserList& users) OVERRIDE; |
| 43 virtual void UserLoggedIn(const std::string& email, | 48 virtual void UserLoggedIn(const std::string& user_id, |
| 44 bool user_is_new, | 49 bool user_is_new, |
| 45 bool user_is_local) OVERRIDE; | 50 bool user_is_local) OVERRIDE; |
| 46 virtual void SaveUserDefaultImageIndex(const std::string& username, | 51 virtual void SaveUserDefaultImageIndex(const std::string& user_id, |
| 47 int image_index) OVERRIDE; | 52 int default_image_index) OVERRIDE; |
| 48 virtual void SaveUserImage(const std::string& username, | 53 virtual void SaveUserImage(const std::string& user_id, |
| 49 const UserImage& user_image) OVERRIDE; | 54 const UserImage& user_image) OVERRIDE; |
| 50 virtual void SaveUserImageFromFile(const std::string& username, | 55 virtual void SaveUserImageFromFile(const std::string& user_id, |
| 51 const base::FilePath& path) OVERRIDE; | 56 const base::FilePath& path) OVERRIDE; |
| 52 virtual void SaveUserImageFromProfileImage( | 57 virtual void SaveUserImageFromProfileImage( |
| 53 const std::string& username) OVERRIDE; | 58 const std::string& user_id) OVERRIDE; |
| 54 virtual void DeleteUserImage(const std::string& username) OVERRIDE; | 59 virtual void DeleteUserImage(const std::string& user_id) OVERRIDE; |
| 55 virtual void DownloadProfileImage(const std::string& reason) OVERRIDE; | 60 virtual void DownloadProfileImage(const std::string& reason) OVERRIDE; |
| 56 virtual const gfx::ImageSkia& DownloadedProfileImage() const OVERRIDE; | 61 virtual const gfx::ImageSkia& DownloadedProfileImage() const OVERRIDE; |
| 57 virtual UserImageSyncObserver* GetSyncObserver() const OVERRIDE; | 62 virtual UserImageSyncObserver* GetSyncObserver() const OVERRIDE; |
| 58 virtual void Shutdown() OVERRIDE; | 63 virtual void Shutdown() OVERRIDE; |
| 59 | 64 |
| 60 private: | 65 private: |
| 61 friend class UserImageManagerTest; | 66 // Every image load or update is encapsulated by a Job. Whenever an image load |
| 67 // or update is requested for a user, the Job currently running for that user | |
| 68 // (if any) is canceled. This ensures that at most one Job is running per user | |
| 69 // at any given time. There are two further guarantees: | |
| 70 // | |
| 71 // * Changes to User objects and local state are performed on the thread that | |
| 72 // |this| runs on. | |
| 73 // * File writes and deletions are performed via |background_task_runner_|. | |
| 74 // | |
| 75 // With the above, it is guaranteed that any changes made by a canceled Job | |
| 76 // cannot race against against changes made by the superseding Job. | |
| 77 class Job; | |
| 62 | 78 |
| 63 // Non-const for testing purposes. | 79 // ProfileDownloaderDelegate: |
| 64 static int user_image_migration_delay_sec; | |
| 65 | |
| 66 // ProfileDownloaderDelegate implementation: | |
| 67 virtual bool NeedsProfilePicture() const OVERRIDE; | 80 virtual bool NeedsProfilePicture() const OVERRIDE; |
| 68 virtual int GetDesiredImageSideLength() const OVERRIDE; | 81 virtual int GetDesiredImageSideLength() const OVERRIDE; |
| 69 virtual Profile* GetBrowserProfile() OVERRIDE; | 82 virtual Profile* GetBrowserProfile() OVERRIDE; |
| 70 virtual std::string GetCachedPictureURL() const OVERRIDE; | 83 virtual std::string GetCachedPictureURL() const OVERRIDE; |
| 71 virtual void OnProfileDownloadSuccess(ProfileDownloader* downloader) OVERRIDE; | 84 virtual void OnProfileDownloadSuccess(ProfileDownloader* downloader) OVERRIDE; |
| 72 virtual void OnProfileDownloadFailure( | 85 virtual void OnProfileDownloadFailure( |
| 73 ProfileDownloader* downloader, | 86 ProfileDownloader* downloader, |
| 74 ProfileDownloaderDelegate::FailureReason reason) OVERRIDE; | 87 ProfileDownloaderDelegate::FailureReason reason) OVERRIDE; |
| 75 | 88 |
| 76 // Returns image filepath for the given user. | 89 // Randomly chooses one of the default images for the specified user, sends a |
| 77 base::FilePath GetImagePathForUser(const std::string& username); | 90 // LOGIN_USER_IMAGE_CHANGED notification and updates local state. |
|
bartfab (slow)
2013/11/13 23:12:09
This used to *not* send a LOGIN_USER_IMAGE_CHANGED
| |
| 91 void SetInitialUserImage(const std::string& user_id); | |
| 78 | 92 |
| 79 // Sets one of the default images for the specified user and saves this | 93 // Initializes the |downloaded_profile_image_| for the currently logged-in |
| 80 // setting in local state. | 94 // user to a profile image that had been downloaded and saved before if such |
| 81 // Does not send LOGIN_USER_IMAGE_CHANGED notification. | 95 // a saved image is available and no updated image has been downloaded yet. |
| 82 void SetInitialUserImage(const std::string& username); | 96 void TryToInitDownloadedProfileImage(); |
| 83 | 97 |
| 84 // Sets image for user |username| and sends LOGIN_USER_IMAGE_CHANGED | 98 // Returns true if the profile image needs to be downloaded. This is the case |
| 85 // notification unless this is a new user and image is set for the first time. | 99 // when a GAIA user is logged in and at least one of the following applies: |
| 86 // If |image| is empty, sets a stub image for the user. | 100 // * The profile image has explicitly been requested by a call to |
| 87 void SetUserImage(const std::string& username, | 101 // DownloadProfileImage() and has not been successfully downloaded since. |
| 88 int image_index, | 102 // * The user's user image is the profile image. |
| 89 const GURL& image_url, | 103 bool NeedProfileImage() const; |
| 90 const UserImage& user_image); | |
| 91 | 104 |
| 92 // Saves image to file, updates local state preferences to given image index | 105 // Downloads the profile data for the currently logged-in user. The user's |
| 93 // and sends LOGIN_USER_IMAGE_CHANGED notification. | 106 // full name and, if NeedProfileImage() is true, the profile image are |
| 94 void SaveUserImageInternal(const std::string& username, | 107 // downloaded. |reason| is an arbitrary string (used to report UMA histograms |
| 95 int image_index, | 108 // with download times). |
| 96 const GURL& image_url, | 109 void DownloadProfileData(const std::string& reason); |
| 97 const UserImage& user_image); | |
| 98 | 110 |
| 99 // Saves image to file with specified path and sends LOGIN_USER_IMAGE_CHANGED | 111 // Removes |user_id| from the dictionary |prefs_dict_root| in local state and |
| 100 // notification. Runs on FILE thread. Posts task for saving image info to | 112 // deletes the image file that the dictionary referenced for that user. |
| 101 // Local State on UI thread. | 113 void DeleteUserImageAndLocalStateEntry(const std::string& user_id, |
| 102 void SaveImageToFile(const std::string& username, | 114 const char* prefs_dict_root); |
| 103 const UserImage& user_image, | |
| 104 const base::FilePath& image_path, | |
| 105 int image_index, | |
| 106 const GURL& image_url); | |
| 107 | 115 |
| 108 // Stores path to the image and its index in local state. Runs on UI thread. | 116 // Called when a Job updates the copy of the user image held in memory by |
| 109 // If |is_async| is true, it has been posted from the FILE thread after | 117 // |user|. Allows |this| to update |downloaded_profile_image_| and send a |
| 110 // saving the image. | 118 // NOTIFICATION_LOGIN_USER_IMAGE_CHANGED notification. |
| 111 void SaveImageToLocalState(const std::string& username, | 119 void OnJobChangedUserImage(const User* user); |
| 112 const std::string& image_path, | |
| 113 int image_index, | |
| 114 const GURL& image_url, | |
| 115 bool is_async); | |
| 116 | 120 |
| 117 // Saves |image| to the specified |image_path|. Runs on FILE thread. | 121 // Called when a Job for |user_id| finishes. If a migration was required for |
| 118 bool SaveBitmapToFile(const UserImage& user_image, | 122 // the user, the migration is now complete and the old image file for that |
| 119 const base::FilePath& image_path); | 123 // user, if any, is deleted. |
| 124 void OnJobDone(const std::string& user_id); | |
| 120 | 125 |
| 121 // Initializes |downloaded_profile_image_| with the picture of the logged-in | 126 // Completes migration by removing |user_id| from the old prefs dictionary. |
| 122 // user. | 127 void UpdateLocalStateAfterMigration(const std::string& user_id); |
| 123 void InitDownloadedProfileImage(); | |
| 124 | |
| 125 // Download user's profile data, including full name and picture, when | |
| 126 // |download_image| is true. | |
| 127 // |reason| is an arbitrary string (used to report UMA histograms with | |
| 128 // download times). | |
| 129 void DownloadProfileData(const std::string& reason, bool download_image); | |
| 130 | |
| 131 // Scheduled call for downloading profile data. | |
| 132 void DownloadProfileDataScheduled(); | |
| 133 | |
| 134 // Delayed call to retry downloading profile data. | |
| 135 void DownloadProfileDataRetry(bool download_image); | |
| 136 | |
| 137 // Migrates image info for the current user and deletes the old image, if any. | |
| 138 void MigrateUserImage(); | |
| 139 | |
| 140 // Deletes old user image and dictionary entry. | |
| 141 void DeleteOldUserImage(const std::string& username); | |
| 142 | 128 |
| 143 // Loader for JPEG user images. | 129 // Loader for JPEG user images. |
| 144 scoped_refptr<UserImageLoader> image_loader_; | 130 scoped_refptr<UserImageLoader> image_loader_; |
| 145 | 131 |
| 146 // Unsafe loader instance for all user images formats. | 132 // Unsafe loader instance for all user images formats. |
| 147 scoped_refptr<UserImageLoader> unsafe_image_loader_; | 133 scoped_refptr<UserImageLoader> unsafe_image_loader_; |
| 148 | 134 |
| 149 // Download user profile image on login to update it if it's changed. | 135 // Whether the |profile_downloader_| is downloading the profile image for the |
| 150 scoped_ptr<ProfileDownloader> profile_image_downloader_; | 136 // currently logged-in user (and not just the full name). Only valid when a |
| 137 // download is currently in progress. | |
| 138 bool downloading_profile_image_; | |
| 151 | 139 |
| 152 // Arbitrary string passed to the last |DownloadProfileImage| call. | 140 // Download reason given to DownloadProfileImage(), used for UMA histograms. |
| 141 // Only valid when a download is currently in progress and | |
| 142 // |downloading_profile_image_| is true. | |
| 153 std::string profile_image_download_reason_; | 143 std::string profile_image_download_reason_; |
| 154 | 144 |
| 155 // Time when the profile image download has started. | 145 // Time when the profile image download started. Only valid when a download is |
| 156 base::Time profile_image_load_start_time_; | 146 // currently in progress and |downloading_profile_image_| is true. |
| 147 base::TimeTicks profile_image_load_start_time_; | |
| 157 | 148 |
| 158 // True if the last user image required async save operation (which may not | 149 // Downloader for the current user's profile data. NULL when no download is |
| 159 // have been completed yet). This flag is used to avoid races when user image | 150 // currently in progress. |
| 160 // is first set with |SaveUserImage| and then with |SaveUserImagePath|. | 151 scoped_ptr<ProfileDownloader> profile_downloader_; |
| 161 bool last_image_set_async_; | |
| 162 | 152 |
| 163 // Result of the last successful profile image download, if any. | 153 // The currently logged-in user's downloaded profile image, if successfully |
| 154 // downloaded or initialized from a previously downloaded and saved image. | |
| 164 gfx::ImageSkia downloaded_profile_image_; | 155 gfx::ImageSkia downloaded_profile_image_; |
| 165 | 156 |
| 166 // Data URL for |downloaded_profile_image_|. | 157 // Data URL corresponding to |downloaded_profile_image_|. Empty if no |
| 158 // |downloaded_profile_image_| is currently available. | |
| 167 std::string downloaded_profile_image_data_url_; | 159 std::string downloaded_profile_image_data_url_; |
| 168 | 160 |
| 169 // Original URL of |downloaded_profile_image_|, from which it was downloaded. | 161 // URL from which |downloaded_profile_image_| was downloaded. Empty if no |
| 162 // |downloaded_profile_image_| is currently available. | |
| 170 GURL profile_image_url_; | 163 GURL profile_image_url_; |
| 171 | 164 |
| 172 // True when |profile_image_downloader_| is fetching profile picture (not | 165 // Whether a download of the currently logged-in user's profile image has been |
| 173 // just full name). | 166 // explicitly requested by a call to DownloadProfileImage() and has not been |
| 174 bool downloading_profile_image_; | 167 // satisfied by a successful download yet. |
| 168 bool profile_image_requested_; | |
| 175 | 169 |
| 176 // Timer triggering DownloadProfileDataScheduled for refreshing profile data. | 170 // Timer used to start a profile data download shortly after login and to |
| 177 base::RepeatingTimer<UserImageManagerImpl> profile_download_timer_; | 171 // restart the download after network errors. |
| 172 base::OneShotTimer<UserImageManagerImpl> profile_download_one_shot_timer_; | |
| 178 | 173 |
| 179 // Users that need image migration to JPEG. | 174 // Timer used to periodically start a profile data, ensuring the profile data |
| 175 // stays up to date. | |
| 176 base::RepeatingTimer<UserImageManagerImpl> profile_download_periodic_timer_; | |
| 177 | |
| 178 // Users whose user images need to be migrated from the old dictionary pref to | |
| 179 // the new dictionary pref, converting any non-default images to JPEG format. | |
| 180 std::set<std::string> users_to_migrate_; | 180 std::set<std::string> users_to_migrate_; |
| 181 | 181 |
| 182 // If |true|, current user image should be migrated right after it is loaded. | 182 // Sync observer for the currently logged-in user. |
| 183 bool migrate_current_user_on_load_; | 183 scoped_ptr<UserImageSyncObserver> user_image_sync_observer_; |
| 184 | 184 |
| 185 // Sync observer attached to current user. | 185 // Background task runner on which Jobs perform file I/O and the image |
| 186 scoped_ptr<UserImageSyncObserver> user_image_sync_observer_; | 186 // decoders run. |
| 187 scoped_refptr<base::SequencedTaskRunner> background_task_runner_; | |
| 188 | |
| 189 // The currently running jobs. | |
| 190 std::map<std::string, linked_ptr<Job> > jobs_; | |
| 191 | |
| 192 base::WeakPtrFactory<UserImageManagerImpl> weak_factory_; | |
| 187 | 193 |
| 188 DISALLOW_COPY_AND_ASSIGN(UserImageManagerImpl); | 194 DISALLOW_COPY_AND_ASSIGN(UserImageManagerImpl); |
| 189 }; | 195 }; |
| 190 | 196 |
| 191 } // namespace chromeos | 197 } // namespace chromeos |
| 192 | 198 |
| 193 #endif // CHROME_BROWSER_CHROMEOS_LOGIN_USER_IMAGE_MANAGER_IMPL_H_ | 199 #endif // CHROME_BROWSER_CHROMEOS_LOGIN_USER_IMAGE_MANAGER_IMPL_H_ |
| OLD | NEW |