summaryrefslogtreecommitdiff
path: root/chromium/ash/desktop_background/desktop_background_controller.h
blob: afdc2dc52fcea83d5a765264bd7a2f14bf8c687e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
// Copyright (c) 2012 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 ASH_DESKTOP_BACKGROUND_DESKTOP_BACKGROUND_CONTROLLER_H_
#define ASH_DESKTOP_BACKGROUND_DESKTOP_BACKGROUND_CONTROLLER_H_

#include "ash/ash_export.h"
#include "base/basictypes.h"
#include "base/files/file_path.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "ui/aura/window.h"
#include "ui/compositor/layer.h"
#include "ui/gfx/image/image_skia.h"

typedef unsigned int SkColor;

class CommandLine;

namespace aura {
class RootWindow;
}

namespace ash {
namespace internal {
class DesktopBackgroundControllerTest;
}  // namespace internal

enum WallpaperLayout {
  // Center the wallpaper on the desktop without scaling it. The wallpaper
  // may be cropped.
  WALLPAPER_LAYOUT_CENTER,
  // Scale the wallpaper (while preserving its aspect ratio) to cover the
  // desktop; the wallpaper may be cropped.
  WALLPAPER_LAYOUT_CENTER_CROPPED,
  // Scale the wallpaper (without preserving its aspect ratio) to match the
  // desktop's size.
  WALLPAPER_LAYOUT_STRETCH,
  // Tile the wallpaper over the background without scaling it.
  WALLPAPER_LAYOUT_TILE,
};

enum WallpaperResolution {
  WALLPAPER_RESOLUTION_LARGE,
  WALLPAPER_RESOLUTION_SMALL
};

const SkColor kLoginWallpaperColor = 0xFEFEFE;

// The width and height of small/large resolution wallpaper. When screen size is
// smaller than |kSmallWallpaperMaxWidth| and |kSmallWallpaperMaxHeight|, the
// small resolution wallpaper should be used. Otherwise, uses the large
// resolution wallpaper.
ASH_EXPORT extern const int kSmallWallpaperMaxWidth;
ASH_EXPORT extern const int kSmallWallpaperMaxHeight;
ASH_EXPORT extern const int kLargeWallpaperMaxWidth;
ASH_EXPORT extern const int kLargeWallpaperMaxHeight;

// The width and heigh of wallpaper thumbnails.
ASH_EXPORT extern const int kWallpaperThumbnailWidth;
ASH_EXPORT extern const int kWallpaperThumbnailHeight;

class DesktopBackgroundControllerObserver;
class WallpaperResizer;

// Loads selected desktop wallpaper from file system asynchronously and updates
// background layer if loaded successfully.
class ASH_EXPORT DesktopBackgroundController {
 public:
  enum BackgroundMode {
    BACKGROUND_NONE,
    BACKGROUND_IMAGE,
    BACKGROUND_SOLID_COLOR
  };

  DesktopBackgroundController();
  virtual ~DesktopBackgroundController();

  BackgroundMode desktop_background_mode() const {
    return desktop_background_mode_;
  }

  void set_command_line_for_testing(CommandLine* command_line) {
    command_line_for_testing_ = command_line;
  }

  // Add/Remove observers.
  void AddObserver(DesktopBackgroundControllerObserver* observer);
  void RemoveObserver(DesktopBackgroundControllerObserver* observer);

  // Provides current image on the background, or empty gfx::ImageSkia if there
  // is no image, e.g. background is solid color.
  gfx::ImageSkia GetWallpaper() const;

  WallpaperLayout GetWallpaperLayout() const;

  // Initialize root window's background.
  void OnRootWindowAdded(aura::RootWindow* root_window);

  // Loads builtin wallpaper asynchronously and sets to current wallpaper
  // after loaded. Returns true if the controller started loading the
  // wallpaper and false otherwise (i.e. the appropriate wallpaper was
  // already loading or loaded).
  bool SetDefaultWallpaper(bool is_guest);

  // Sets the user selected custom wallpaper. Called when user selected a file
  // from file system or changed the layout of wallpaper.
  void SetCustomWallpaper(const gfx::ImageSkia& image, WallpaperLayout layout);

  // Cancels the current wallpaper loading operation.
  void CancelPendingWallpaperOperation();

  // Sets the desktop background to solid color mode and creates a solid
  // |color| layout.
  void SetDesktopBackgroundSolidColorMode(SkColor color);

  // Creates an empty wallpaper. Some tests require a wallpaper widget is ready
  // when running. However, the wallpaper widgets are now created asynchronously
  // . If loading a real wallpaper, there are cases that these tests crash
  // because the required widget is not ready. This function synchronously
  // creates an empty widget for those tests to prevent crashes. An example test
  // is SystemGestureEventFilterTest.ThreeFingerSwipe.
  void CreateEmptyWallpaper();

  // Returns the appropriate wallpaper resolution for all root windows.
  WallpaperResolution GetAppropriateResolution();

  // Move all desktop widgets to locked container.
  // Returns true if the desktop moved.
  bool MoveDesktopToLockedContainer();

  // Move all desktop widgets to unlocked container.
  // Returns true if the desktop moved.
  bool MoveDesktopToUnlockedContainer();

 private:
  friend class internal::DesktopBackgroundControllerTest;

  // An operation to asynchronously loads wallpaper.
  class WallpaperLoader;

  // Returns true if the specified default wallpaper is already being
  // loaded by |wallpaper_loader_| or stored in |current_wallpaper_|.
  bool DefaultWallpaperIsAlreadyLoadingOrLoaded(
      const base::FilePath& image_file, int image_resource_id) const;

  // Returns true if the specified custom wallpaper is already stored
  // in |current_wallpaper_|.
  bool CustomWallpaperIsAlreadyLoaded(const gfx::ImageSkia& image) const;

  // Creates view for all root windows, or notifies them to repaint if they
  // already exist.
  void SetDesktopBackgroundImageMode();

  // Creates a new background widget and sets the background mode to image mode.
  // Called after a default wallpaper has been loaded successfully.
  void OnDefaultWallpaperLoadCompleted(scoped_refptr<WallpaperLoader> loader);

  // Adds layer with solid |color| to container |container_id| in |root_window|.
  ui::Layer* SetColorLayerForContainer(SkColor color,
                                       aura::RootWindow* root_window,
                                       int container_id);

  // Creates and adds component for current mode (either Widget or Layer) to
  // |root_window|.
  void InstallDesktopController(aura::RootWindow* root_window);

  // Creates and adds component for current mode (either Widget or Layer) to
  // all root windows.
  void InstallDesktopControllerForAllWindows();

  // Moves all desktop components from one container to other across all root
  // windows. Returns true if a desktop moved.
  bool ReparentBackgroundWidgets(int src_container, int dst_container);

  // Returns id for background container for unlocked and locked states.
  int GetBackgroundContainerId(bool locked);

  // Send notification that background animation finished.
  void NotifyAnimationFinished();

  // If non-NULL, used in place of the real command line.
  CommandLine* command_line_for_testing_;

  // Can change at runtime.
  bool locked_;

  BackgroundMode desktop_background_mode_;

  SkColor background_color_;

  ObserverList<DesktopBackgroundControllerObserver> observers_;

  // The current wallpaper.
  scoped_ptr<WallpaperResizer> current_wallpaper_;

  // If a default wallpaper is stored in |current_wallpaper_|, the path and
  // resource ID that were passed to WallpaperLoader when loading it.
  // Otherwise, empty and -1, respectively.
  base::FilePath current_default_wallpaper_path_;
  int current_default_wallpaper_resource_id_;

  scoped_refptr<WallpaperLoader> wallpaper_loader_;

  base::WeakPtrFactory<DesktopBackgroundController> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(DesktopBackgroundController);
};

}  // namespace ash

#endif  // ASH_DESKTOP_BACKGROUND_DESKTOP_BACKGROUND_CONTROLLER_H_