1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_CHROMEOS_LOGIN_USERS_AVATAR_USER_IMAGE_MANAGER_IMPL_H_ 6 #define CHROME_BROWSER_CHROMEOS_LOGIN_USERS_AVATAR_USER_IMAGE_MANAGER_IMPL_H_ 7 8 #include <map> 9 #include <set> 10 #include <string> 11 12 #include "base/basictypes.h" 13 #include "base/compiler_specific.h" 14 #include "base/memory/ref_counted.h" 15 #include "base/memory/scoped_ptr.h" 16 #include "base/memory/weak_ptr.h" 17 #include "base/time/time.h" 18 #include "base/timer/timer.h" 19 #include "base/values.h" 20 #include "chrome/browser/chromeos/login/users/avatar/user_image_loader.h" 21 #include "chrome/browser/chromeos/login/users/avatar/user_image_manager.h" 22 #include "chrome/browser/profiles/profile_downloader_delegate.h" 23 #include "components/user_manager/user.h" 24 #include "ui/gfx/image/image_skia.h" 25 26 class ProfileDownloader; 27 28 namespace base { 29 class FilePath; 30 class SequencedTaskRunner; 31 } 32 33 namespace user_manager { 34 class UserImage; 35 class UserManager; 36 } 37 38 namespace chromeos { 39 40 class UserImageSyncObserver; 41 42 class UserImageManagerImpl 43 : public UserImageManager, 44 public ProfileDownloaderDelegate { 45 public: 46 // UserImageManager: 47 UserImageManagerImpl(const std::string& user_id, 48 user_manager::UserManager* user_manager); 49 virtual ~UserImageManagerImpl(); 50 51 virtual void LoadUserImage() OVERRIDE; 52 virtual void UserLoggedIn(bool user_is_new, bool user_is_local) OVERRIDE; 53 virtual void SaveUserDefaultImageIndex(int default_image_index) OVERRIDE; 54 virtual void SaveUserImage( 55 const user_manager::UserImage& user_image) OVERRIDE; 56 virtual void SaveUserImageFromFile(const base::FilePath& path) OVERRIDE; 57 virtual void SaveUserImageFromProfileImage() OVERRIDE; 58 virtual void DeleteUserImage() OVERRIDE; 59 virtual void DownloadProfileImage(const std::string& reason) OVERRIDE; 60 virtual const gfx::ImageSkia& DownloadedProfileImage() const OVERRIDE; 61 virtual UserImageSyncObserver* GetSyncObserver() const OVERRIDE; 62 virtual void Shutdown() OVERRIDE; 63 64 virtual void OnExternalDataSet(const std::string& policy) OVERRIDE; 65 virtual void OnExternalDataCleared(const std::string& policy) OVERRIDE; 66 virtual void OnExternalDataFetched(const std::string& policy, 67 scoped_ptr<std::string> data) OVERRIDE; 68 69 static void IgnoreProfileDataDownloadDelayForTesting(); 70 71 private: 72 friend class UserImageManagerTest; 73 74 // Every image load or update is encapsulated by a Job. Whenever an image load 75 // or update is requested for a user, the Job currently running for that user 76 // (if any) is canceled. This ensures that at most one Job is running per user 77 // at any given time. There are two further guarantees: 78 // 79 // * Changes to User objects and local state are performed on the thread that 80 // |this| runs on. 81 // * File writes and deletions are performed via |background_task_runner_|. 82 // 83 // With the above, it is guaranteed that any changes made by a canceled Job 84 // cannot race against against changes made by the superseding Job. 85 class Job; 86 87 // ProfileDownloaderDelegate: 88 virtual bool NeedsProfilePicture() const OVERRIDE; 89 virtual int GetDesiredImageSideLength() const OVERRIDE; 90 virtual Profile* GetBrowserProfile() OVERRIDE; 91 virtual std::string GetCachedPictureURL() const OVERRIDE; 92 virtual void OnProfileDownloadSuccess(ProfileDownloader* downloader) OVERRIDE; 93 virtual void OnProfileDownloadFailure( 94 ProfileDownloader* downloader, 95 ProfileDownloaderDelegate::FailureReason reason) OVERRIDE; 96 97 // Returns true if the user image for the user is managed by 98 // policy and the user is not allowed to change it. 99 bool IsUserImageManaged() const; 100 101 // Randomly chooses one of the default images for the specified user, sends a 102 // LOGIN_USER_IMAGE_CHANGED notification and updates local state. 103 void SetInitialUserImage(); 104 105 // Initializes the |downloaded_profile_image_| for the currently logged-in 106 // user to a profile image that had been downloaded and saved before if such 107 // a saved image is available and no updated image has been downloaded yet. 108 void TryToInitDownloadedProfileImage(); 109 110 // Returns true if the profile image needs to be downloaded. This is the case 111 // when a GAIA user is logged in and at least one of the following applies: 112 // * The profile image has explicitly been requested by a call to 113 // DownloadProfileImage() and has not been successfully downloaded since. 114 // * The user's user image is the profile image. 115 bool NeedProfileImage() const; 116 117 // Downloads the profile data for the currently logged-in user. The user's 118 // full name and, if NeedProfileImage() is true, the profile image are 119 // downloaded. |reason| is an arbitrary string (used to report UMA histograms 120 // with download times). 121 void DownloadProfileData(const std::string& reason); 122 123 // Removes ther user from the dictionary |prefs_dict_root| in 124 // local state and deletes the image file that the dictionary 125 // referenced for that user. 126 void DeleteUserImageAndLocalStateEntry(const char* prefs_dict_root); 127 128 // Called when a Job updates the copy of the user image held in 129 // memory. Allows |this| to update |downloaded_profile_image_| and 130 // send a NOTIFICATION_LOGIN_USER_IMAGE_CHANGED notification. 131 void OnJobChangedUserImage(); 132 133 // Called when a Job for the user finishes. If a migration was 134 // required for the user, the migration is now complete and the old 135 // image file for that user, if any, is deleted. 136 void OnJobDone(); 137 138 // Completes migration by removing the user from the old prefs 139 // dictionary. 140 void UpdateLocalStateAfterMigration(); 141 142 // Create a sync observer if a user is logged in, the user's user image is 143 // allowed to be synced and no sync observer exists yet. 144 void TryToCreateImageSyncObserver(); 145 146 // Returns immutable version of user with |user_id_|. 147 const user_manager::User* GetUser() const; 148 149 // Returns mutable version of user with |user_id_|. 150 user_manager::User* GetUserAndModify() const; 151 152 // Returns true if user with |user_id_| is logged in and a regular user. 153 bool IsUserLoggedInAndRegular() const; 154 155 // The user manager. 156 user_manager::UserManager* user_manager_; 157 158 // Loader for JPEG user images. 159 scoped_refptr<UserImageLoader> image_loader_; 160 161 // Unsafe loader instance for all user images formats. 162 scoped_refptr<UserImageLoader> unsafe_image_loader_; 163 164 // Whether the |profile_downloader_| is downloading the profile image for the 165 // currently logged-in user (and not just the full name). Only valid when a 166 // download is currently in progress. 167 bool downloading_profile_image_; 168 169 // Download reason given to DownloadProfileImage(), used for UMA histograms. 170 // Only valid when a download is currently in progress and 171 // |downloading_profile_image_| is true. 172 std::string profile_image_download_reason_; 173 174 // Time when the profile image download started. Only valid when a download is 175 // currently in progress and |downloading_profile_image_| is true. 176 base::TimeTicks profile_image_load_start_time_; 177 178 // Downloader for the user's profile data. NULL when no download is 179 // currently in progress. 180 scoped_ptr<ProfileDownloader> profile_downloader_; 181 182 // The currently logged-in user's downloaded profile image, if successfully 183 // downloaded or initialized from a previously downloaded and saved image. 184 gfx::ImageSkia downloaded_profile_image_; 185 186 // Data URL corresponding to |downloaded_profile_image_|. Empty if no 187 // |downloaded_profile_image_| is currently available. 188 std::string downloaded_profile_image_data_url_; 189 190 // URL from which |downloaded_profile_image_| was downloaded. Empty if no 191 // |downloaded_profile_image_| is currently available. 192 GURL profile_image_url_; 193 194 // Whether a download of the currently logged-in user's profile image has been 195 // explicitly requested by a call to DownloadProfileImage() and has not been 196 // satisfied by a successful download yet. 197 bool profile_image_requested_; 198 199 // Timer used to start a profile data download shortly after login and to 200 // restart the download after network errors. 201 base::OneShotTimer<UserImageManagerImpl> profile_download_one_shot_timer_; 202 203 // Timer used to periodically start a profile data, ensuring the profile data 204 // stays up to date. 205 base::RepeatingTimer<UserImageManagerImpl> profile_download_periodic_timer_; 206 207 // Sync observer for the currently logged-in user. 208 scoped_ptr<UserImageSyncObserver> user_image_sync_observer_; 209 210 // Background task runner on which Jobs perform file I/O and the image 211 // decoders run. 212 scoped_refptr<base::SequencedTaskRunner> background_task_runner_; 213 214 // The currently running job. 215 scoped_ptr<Job> job_; 216 217 bool has_managed_image_; 218 bool user_needs_migration_; 219 220 base::WeakPtrFactory<UserImageManagerImpl> weak_factory_; 221 222 DISALLOW_COPY_AND_ASSIGN(UserImageManagerImpl); 223 }; 224 225 } // namespace chromeos 226 227 #endif // CHROME_BROWSER_CHROMEOS_LOGIN_USERS_AVATAR_USER_IMAGE_MANAGER_IMPL_H_ 228