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