Home | History | Annotate | Download | only in login
      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
      3 // found in the LICENSE file.
      4 
      5 #ifndef CHROME_BROWSER_CHROMEOS_LOGIN_WALLPAPER_MANAGER_H_
      6 #define CHROME_BROWSER_CHROMEOS_LOGIN_WALLPAPER_MANAGER_H_
      7 
      8 #include <string>
      9 
     10 #include "ash/desktop_background/desktop_background_controller.h"
     11 #include "base/files/file_path.h"
     12 #include "base/memory/ref_counted_memory.h"
     13 #include "base/memory/weak_ptr.h"
     14 #include "base/threading/sequenced_worker_pool.h"
     15 #include "base/time/time.h"
     16 #include "base/timer/timer.h"
     17 #include "chrome/browser/chromeos/login/user.h"
     18 #include "chrome/browser/chromeos/login/user_image.h"
     19 #include "chrome/browser/chromeos/login/user_image_loader.h"
     20 #include "chrome/browser/chromeos/system/timezone_settings.h"
     21 #include "chromeos/dbus/power_manager_client.h"
     22 #include "content/public/browser/notification_observer.h"
     23 #include "content/public/browser/notification_registrar.h"
     24 #include "third_party/icu/source/i18n/unicode/timezone.h"
     25 #include "ui/gfx/image/image_skia.h"
     26 
     27 class CommandLine;
     28 class PrefRegistrySimple;
     29 
     30 namespace base {
     31 class SequencedTaskRunner;
     32 }
     33 
     34 namespace chromeos {
     35 
     36 struct WallpaperInfo {
     37   // Online wallpaper URL or file name of migrated wallpaper.
     38   std::string file;
     39   ash::WallpaperLayout layout;
     40   User::WallpaperType type;
     41   base::Time date;
     42   bool operator==(const WallpaperInfo& other) {
     43     return (file == other.file) && (layout == other.layout) &&
     44         (type == other.type);
     45   }
     46 };
     47 
     48 class WallpaperManagerBrowserTest;
     49 class UserImage;
     50 
     51 // Name of wallpaper sequence token.
     52 extern const char kWallpaperSequenceTokenName[];
     53 
     54 // File path suffices of resized small or large wallpaper.
     55 // TODO(bshe): Use the same sub folder system as custom wallpapers use.
     56 // crbug.com/174928
     57 extern const char kSmallWallpaperSuffix[];
     58 extern const char kLargeWallpaperSuffix[];
     59 
     60 // Directory names of custom wallpapers.
     61 extern const char kSmallWallpaperSubDir[];
     62 extern const char kLargeWallpaperSubDir[];
     63 extern const char kOriginalWallpaperSubDir[];
     64 extern const char kThumbnailWallpaperSubDir[];
     65 
     66 // This class maintains wallpapers for users who have logged into this Chrome
     67 // OS device.
     68 class WallpaperManager: public system::TimezoneSettings::Observer,
     69                         public chromeos::PowerManagerClient::Observer,
     70                         public content::NotificationObserver {
     71  public:
     72   // For testing.
     73   class TestApi {
     74    public:
     75     explicit TestApi(WallpaperManager* wallpaper_manager);
     76     virtual ~TestApi();
     77 
     78     base::FilePath current_wallpaper_path();
     79 
     80    private:
     81     WallpaperManager* wallpaper_manager_;  // not owned
     82 
     83     DISALLOW_COPY_AND_ASSIGN(TestApi);
     84   };
     85 
     86   static WallpaperManager* Get();
     87 
     88   WallpaperManager();
     89   virtual ~WallpaperManager();
     90 
     91   void set_command_line_for_testing(CommandLine* command_line) {
     92     command_line_for_testing_ = command_line;
     93   }
     94 
     95   // Indicates imminent shutdown, allowing the WallpaperManager to remove any
     96   // observers it has registered.
     97   void Shutdown();
     98 
     99   // Registers wallpaper manager preferences.
    100   static void RegisterPrefs(PrefRegistrySimple* registry);
    101 
    102   // Adds PowerManagerClient, TimeZoneSettings and CrosSettings observers.
    103   void AddObservers();
    104 
    105   // Loads wallpaper asynchronously if the current wallpaper is not the
    106   // wallpaper of logged in user.
    107   void EnsureLoggedInUserWallpaperLoaded();
    108 
    109   // Clears ONLINE and CUSTOM wallpaper cache.
    110   void ClearWallpaperCache();
    111 
    112   // Returns custom wallpaper path. Append |sub_dir|, |email| and |file| to
    113   // custom wallpaper directory.
    114   base::FilePath GetCustomWallpaperPath(const char* sub_dir,
    115                                         const std::string& email,
    116                                         const std::string& file);
    117 
    118   // Gets encoded wallpaper from cache. Returns true if success.
    119   bool GetWallpaperFromCache(const std::string& email,
    120                              gfx::ImageSkia* wallpaper);
    121 
    122   // Returns filepath to save original custom wallpaper for the given user.
    123   base::FilePath GetOriginalWallpaperPathForUser(const std::string& username);
    124 
    125   // Returns small resolution custom wallpaper filepath for the given user when
    126   // |is_small| is ture. Otherwise, returns large resolution custom wallpaper
    127   // path.
    128   // TODO(bshe): Remove this function when all custom wallpapers moved to the
    129   // new direcotry. crbug.com/174925
    130   base::FilePath GetWallpaperPathForUser(const std::string& username,
    131                                          bool is_small);
    132 
    133   // Gets wallpaper information of logged in user.
    134   bool GetLoggedInUserWallpaperInfo(WallpaperInfo* info);
    135 
    136   // Initializes wallpaper. If logged in, loads user's wallpaper. If not logged
    137   // in, uses a solid color wallpaper. If logged in as a stub user, uses an
    138   // empty wallpaper.
    139   void InitializeWallpaper();
    140 
    141   // NotificationObserver overrides:
    142   virtual void Observe(int type,
    143                        const content::NotificationSource& source,
    144                        const content::NotificationDetails& details) OVERRIDE;
    145 
    146   // Removes all |email| related wallpaper info and saved wallpapers.
    147   void RemoveUserWallpaperInfo(const std::string& email);
    148 
    149   // Resizes |wallpaper| to a resolution which is nearest to |preferred_width|
    150   // and |preferred_height| while maintaining aspect ratio.
    151   bool ResizeWallpaper(const UserImage& wallpaper,
    152                        ash::WallpaperLayout layout,
    153                        int preferred_width,
    154                        int preferred_height,
    155                        scoped_refptr<base::RefCountedBytes>* output);
    156 
    157   // Resizes |wallpaper| to a resolution which is nearest to |preferred_width|
    158   // and |preferred_height| while maintaining aspect ratio. And saves the
    159   // resized wallpaper to |path|.
    160   void ResizeAndSaveWallpaper(const UserImage& wallpaper,
    161                               const base::FilePath& path,
    162                               ash::WallpaperLayout layout,
    163                               int preferred_width,
    164                               int preferred_height);
    165 
    166   // Starts a one shot timer which calls BatchUpdateWallpaper at next midnight.
    167   // Cancel any previous timer if any.
    168   void RestartTimer();
    169 
    170   // Saves custom wallpaper to file, post task to generate thumbnail and updates
    171   // local state preferences.
    172   void SetCustomWallpaper(const std::string& username,
    173                           const std::string& file,
    174                           ash::WallpaperLayout layout,
    175                           User::WallpaperType type,
    176                           const UserImage& wallpaper);
    177 
    178   // Sets wallpaper to default wallpaper.
    179   void SetDefaultWallpaper();
    180 
    181   // Sets one of the default wallpapers for the specified user and saves this
    182   // settings in local state.
    183   void SetInitialUserWallpaper(const std::string& username, bool is_persistent);
    184 
    185   // Sets selected wallpaper information for |username| and saves it to Local
    186   // State if |is_persistent| is true.
    187   void SetUserWallpaperInfo(const std::string& username,
    188                             const WallpaperInfo& info,
    189                             bool is_persistent);
    190 
    191   // Sets last selected user on user pod row.
    192   void SetLastSelectedUser(const std::string& last_selected_user);
    193 
    194   // Sets |email|'s wallpaper.
    195   void SetUserWallpaper(const std::string& email);
    196 
    197   // Sets wallpaper to |wallpaper|.
    198   void SetWallpaperFromImageSkia(const gfx::ImageSkia& wallpaper,
    199                                  ash::WallpaperLayout layout);
    200 
    201   // Updates current wallpaper. It may switch the size of wallpaper based on the
    202   // current display's resolution.
    203   void UpdateWallpaper();
    204 
    205  private:
    206   friend class TestApi;
    207   friend class WallpaperManagerBrowserTest;
    208   typedef std::map<std::string, gfx::ImageSkia> CustomWallpaperMap;
    209 
    210   // The number of wallpapers have loaded. For test only.
    211   int loaded_wallpapers() const { return loaded_wallpapers_; }
    212 
    213   // Change the wallpapers for users who choose DAILY wallpaper type. Updates
    214   // current wallpaper if it changed. This function should be called at exactly
    215   // at 0am if chromeos device is on.
    216   void BatchUpdateWallpaper();
    217 
    218   // Cache some (or all) logged in users' wallpapers to memory at login
    219   // screen. It should not compete with first wallpaper loading when boot
    220   // up/initialize login WebUI page.
    221   // There are two ways the first wallpaper might be loaded:
    222   // 1. Loaded on boot. Login WebUI waits for it.
    223   // 2. When flag --disable-boot-animation is passed. Login WebUI is loaded
    224   // right away and in 500ms after. Wallpaper started to load.
    225   // For case 2, should_cache_wallpaper_ is used to indicate if we need to
    226   // cache wallpapers on wallpaper animation finished. The cache operation
    227   // should be only executed once.
    228   void CacheUsersWallpapers();
    229 
    230   // Caches |email|'s wallpaper to memory.
    231   void CacheUserWallpaper(const std::string& email);
    232 
    233   // Clears all obsolete wallpaper prefs from old version wallpaper pickers.
    234   void ClearObsoleteWallpaperPrefs();
    235 
    236   // Deletes everything else except |path| in the same directory.
    237   void DeleteAllExcept(const base::FilePath& path);
    238 
    239   // Deletes a list of wallpaper files in |file_list|.
    240   void DeleteWallpaperInList(const std::vector<base::FilePath>& file_list);
    241 
    242   // Deletes all |email| related custom or converted wallpapers.
    243   void DeleteUserWallpapers(const std::string& email);
    244 
    245   // Creates all new custom wallpaper directories for |email| if not exist.
    246   void EnsureCustomWallpaperDirectories(const std::string& email);
    247 
    248   // Gets the CommandLine representing the current process's command line.
    249   CommandLine* GetComandLine();
    250 
    251   // Loads custom wallpaper from old places and triggers move all custom
    252   // wallpapers to new places.
    253   // TODO(bshe): Remove this function when all custom wallpapers moved to the
    254   // new direcotry. crbug.com/174925
    255   void FallbackToOldCustomWallpaper(const std::string& email,
    256                                     const WallpaperInfo& info,
    257                                     bool update_wallpaper);
    258 
    259   // Initialize wallpaper of registered device after device policy is trusted.
    260   // Note that before device is enrolled, it proceeds with untrusted setting.
    261   void InitializeRegisteredDeviceWallpaper();
    262 
    263   // Loads |email|'s wallpaper. When |update_wallpaper| is true, sets wallpaper
    264   // to the loaded wallpaper.
    265   void LoadWallpaper(const std::string& email,
    266                      const WallpaperInfo& info,
    267                      bool update_wallpaper);
    268 
    269   // Gets UserList and starts MoveCustomWallpapersOnWorker().
    270   // Must be called on UI thread.
    271   // TODO(bshe): Remove this function when all custom wallpapers moved to the
    272   // new direcotry. crbug.com/174925
    273   void MoveCustomWallpapers();
    274 
    275   // Move old custom wallpapers to new places for |users|.
    276   // Must execute on wallpaper sequenced worker thread.
    277   // TODO(bshe): Remove this function when all custom wallpapers moved to the
    278   // new direcotry. crbug.com/174925
    279   void MoveCustomWallpapersOnWorker(const UserList& users);
    280 
    281   // Gets |email|'s custom wallpaper at |wallpaper_path|. Falls back on original
    282   // custom wallpaper. When |update_wallpaper| is true, sets wallpaper to the
    283   // loaded wallpaper. Must run on wallpaper sequenced worker thread.
    284   // TODO(bshe): Remove this function when all custom wallpapers moved to the
    285   // new direcotry. crbug.com/174925
    286   void GetCustomWallpaperInternalOld(const std::string& email,
    287                                      const WallpaperInfo& info,
    288                                      const base::FilePath& wallpaper_path,
    289                                      bool update_wallpaper);
    290 
    291   // Gets |email|'s custom wallpaper at |wallpaper_path|. Falls back on original
    292   // custom wallpaper. When |update_wallpaper| is true, sets wallpaper to the
    293   // loaded wallpaper. Must run on wallpaper sequenced worker thread.
    294   void GetCustomWallpaperInternal(const std::string& email,
    295                                   const WallpaperInfo& info,
    296                                   const base::FilePath& wallpaper_path,
    297                                   bool update_wallpaper);
    298 
    299   // Gets wallpaper information of |email| from Local State or memory. Returns
    300   // false if wallpaper information is not found.
    301   bool GetUserWallpaperInfo(const std::string& email, WallpaperInfo* info);
    302 
    303   // Sets wallpaper to the decoded wallpaper if |update_wallpaper| is true.
    304   // Otherwise, cache wallpaper to memory if not logged in.
    305   void OnWallpaperDecoded(const std::string& email,
    306                           ash::WallpaperLayout layout,
    307                           bool update_wallpaper,
    308                           const UserImage& wallpaper);
    309 
    310   // Generates thumbnail of custom wallpaper on wallpaper sequenced worker
    311   // thread. If |persistent| is true, saves original custom image and resized
    312   // images to disk.
    313   void ProcessCustomWallpaper(const std::string& email,
    314                               bool persistent,
    315                               const WallpaperInfo& info,
    316                               scoped_ptr<gfx::ImageSkia> image,
    317                               const UserImage::RawImage& raw_image);
    318 
    319   // Record data for User Metrics Analysis.
    320   void RecordUma(User::WallpaperType type, int index);
    321 
    322   // Saves original custom wallpaper to |path| (absolute path) on filesystem
    323   // and starts resizing operation of the custom wallpaper if necessary.
    324   void SaveCustomWallpaper(const std::string& email,
    325                            const base::FilePath& path,
    326                            ash::WallpaperLayout layout,
    327                            const UserImage& wallpaper);
    328 
    329   // Saves wallpaper image raw |data| to |path| (absolute path) in file system.
    330   void SaveWallpaperInternal(const base::FilePath& path, const char* data,
    331                              int size);
    332 
    333   // Starts to load wallpaper at |wallpaper_path|. If |wallpaper_path| is the
    334   // same as |current_wallpaper_path_|, do nothing. Must be called on UI thread.
    335   void StartLoad(const std::string& email,
    336                  const WallpaperInfo& info,
    337                  bool update_wallpaper,
    338                  const base::FilePath& wallpaper_path);
    339 
    340   // Overridden from chromeos::PowerManagerObserver.
    341   virtual void SystemResumed(const base::TimeDelta& sleep_duration) OVERRIDE;
    342 
    343   // Overridden from system::TimezoneSettings::Observer.
    344   virtual void TimezoneChanged(const icu::TimeZone& timezone) OVERRIDE;
    345 
    346   // True if wallpaper manager is not observering other objects.
    347   bool no_observers_;
    348 
    349   // The number of loaded wallpapers.
    350   int loaded_wallpapers_;
    351 
    352   // Sequence token associated with wallpaper operations.
    353   base::SequencedWorkerPool::SequenceToken sequence_token_;
    354 
    355   // Wallpaper sequenced task runner.
    356   scoped_refptr<base::SequencedTaskRunner> task_runner_;
    357 
    358   // The file path of current loaded/loading custom/online wallpaper.
    359   base::FilePath current_wallpaper_path_;
    360 
    361   // Loads user wallpaper from its file.
    362   scoped_refptr<UserImageLoader> wallpaper_loader_;
    363 
    364   // Logged-in user wallpaper information.
    365   WallpaperInfo current_user_wallpaper_info_;
    366 
    367   // If non-NULL, used in place of the real command line.
    368   CommandLine* command_line_for_testing_;
    369 
    370   // Caches wallpapers of users. Accessed only on UI thread.
    371   CustomWallpaperMap wallpaper_cache_;
    372 
    373   // The last selected user on user pod row.
    374   std::string last_selected_user_;
    375 
    376   bool should_cache_wallpaper_;
    377 
    378   base::WeakPtrFactory<WallpaperManager> weak_factory_;
    379 
    380   content::NotificationRegistrar registrar_;
    381 
    382   base::OneShotTimer<WallpaperManager> timer_;
    383 
    384   DISALLOW_COPY_AND_ASSIGN(WallpaperManager);
    385 };
    386 
    387 }  // namespace chromeos
    388 
    389 #endif  // CHROME_BROWSER_CHROMEOS_LOGIN_WALLPAPER_MANAGER_H_
    390