// Copyright (c) 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CHROME_BROWSER_CHROMEOS_LOGIN_USER_IMAGE_MANAGER_IMPL_H_ #define CHROME_BROWSER_CHROMEOS_LOGIN_USER_IMAGE_MANAGER_IMPL_H_ #include <map> #include <set> #include <string> #include "base/basictypes.h" #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/time/time.h" #include "base/timer/timer.h" #include "base/values.h" #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/profiles/profile_downloader_delegate.h" #include "ui/gfx/image/image_skia.h" class ProfileDownloader; class UserImage; namespace base { class FilePath; class SequencedTaskRunner; } namespace chromeos { class UserImageSyncObserver; class UserManager; class UserImageManagerImpl : public UserImageManager, public ProfileDownloaderDelegate { public: // UserImageManager: UserImageManagerImpl(const std::string& user_id, UserManager* user_manager); virtual ~UserImageManagerImpl(); 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; virtual void OnExternalDataSet(const std::string& policy) OVERRIDE; virtual void OnExternalDataCleared(const std::string& policy) OVERRIDE; virtual void OnExternalDataFetched(const std::string& policy, scoped_ptr<std::string> data) OVERRIDE; static void IgnoreProfileDataDownloadDelayForTesting(); private: friend class UserImageManagerTest; // Every image load or update is encapsulated by a Job. Whenever an image load // or update is requested for a user, the Job currently running for that user // (if any) is canceled. This ensures that at most one Job is running per user // at any given time. There are two further guarantees: // // * Changes to User objects and local state are performed on the thread that // |this| runs on. // * File writes and deletions are performed via |background_task_runner_|. // // With the above, it is guaranteed that any changes made by a canceled Job // cannot race against against changes made by the superseding Job. class Job; // ProfileDownloaderDelegate: virtual bool NeedsProfilePicture() const OVERRIDE; virtual int GetDesiredImageSideLength() const OVERRIDE; virtual Profile* GetBrowserProfile() OVERRIDE; virtual std::string GetCachedPictureURL() const OVERRIDE; virtual void OnProfileDownloadSuccess(ProfileDownloader* downloader) OVERRIDE; virtual void OnProfileDownloadFailure( ProfileDownloader* downloader, ProfileDownloaderDelegate::FailureReason reason) OVERRIDE; // 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(); // Initializes the |downloaded_profile_image_| for the currently logged-in // user to a profile image that had been downloaded and saved before if such // a saved image is available and no updated image has been downloaded yet. void TryToInitDownloadedProfileImage(); // Returns true if the profile image needs to be downloaded. This is the case // when a GAIA user is logged in and at least one of the following applies: // * The profile image has explicitly been requested by a call to // DownloadProfileImage() and has not been successfully downloaded since. // * The user's user image is the profile image. bool NeedProfileImage() const; // Downloads the profile data for the currently logged-in user. The user's // full name and, if NeedProfileImage() is true, the profile image are // downloaded. |reason| is an arbitrary string (used to report UMA histograms // with download times). void DownloadProfileData(const std::string& reason); // 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. Allows |this| to update |downloaded_profile_image_| and // send a NOTIFICATION_LOGIN_USER_IMAGE_CHANGED notification. void OnJobChangedUserImage(); // 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 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_; // Loader for JPEG user images. scoped_refptr<UserImageLoader> image_loader_; // Unsafe loader instance for all user images formats. scoped_refptr<UserImageLoader> unsafe_image_loader_; // Whether the |profile_downloader_| is downloading the profile image for the // currently logged-in user (and not just the full name). Only valid when a // download is currently in progress. bool downloading_profile_image_; // Download reason given to DownloadProfileImage(), used for UMA histograms. // Only valid when a download is currently in progress and // |downloading_profile_image_| is true. std::string profile_image_download_reason_; // Time when the profile image download started. Only valid when a download is // currently in progress and |downloading_profile_image_| is true. base::TimeTicks profile_image_load_start_time_; // Downloader for the user's profile data. NULL when no download is // currently in progress. scoped_ptr<ProfileDownloader> profile_downloader_; // The currently logged-in user's downloaded profile image, if successfully // downloaded or initialized from a previously downloaded and saved image. gfx::ImageSkia downloaded_profile_image_; // Data URL corresponding to |downloaded_profile_image_|. Empty if no // |downloaded_profile_image_| is currently available. std::string downloaded_profile_image_data_url_; // URL from which |downloaded_profile_image_| was downloaded. Empty if no // |downloaded_profile_image_| is currently available. GURL profile_image_url_; // Whether a download of the currently logged-in user's profile image has been // explicitly requested by a call to DownloadProfileImage() and has not been // satisfied by a successful download yet. bool profile_image_requested_; // Timer used to start a profile data download shortly after login and to // restart the download after network errors. base::OneShotTimer<UserImageManagerImpl> profile_download_one_shot_timer_; // Timer used to periodically start a profile data, ensuring the profile data // stays up to date. base::RepeatingTimer<UserImageManagerImpl> profile_download_periodic_timer_; // Sync observer for the currently logged-in user. scoped_ptr<UserImageSyncObserver> user_image_sync_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 job. scoped_ptr<Job> job_; bool has_managed_image_; bool user_needs_migration_; base::WeakPtrFactory<UserImageManagerImpl> weak_factory_; DISALLOW_COPY_AND_ASSIGN(UserImageManagerImpl); }; } // namespace chromeos #endif // CHROME_BROWSER_CHROMEOS_LOGIN_USER_IMAGE_MANAGER_IMPL_H_