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