root/chrome/browser/chromeos/login/user_image_manager_impl.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


// 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_

/* [<][>][^][v][top][bottom][index][help] */