// 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_WALLPAPER_MANAGER_H_ #define CHROME_BROWSER_CHROMEOS_LOGIN_WALLPAPER_MANAGER_H_ #include <string> #include "ash/desktop_background/desktop_background_controller.h" #include "base/files/file_path.h" #include "base/memory/ref_counted_memory.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "base/threading/sequenced_worker_pool.h" #include "base/time/time.h" #include "chrome/browser/chromeos/login/user.h" #include "chrome/browser/chromeos/login/user_image.h" #include "chrome/browser/chromeos/login/user_image_loader.h" #include "chrome/browser/chromeos/settings/cros_settings.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" #include "third_party/icu/source/i18n/unicode/timezone.h" #include "ui/gfx/image/image_skia.h" class CommandLine; class PrefRegistrySimple; namespace base { class SequencedTaskRunner; } namespace chromeos { struct WallpaperInfo { // Online wallpaper URL or file name of migrated wallpaper. std::string file; ash::WallpaperLayout layout; User::WallpaperType type; base::Time date; bool operator==(const WallpaperInfo& other) { return (file == other.file) && (layout == other.layout) && (type == other.type); } }; class WallpaperManagerBrowserTest; class UserImage; // Name of wallpaper sequence token. extern const char kWallpaperSequenceTokenName[]; // File path suffices of resized small or large wallpaper. // TODO(bshe): Use the same sub folder system as custom wallpapers use. // crbug.com/174928 extern const char kSmallWallpaperSuffix[]; extern const char kLargeWallpaperSuffix[]; // Directory names of custom wallpapers. extern const char kSmallWallpaperSubDir[]; extern const char kLargeWallpaperSubDir[]; extern const char kOriginalWallpaperSubDir[]; extern const char kThumbnailWallpaperSubDir[]; // This class maintains wallpapers for users who have logged into this Chrome // OS device. class WallpaperManager: public content::NotificationObserver { public: // For testing. class TestApi { public: explicit TestApi(WallpaperManager* wallpaper_manager); virtual ~TestApi(); base::FilePath current_wallpaper_path(); private: WallpaperManager* wallpaper_manager_; // not owned DISALLOW_COPY_AND_ASSIGN(TestApi); }; class Observer { public: virtual ~Observer() {} virtual void OnWallpaperAnimationFinished(const std::string& email) = 0; }; static WallpaperManager* Get(); WallpaperManager(); virtual ~WallpaperManager(); void set_command_line_for_testing(CommandLine* command_line) { command_line_for_testing_ = command_line; } // Indicates imminent shutdown, allowing the WallpaperManager to remove any // observers it has registered. void Shutdown(); // Registers wallpaper manager preferences. static void RegisterPrefs(PrefRegistrySimple* registry); // Adds PowerManagerClient, TimeZoneSettings and CrosSettings observers. void AddObservers(); // Loads wallpaper asynchronously if the current wallpaper is not the // wallpaper of logged in user. void EnsureLoggedInUserWallpaperLoaded(); // Clears ONLINE and CUSTOM wallpaper cache. void ClearWallpaperCache(); // Returns custom wallpaper path. Append |sub_dir|, |user_id_hash| and |file| // to custom wallpaper directory. base::FilePath GetCustomWallpaperPath(const char* sub_dir, const std::string& user_id_hash, const std::string& file); // Gets encoded wallpaper from cache. Returns true if success. bool GetWallpaperFromCache(const std::string& email, gfx::ImageSkia* wallpaper); // Returns filepath to save original custom wallpaper for the given user. base::FilePath GetOriginalWallpaperPathForUser(const std::string& username); // Gets wallpaper information of logged in user. bool GetLoggedInUserWallpaperInfo(WallpaperInfo* info); // Initializes wallpaper. If logged in, loads user's wallpaper. If not logged // in, uses a solid color wallpaper. If logged in as a stub user, uses an // empty wallpaper. void InitializeWallpaper(); // NotificationObserver overrides: virtual void Observe(int type, const content::NotificationSource& source, const content::NotificationDetails& details) OVERRIDE; // Removes all |email| related wallpaper info and saved wallpapers. void RemoveUserWallpaperInfo(const std::string& email); // Resizes |wallpaper| to a resolution which is nearest to |preferred_width| // and |preferred_height| while maintaining aspect ratio. bool ResizeWallpaper(const UserImage& wallpaper, ash::WallpaperLayout layout, int preferred_width, int preferred_height, scoped_refptr<base::RefCountedBytes>* output); // Resizes |wallpaper| to a resolution which is nearest to |preferred_width| // and |preferred_height| while maintaining aspect ratio. And saves the // resized wallpaper to |path|. void ResizeAndSaveWallpaper(const UserImage& wallpaper, const base::FilePath& path, ash::WallpaperLayout layout, int preferred_width, int preferred_height); // Saves custom wallpaper to file, post task to generate thumbnail and updates // local state preferences. void SetCustomWallpaper(const std::string& username, const std::string& user_id_hash, const std::string& file, ash::WallpaperLayout layout, User::WallpaperType type, const UserImage& wallpaper); // Sets wallpaper to default wallpaper. void SetDefaultWallpaper(); // Sets one of the default wallpapers for the specified user and saves this // settings in local state. void SetInitialUserWallpaper(const std::string& username, bool is_persistent); // Sets selected wallpaper information for |username| and saves it to Local // State if |is_persistent| is true. void SetUserWallpaperInfo(const std::string& username, const WallpaperInfo& info, bool is_persistent); // Sets last selected user on user pod row. void SetLastSelectedUser(const std::string& last_selected_user); // Sets |email|'s wallpaper. void SetUserWallpaper(const std::string& email); // Sets wallpaper to |wallpaper|. void SetWallpaperFromImageSkia(const gfx::ImageSkia& wallpaper, ash::WallpaperLayout layout); // Updates current wallpaper. It may switch the size of wallpaper based on the // current display's resolution. void UpdateWallpaper(); // Adds given observer to the list. void AddObserver(Observer* observer); // Removes given observer from the list. void RemoveObserver(Observer* observer); private: friend class TestApi; friend class WallpaperManagerBrowserTest; typedef std::map<std::string, gfx::ImageSkia> CustomWallpaperMap; // The number of wallpapers have loaded. For test only. int loaded_wallpapers() const { return loaded_wallpapers_; } // Cache some (or all) logged in users' wallpapers to memory at login // screen. It should not compete with first wallpaper loading when boot // up/initialize login WebUI page. // There are two ways the first wallpaper might be loaded: // 1. Loaded on boot. Login WebUI waits for it. // 2. When flag --disable-boot-animation is passed. Login WebUI is loaded // right away and in 500ms after. Wallpaper started to load. // For case 2, should_cache_wallpaper_ is used to indicate if we need to // cache wallpapers on wallpaper animation finished. The cache operation // should be only executed once. void CacheUsersWallpapers(); // Caches |email|'s wallpaper to memory. void CacheUserWallpaper(const std::string& email); // Clears all obsolete wallpaper prefs from old version wallpaper pickers. void ClearObsoleteWallpaperPrefs(); // Deletes everything else except |path| in the same directory. void DeleteAllExcept(const base::FilePath& path); // Deletes a list of wallpaper files in |file_list|. void DeleteWallpaperInList(const std::vector<base::FilePath>& file_list); // Deletes all |email| related custom wallpapers and directories. void DeleteUserWallpapers(const std::string& email, const std::string& path_to_file); // Creates all new custom wallpaper directories for |user_id_hash| if not // exist. void EnsureCustomWallpaperDirectories(const std::string& user_id_hash); // Gets the CommandLine representing the current process's command line. CommandLine* GetComandLine(); // Initialize wallpaper of registered device after device policy is trusted. // Note that before device is enrolled, it proceeds with untrusted setting. void InitializeRegisteredDeviceWallpaper(); // Loads |email|'s wallpaper. When |update_wallpaper| is true, sets wallpaper // to the loaded wallpaper. void LoadWallpaper(const std::string& email, const WallpaperInfo& info, bool update_wallpaper); // Moves custom wallpapers from |email| directory to |user_id_hash| // directory. void MoveCustomWallpapersOnWorker(const std::string& email, const std::string& user_id_hash); // Called when the original custom wallpaper is moved to the new place. // Updates the corresponding user wallpaper info. void MoveCustomWallpapersSuccess(const std::string& email, const std::string& user_id_hash); // Moves custom wallpaper to a new place. Email address was used as directory // name in the old system, this is not safe. New directory system uses // user_id_hash instead of email. This must be called after user_id_hash is // ready. void MoveLoggedInUserCustomWallpaper(); // Gets |email|'s custom wallpaper at |wallpaper_path|. Falls back on original // custom wallpaper. When |update_wallpaper| is true, sets wallpaper to the // loaded wallpaper. Must run on wallpaper sequenced worker thread. void GetCustomWallpaperInternal(const std::string& email, const WallpaperInfo& info, const base::FilePath& wallpaper_path, bool update_wallpaper); // Gets wallpaper information of |email| from Local State or memory. Returns // false if wallpaper information is not found. bool GetUserWallpaperInfo(const std::string& email, WallpaperInfo* info); // Sets wallpaper to the decoded wallpaper if |update_wallpaper| is true. // Otherwise, cache wallpaper to memory if not logged in. void OnWallpaperDecoded(const std::string& email, ash::WallpaperLayout layout, bool update_wallpaper, const UserImage& wallpaper); // Generates thumbnail of custom wallpaper on wallpaper sequenced worker // thread. If |persistent| is true, saves original custom image and resized // images to disk. void ProcessCustomWallpaper(const std::string& user_id_hash, bool persistent, const WallpaperInfo& info, scoped_ptr<gfx::ImageSkia> image, const UserImage::RawImage& raw_image); // Record data for User Metrics Analysis. void RecordUma(User::WallpaperType type, int index); // Saves original custom wallpaper to |path| (absolute path) on filesystem // and starts resizing operation of the custom wallpaper if necessary. void SaveCustomWallpaper(const std::string& user_id_hash, const base::FilePath& path, ash::WallpaperLayout layout, const UserImage& wallpaper); // Saves wallpaper image raw |data| to |path| (absolute path) in file system. void SaveWallpaperInternal(const base::FilePath& path, const char* data, int size); // Starts to load wallpaper at |wallpaper_path|. If |wallpaper_path| is the // same as |current_wallpaper_path_|, do nothing. Must be called on UI thread. void StartLoad(const std::string& email, const WallpaperInfo& info, bool update_wallpaper, const base::FilePath& wallpaper_path); // Notify all registed observers. void NotifyAnimationFinished(); // The number of loaded wallpapers. int loaded_wallpapers_; // Sequence token associated with wallpaper operations. base::SequencedWorkerPool::SequenceToken sequence_token_; // Wallpaper sequenced task runner. scoped_refptr<base::SequencedTaskRunner> task_runner_; // The file path of current loaded/loading custom/online wallpaper. base::FilePath current_wallpaper_path_; // Loads user wallpaper from its file. scoped_refptr<UserImageLoader> wallpaper_loader_; // Logged-in user wallpaper information. WallpaperInfo current_user_wallpaper_info_; // If non-NULL, used in place of the real command line. CommandLine* command_line_for_testing_; // Caches wallpapers of users. Accessed only on UI thread. CustomWallpaperMap wallpaper_cache_; // The last selected user on user pod row. std::string last_selected_user_; bool should_cache_wallpaper_; scoped_ptr<CrosSettings::ObserverSubscription> show_user_name_on_signin_subscription_; base::WeakPtrFactory<WallpaperManager> weak_factory_; content::NotificationRegistrar registrar_; ObserverList<Observer> observers_; DISALLOW_COPY_AND_ASSIGN(WallpaperManager); }; } // namespace chromeos #endif // CHROME_BROWSER_CHROMEOS_LOGIN_WALLPAPER_MANAGER_H_