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
20typedef unsigned int SkColor;
21
22class CommandLine;
23
24namespace aura {
25class Window;
26}
27
28namespace ash {
29
30enum 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
44enum WallpaperResolution {
45  WALLPAPER_RESOLUTION_LARGE,
46  WALLPAPER_RESOLUTION_SMALL
47};
48
49const 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.
55ASH_EXPORT extern const int kSmallWallpaperMaxWidth;
56ASH_EXPORT extern const int kSmallWallpaperMaxHeight;
57ASH_EXPORT extern const int kLargeWallpaperMaxWidth;
58ASH_EXPORT extern const int kLargeWallpaperMaxHeight;
59
60// The width and heigh of wallpaper thumbnails.
61ASH_EXPORT extern const int kWallpaperThumbnailWidth;
62ASH_EXPORT extern const int kWallpaperThumbnailHeight;
63
64class DesktopBackgroundControllerObserver;
65class WallpaperResizer;
66
67// Loads selected desktop wallpaper from file system asynchronously and updates
68// background layer if loaded successfully.
69class 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