• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/scoped_ptr.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/observer_list.h"
16 #include "base/threading/sequenced_worker_pool.h"
17 #include "base/time/time.h"
18 #include "chrome/browser/chromeos/login/user.h"
19 #include "chrome/browser/chromeos/login/user_image.h"
20 #include "chrome/browser/chromeos/login/user_image_loader.h"
21 #include "chrome/browser/chromeos/settings/cros_settings.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 content::NotificationObserver {
69  public:
70   // For testing.
71   class TestApi {
72    public:
73     explicit TestApi(WallpaperManager* wallpaper_manager);
74     virtual ~TestApi();
75 
76     base::FilePath current_wallpaper_path();
77 
78    private:
79     WallpaperManager* wallpaper_manager_;  // not owned
80 
81     DISALLOW_COPY_AND_ASSIGN(TestApi);
82   };
83 
84   class Observer {
85    public:
~Observer()86     virtual ~Observer() {}
87     virtual void OnWallpaperAnimationFinished(const std::string& email) = 0;
88   };
89 
90   static WallpaperManager* Get();
91 
92   WallpaperManager();
93   virtual ~WallpaperManager();
94 
set_command_line_for_testing(CommandLine * command_line)95   void set_command_line_for_testing(CommandLine* command_line) {
96     command_line_for_testing_ = command_line;
97   }
98 
99   // Indicates imminent shutdown, allowing the WallpaperManager to remove any
100   // observers it has registered.
101   void Shutdown();
102 
103   // Registers wallpaper manager preferences.
104   static void RegisterPrefs(PrefRegistrySimple* registry);
105 
106   // Adds PowerManagerClient, TimeZoneSettings and CrosSettings observers.
107   void AddObservers();
108 
109   // Loads wallpaper asynchronously if the current wallpaper is not the
110   // wallpaper of logged in user.
111   void EnsureLoggedInUserWallpaperLoaded();
112 
113   // Clears ONLINE and CUSTOM wallpaper cache.
114   void ClearWallpaperCache();
115 
116   // Returns custom wallpaper path. Append |sub_dir|, |user_id_hash| and |file|
117   // to custom wallpaper directory.
118   base::FilePath GetCustomWallpaperPath(const char* sub_dir,
119                                         const std::string& user_id_hash,
120                                         const std::string& file);
121 
122   // Gets encoded wallpaper from cache. Returns true if success.
123   bool GetWallpaperFromCache(const std::string& email,
124                              gfx::ImageSkia* wallpaper);
125 
126   // Returns filepath to save original custom wallpaper for the given user.
127   base::FilePath GetOriginalWallpaperPathForUser(const std::string& username);
128 
129   // Gets wallpaper information of logged in user.
130   bool GetLoggedInUserWallpaperInfo(WallpaperInfo* info);
131 
132   // Initializes wallpaper. If logged in, loads user's wallpaper. If not logged
133   // in, uses a solid color wallpaper. If logged in as a stub user, uses an
134   // empty wallpaper.
135   void InitializeWallpaper();
136 
137   // NotificationObserver overrides:
138   virtual void Observe(int type,
139                        const content::NotificationSource& source,
140                        const content::NotificationDetails& details) OVERRIDE;
141 
142   // Removes all |email| related wallpaper info and saved wallpapers.
143   void RemoveUserWallpaperInfo(const std::string& email);
144 
145   // Resizes |wallpaper| to a resolution which is nearest to |preferred_width|
146   // and |preferred_height| while maintaining aspect ratio.
147   bool ResizeWallpaper(const UserImage& wallpaper,
148                        ash::WallpaperLayout layout,
149                        int preferred_width,
150                        int preferred_height,
151                        scoped_refptr<base::RefCountedBytes>* output);
152 
153   // Resizes |wallpaper| to a resolution which is nearest to |preferred_width|
154   // and |preferred_height| while maintaining aspect ratio. And saves the
155   // resized wallpaper to |path|.
156   void ResizeAndSaveWallpaper(const UserImage& wallpaper,
157                               const base::FilePath& path,
158                               ash::WallpaperLayout layout,
159                               int preferred_width,
160                               int preferred_height);
161 
162   // Saves custom wallpaper to file, post task to generate thumbnail and updates
163   // local state preferences.
164   void SetCustomWallpaper(const std::string& username,
165                           const std::string& user_id_hash,
166                           const std::string& file,
167                           ash::WallpaperLayout layout,
168                           User::WallpaperType type,
169                           const UserImage& wallpaper);
170 
171   // Sets wallpaper to default wallpaper.
172   void SetDefaultWallpaper();
173 
174   // Sets one of the default wallpapers for the specified user and saves this
175   // settings in local state.
176   void SetInitialUserWallpaper(const std::string& username, bool is_persistent);
177 
178   // Sets selected wallpaper information for |username| and saves it to Local
179   // State if |is_persistent| is true.
180   void SetUserWallpaperInfo(const std::string& username,
181                             const WallpaperInfo& info,
182                             bool is_persistent);
183 
184   // Sets last selected user on user pod row.
185   void SetLastSelectedUser(const std::string& last_selected_user);
186 
187   // Sets |email|'s wallpaper.
188   void SetUserWallpaper(const std::string& email);
189 
190   // Sets wallpaper to |wallpaper|.
191   void SetWallpaperFromImageSkia(const gfx::ImageSkia& wallpaper,
192                                  ash::WallpaperLayout layout);
193 
194   // Updates current wallpaper. It may switch the size of wallpaper based on the
195   // current display's resolution.
196   void UpdateWallpaper();
197 
198   // Adds given observer to the list.
199   void AddObserver(Observer* observer);
200 
201   // Removes given observer from the list.
202   void RemoveObserver(Observer* observer);
203 
204  private:
205   friend class TestApi;
206   friend class WallpaperManagerBrowserTest;
207   typedef std::map<std::string, gfx::ImageSkia> CustomWallpaperMap;
208 
209   // The number of wallpapers have loaded. For test only.
loaded_wallpapers()210   int loaded_wallpapers() const { return loaded_wallpapers_; }
211 
212   // Cache some (or all) logged in users' wallpapers to memory at login
213   // screen. It should not compete with first wallpaper loading when boot
214   // up/initialize login WebUI page.
215   // There are two ways the first wallpaper might be loaded:
216   // 1. Loaded on boot. Login WebUI waits for it.
217   // 2. When flag --disable-boot-animation is passed. Login WebUI is loaded
218   // right away and in 500ms after. Wallpaper started to load.
219   // For case 2, should_cache_wallpaper_ is used to indicate if we need to
220   // cache wallpapers on wallpaper animation finished. The cache operation
221   // should be only executed once.
222   void CacheUsersWallpapers();
223 
224   // Caches |email|'s wallpaper to memory.
225   void CacheUserWallpaper(const std::string& email);
226 
227   // Clears all obsolete wallpaper prefs from old version wallpaper pickers.
228   void ClearObsoleteWallpaperPrefs();
229 
230   // Deletes everything else except |path| in the same directory.
231   void DeleteAllExcept(const base::FilePath& path);
232 
233   // Deletes a list of wallpaper files in |file_list|.
234   void DeleteWallpaperInList(const std::vector<base::FilePath>& file_list);
235 
236   // Deletes all |email| related custom wallpapers and directories.
237   void DeleteUserWallpapers(const std::string& email,
238                             const std::string& path_to_file);
239 
240   // Creates all new custom wallpaper directories for |user_id_hash| if not
241   // exist.
242   void EnsureCustomWallpaperDirectories(const std::string& user_id_hash);
243 
244   // Gets the CommandLine representing the current process's command line.
245   CommandLine* GetComandLine();
246 
247   // Initialize wallpaper of registered device after device policy is trusted.
248   // Note that before device is enrolled, it proceeds with untrusted setting.
249   void InitializeRegisteredDeviceWallpaper();
250 
251   // Loads |email|'s wallpaper. When |update_wallpaper| is true, sets wallpaper
252   // to the loaded wallpaper.
253   void LoadWallpaper(const std::string& email,
254                      const WallpaperInfo& info,
255                      bool update_wallpaper);
256 
257   // Moves custom wallpapers from |email| directory to |user_id_hash|
258   // directory.
259   void MoveCustomWallpapersOnWorker(const std::string& email,
260                                     const std::string& user_id_hash);
261 
262   // Called when the original custom wallpaper is moved to the new place.
263   // Updates the corresponding user wallpaper info.
264   void MoveCustomWallpapersSuccess(const std::string& email,
265                                    const std::string& user_id_hash);
266 
267   // Moves custom wallpaper to a new place. Email address was used as directory
268   // name in the old system, this is not safe. New directory system uses
269   // user_id_hash instead of email. This must be called after user_id_hash is
270   // ready.
271   void MoveLoggedInUserCustomWallpaper();
272 
273   // Gets |email|'s custom wallpaper at |wallpaper_path|. Falls back on original
274   // custom wallpaper. When |update_wallpaper| is true, sets wallpaper to the
275   // loaded wallpaper. Must run on wallpaper sequenced worker thread.
276   void GetCustomWallpaperInternal(const std::string& email,
277                                   const WallpaperInfo& info,
278                                   const base::FilePath& wallpaper_path,
279                                   bool update_wallpaper);
280 
281   // Gets wallpaper information of |email| from Local State or memory. Returns
282   // false if wallpaper information is not found.
283   bool GetUserWallpaperInfo(const std::string& email, WallpaperInfo* info);
284 
285   // Sets wallpaper to the decoded wallpaper if |update_wallpaper| is true.
286   // Otherwise, cache wallpaper to memory if not logged in.
287   void OnWallpaperDecoded(const std::string& email,
288                           ash::WallpaperLayout layout,
289                           bool update_wallpaper,
290                           const UserImage& wallpaper);
291 
292   // Generates thumbnail of custom wallpaper on wallpaper sequenced worker
293   // thread. If |persistent| is true, saves original custom image and resized
294   // images to disk.
295   void ProcessCustomWallpaper(const std::string& user_id_hash,
296                               bool persistent,
297                               const WallpaperInfo& info,
298                               scoped_ptr<gfx::ImageSkia> image,
299                               const UserImage::RawImage& raw_image);
300 
301   // Record data for User Metrics Analysis.
302   void RecordUma(User::WallpaperType type, int index);
303 
304   // Saves original custom wallpaper to |path| (absolute path) on filesystem
305   // and starts resizing operation of the custom wallpaper if necessary.
306   void SaveCustomWallpaper(const std::string& user_id_hash,
307                            const base::FilePath& path,
308                            ash::WallpaperLayout layout,
309                            const UserImage& wallpaper);
310 
311   // Saves wallpaper image raw |data| to |path| (absolute path) in file system.
312   void SaveWallpaperInternal(const base::FilePath& path, const char* data,
313                              int size);
314 
315   // Starts to load wallpaper at |wallpaper_path|. If |wallpaper_path| is the
316   // same as |current_wallpaper_path_|, do nothing. Must be called on UI thread.
317   void StartLoad(const std::string& email,
318                  const WallpaperInfo& info,
319                  bool update_wallpaper,
320                  const base::FilePath& wallpaper_path);
321 
322   // Notify all registed observers.
323   void NotifyAnimationFinished();
324 
325   // The number of loaded wallpapers.
326   int loaded_wallpapers_;
327 
328   // Sequence token associated with wallpaper operations.
329   base::SequencedWorkerPool::SequenceToken sequence_token_;
330 
331   // Wallpaper sequenced task runner.
332   scoped_refptr<base::SequencedTaskRunner> task_runner_;
333 
334   // The file path of current loaded/loading custom/online wallpaper.
335   base::FilePath current_wallpaper_path_;
336 
337   // Loads user wallpaper from its file.
338   scoped_refptr<UserImageLoader> wallpaper_loader_;
339 
340   // Logged-in user wallpaper information.
341   WallpaperInfo current_user_wallpaper_info_;
342 
343   // If non-NULL, used in place of the real command line.
344   CommandLine* command_line_for_testing_;
345 
346   // Caches wallpapers of users. Accessed only on UI thread.
347   CustomWallpaperMap wallpaper_cache_;
348 
349   // The last selected user on user pod row.
350   std::string last_selected_user_;
351 
352   bool should_cache_wallpaper_;
353 
354   scoped_ptr<CrosSettings::ObserverSubscription>
355       show_user_name_on_signin_subscription_;
356 
357   base::WeakPtrFactory<WallpaperManager> weak_factory_;
358 
359   content::NotificationRegistrar registrar_;
360 
361   ObserverList<Observer> observers_;
362 
363   DISALLOW_COPY_AND_ASSIGN(WallpaperManager);
364 };
365 
366 }  // namespace chromeos
367 
368 #endif  // CHROME_BROWSER_CHROMEOS_LOGIN_WALLPAPER_MANAGER_H_
369