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