1 // Copyright (c) 2012 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 ASH_DESKTOP_BACKGROUND_DESKTOP_BACKGROUND_CONTROLLER_H_ 6 #define ASH_DESKTOP_BACKGROUND_DESKTOP_BACKGROUND_CONTROLLER_H_ 7 8 #include "ash/ash_export.h" 9 #include "ash/display/display_controller.h" 10 #include "base/basictypes.h" 11 #include "base/files/file_path.h" 12 #include "base/gtest_prod_util.h" 13 #include "base/memory/scoped_ptr.h" 14 #include "base/memory/weak_ptr.h" 15 #include "base/observer_list.h" 16 #include "base/timer/timer.h" 17 #include "ui/compositor/layer.h" 18 #include "ui/gfx/image/image_skia.h" 19 20 typedef unsigned int SkColor; 21 22 class CommandLine; 23 24 namespace aura { 25 class Window; 26 } 27 28 namespace ash { 29 30 enum WallpaperLayout { 31 // Center the wallpaper on the desktop without scaling it. The wallpaper 32 // may be cropped. 33 WALLPAPER_LAYOUT_CENTER, 34 // Scale the wallpaper (while preserving its aspect ratio) to cover the 35 // desktop; the wallpaper may be cropped. 36 WALLPAPER_LAYOUT_CENTER_CROPPED, 37 // Scale the wallpaper (without preserving its aspect ratio) to match the 38 // desktop's size. 39 WALLPAPER_LAYOUT_STRETCH, 40 // Tile the wallpaper over the background without scaling it. 41 WALLPAPER_LAYOUT_TILE, 42 }; 43 44 enum WallpaperResolution { 45 WALLPAPER_RESOLUTION_LARGE, 46 WALLPAPER_RESOLUTION_SMALL 47 }; 48 49 const SkColor kLoginWallpaperColor = 0xFEFEFE; 50 51 // The width and height of small/large resolution wallpaper. When screen size is 52 // smaller than |kSmallWallpaperMaxWidth| and |kSmallWallpaperMaxHeight|, the 53 // small resolution wallpaper should be used. Otherwise, uses the large 54 // resolution wallpaper. 55 ASH_EXPORT extern const int kSmallWallpaperMaxWidth; 56 ASH_EXPORT extern const int kSmallWallpaperMaxHeight; 57 ASH_EXPORT extern const int kLargeWallpaperMaxWidth; 58 ASH_EXPORT extern const int kLargeWallpaperMaxHeight; 59 60 // The width and heigh of wallpaper thumbnails. 61 ASH_EXPORT extern const int kWallpaperThumbnailWidth; 62 ASH_EXPORT extern const int kWallpaperThumbnailHeight; 63 64 class DesktopBackgroundControllerObserver; 65 class WallpaperResizer; 66 67 // Loads selected desktop wallpaper from file system asynchronously and updates 68 // background layer if loaded successfully. 69 class ASH_EXPORT DesktopBackgroundController 70 : public DisplayController::Observer { 71 public: 72 enum BackgroundMode { 73 BACKGROUND_NONE, 74 BACKGROUND_IMAGE, 75 }; 76 77 DesktopBackgroundController(); 78 virtual ~DesktopBackgroundController(); 79 80 BackgroundMode desktop_background_mode() const { 81 return desktop_background_mode_; 82 } 83 84 void set_command_line_for_testing(CommandLine* command_line) { 85 command_line_for_testing_ = command_line; 86 } 87 88 // Add/Remove observers. 89 void AddObserver(DesktopBackgroundControllerObserver* observer); 90 void RemoveObserver(DesktopBackgroundControllerObserver* observer); 91 92 // Provides current image on the background, or empty gfx::ImageSkia if there 93 // is no image, e.g. background is none. 94 gfx::ImageSkia GetWallpaper() const; 95 96 WallpaperLayout GetWallpaperLayout() const; 97 98 // Initialize root window's background. 99 void OnRootWindowAdded(aura::Window* root_window); 100 101 // Loads builtin wallpaper asynchronously and sets to current wallpaper 102 // after loaded. Returns true if the controller started loading the 103 // wallpaper and false otherwise (i.e. the appropriate wallpaper was 104 // already loading or loaded). 105 bool SetDefaultWallpaper(bool is_guest); 106 107 // Sets the user selected custom wallpaper. Called when user selected a file 108 // from file system or changed the layout of wallpaper. 109 void SetCustomWallpaper(const gfx::ImageSkia& image, WallpaperLayout layout); 110 111 // Cancels the current wallpaper loading operation. 112 void CancelPendingWallpaperOperation(); 113 114 // Creates an empty wallpaper. Some tests require a wallpaper widget is ready 115 // when running. However, the wallpaper widgets are now created asynchronously 116 // . If loading a real wallpaper, there are cases that these tests crash 117 // because the required widget is not ready. This function synchronously 118 // creates an empty widget for those tests to prevent crashes. An example test 119 // is SystemGestureEventFilterTest.ThreeFingerSwipe. 120 void CreateEmptyWallpaper(); 121 122 // Returns the appropriate wallpaper resolution for all root windows. 123 WallpaperResolution GetAppropriateResolution(); 124 125 // Move all desktop widgets to locked container. 126 // Returns true if the desktop moved. 127 bool MoveDesktopToLockedContainer(); 128 129 // Move all desktop widgets to unlocked container. 130 // Returns true if the desktop moved. 131 bool MoveDesktopToUnlockedContainer(); 132 133 // Overrides DisplayController::Observer: 134 virtual void OnDisplayConfigurationChanged() OVERRIDE; 135 136 private: 137 friend class DesktopBackgroundControllerTest; 138 FRIEND_TEST_ALL_PREFIXES(DesktopBackgroundControllerTest, GetMaxDisplaySize); 139 140 // An operation to asynchronously loads wallpaper. 141 class WallpaperLoader; 142 143 // Returns true if the specified default wallpaper is already being 144 // loaded by |wallpaper_loader_| or stored in |current_wallpaper_|. 145 bool DefaultWallpaperIsAlreadyLoadingOrLoaded( 146 const base::FilePath& image_file, int image_resource_id) const; 147 148 // Returns true if the specified custom wallpaper is already stored 149 // in |current_wallpaper_|. 150 bool CustomWallpaperIsAlreadyLoaded(const gfx::ImageSkia& image) const; 151 152 // Creates view for all root windows, or notifies them to repaint if they 153 // already exist. 154 void SetDesktopBackgroundImageMode(); 155 156 // Creates a new background widget and sets the background mode to image mode. 157 // Called after a default wallpaper has been loaded successfully. 158 void OnDefaultWallpaperLoadCompleted(scoped_refptr<WallpaperLoader> loader); 159 160 // Creates and adds component for current mode (either Widget or Layer) to 161 // |root_window|. 162 void InstallDesktopController(aura::Window* root_window); 163 164 // Creates and adds component for current mode (either Widget or Layer) to 165 // all root windows. 166 void InstallDesktopControllerForAllWindows(); 167 168 // Moves all desktop components from one container to other across all root 169 // windows. Returns true if a desktop moved. 170 bool ReparentBackgroundWidgets(int src_container, int dst_container); 171 172 // Returns id for background container for unlocked and locked states. 173 int GetBackgroundContainerId(bool locked); 174 175 // Send notification that background animation finished. 176 void NotifyAnimationFinished(); 177 178 // Reload the wallpaper. 179 void UpdateWallpaper(); 180 181 void set_wallpaper_reload_delay_for_test(bool value) { 182 wallpaper_reload_delay_ = value; 183 } 184 185 // Returns the maximum size of all displays combined in native 186 // resolutions. Note that this isn't the bounds of the display who 187 // has maximum resolutions. Instead, this returns the size of the 188 // maximum width of all displays, and the maximum height of all displays. 189 static gfx::Size GetMaxDisplaySizeInNative(); 190 191 // If non-NULL, used in place of the real command line. 192 CommandLine* command_line_for_testing_; 193 194 // Can change at runtime. 195 bool locked_; 196 197 BackgroundMode desktop_background_mode_; 198 199 SkColor background_color_; 200 201 ObserverList<DesktopBackgroundControllerObserver> observers_; 202 203 // The current wallpaper. 204 scoped_ptr<WallpaperResizer> current_wallpaper_; 205 206 // If a default wallpaper is stored in |current_wallpaper_|, the path and 207 // resource ID that were passed to WallpaperLoader when loading it. 208 // Otherwise, empty and -1, respectively. 209 base::FilePath current_default_wallpaper_path_; 210 int current_default_wallpaper_resource_id_; 211 212 gfx::Size current_max_display_size_; 213 214 scoped_refptr<WallpaperLoader> wallpaper_loader_; 215 216 base::WeakPtrFactory<DesktopBackgroundController> weak_ptr_factory_; 217 218 base::OneShotTimer<DesktopBackgroundController> timer_; 219 220 int wallpaper_reload_delay_; 221 222 DISALLOW_COPY_AND_ASSIGN(DesktopBackgroundController); 223 }; 224 225 } // namespace ash 226 227 #endif // ASH_DESKTOP_BACKGROUND_DESKTOP_BACKGROUND_CONTROLLER_H_ 228