Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(184)

Side by Side Diff: ash/common/wallpaper/wallpaper_controller.cc

Issue 2736573002: chromeos: Move files in //ash/common to //ash, part 2 (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 #include "ash/common/wallpaper/wallpaper_controller.h"
6
7 #include <string>
8 #include <utility>
9
10 #include "ash/common/ash_switches.h"
11 #include "ash/common/wallpaper/wallpaper_controller_observer.h"
12 #include "ash/common/wallpaper/wallpaper_delegate.h"
13 #include "ash/common/wallpaper/wallpaper_view.h"
14 #include "ash/common/wallpaper/wallpaper_widget_controller.h"
15 #include "ash/common/wm_shell.h"
16 #include "ash/common/wm_window.h"
17 #include "ash/public/cpp/shell_window_ids.h"
18 #include "ash/root_window_controller.h"
19 #include "base/bind.h"
20 #include "base/command_line.h"
21 #include "base/logging.h"
22 #include "base/task_runner.h"
23 #include "components/wallpaper/wallpaper_color_calculator.h"
24 #include "components/wallpaper/wallpaper_resizer.h"
25 #include "ui/display/manager/managed_display_info.h"
26 #include "ui/display/screen.h"
27 #include "ui/gfx/color_analysis.h"
28 #include "ui/views/widget/widget.h"
29
30 namespace ash {
31
32 namespace {
33
34 // How long to wait reloading the wallpaper after the display size has changed.
35 const int kWallpaperReloadDelayMs = 100;
36
37 } // namespace
38
39 // static
40 bool WallpaperController::GetProminentColorProfile(
41 color_utils::LumaRange* luma,
42 color_utils::SaturationRange* saturation) {
43 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
44 switches::kAshShelfColor)) {
45 return false;
46 }
47
48 *luma = color_utils::LumaRange::NORMAL;
49 *saturation = color_utils::SaturationRange::VIBRANT;
50
51 const std::string switch_value =
52 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
53 switches::kAshShelfColor);
54 if (switch_value.find("light") != std::string::npos)
55 *luma = color_utils::LumaRange::LIGHT;
56 else if (switch_value.find("normal") != std::string::npos)
57 *luma = color_utils::LumaRange::NORMAL;
58 else if (switch_value.find("dark") != std::string::npos)
59 *luma = color_utils::LumaRange::DARK;
60
61 if (switch_value.find("vibrant") != std::string::npos)
62 *saturation = color_utils::SaturationRange::VIBRANT;
63 else if (switch_value.find("muted") != std::string::npos)
64 *saturation = color_utils::SaturationRange::MUTED;
65
66 return true;
67 }
68
69 WallpaperController::WallpaperController(
70 const scoped_refptr<base::TaskRunner>& task_runner)
71 : locked_(false),
72 wallpaper_mode_(WALLPAPER_NONE),
73 prominent_color_(SK_ColorTRANSPARENT),
74 wallpaper_reload_delay_(kWallpaperReloadDelayMs),
75 task_runner_(task_runner) {
76 WmShell::Get()->AddDisplayObserver(this);
77 WmShell::Get()->AddShellObserver(this);
78 }
79
80 WallpaperController::~WallpaperController() {
81 if (current_wallpaper_)
82 current_wallpaper_->RemoveObserver(this);
83 if (color_calculator_)
84 color_calculator_->RemoveObserver(this);
85 WmShell::Get()->RemoveDisplayObserver(this);
86 WmShell::Get()->RemoveShellObserver(this);
87 }
88
89 void WallpaperController::BindRequest(
90 mojom::WallpaperControllerRequest request) {
91 bindings_.AddBinding(this, std::move(request));
92 }
93
94 gfx::ImageSkia WallpaperController::GetWallpaper() const {
95 if (current_wallpaper_)
96 return current_wallpaper_->image();
97 return gfx::ImageSkia();
98 }
99
100 void WallpaperController::AddObserver(WallpaperControllerObserver* observer) {
101 observers_.AddObserver(observer);
102 }
103
104 void WallpaperController::RemoveObserver(
105 WallpaperControllerObserver* observer) {
106 observers_.RemoveObserver(observer);
107 }
108
109 wallpaper::WallpaperLayout WallpaperController::GetWallpaperLayout() const {
110 if (current_wallpaper_)
111 return current_wallpaper_->layout();
112 return wallpaper::WALLPAPER_LAYOUT_CENTER_CROPPED;
113 }
114
115 void WallpaperController::SetWallpaperImage(const gfx::ImageSkia& image,
116 wallpaper::WallpaperLayout layout) {
117 VLOG(1) << "SetWallpaper: image_id="
118 << wallpaper::WallpaperResizer::GetImageId(image)
119 << " layout=" << layout;
120
121 if (WallpaperIsAlreadyLoaded(image, true /* compare_layouts */, layout)) {
122 VLOG(1) << "Wallpaper is already loaded";
123 return;
124 }
125
126 current_wallpaper_.reset(new wallpaper::WallpaperResizer(
127 image, GetMaxDisplaySizeInNative(), layout, task_runner_));
128 current_wallpaper_->AddObserver(this);
129 current_wallpaper_->StartResize();
130
131 for (auto& observer : observers_)
132 observer.OnWallpaperDataChanged();
133 wallpaper_mode_ = WALLPAPER_IMAGE;
134 InstallDesktopControllerForAllWindows();
135 }
136
137 void WallpaperController::CreateEmptyWallpaper() {
138 SetProminentColor(SK_ColorTRANSPARENT);
139 current_wallpaper_.reset();
140 wallpaper_mode_ = WALLPAPER_IMAGE;
141 InstallDesktopControllerForAllWindows();
142 }
143
144 bool WallpaperController::MoveToLockedContainer() {
145 if (locked_)
146 return false;
147 locked_ = true;
148 return ReparentWallpaper(GetWallpaperContainerId(true));
149 }
150
151 bool WallpaperController::MoveToUnlockedContainer() {
152 if (!locked_)
153 return false;
154 locked_ = false;
155 return ReparentWallpaper(GetWallpaperContainerId(false));
156 }
157
158 void WallpaperController::OnDisplayConfigurationChanged() {
159 gfx::Size max_display_size = GetMaxDisplaySizeInNative();
160 if (current_max_display_size_ != max_display_size) {
161 current_max_display_size_ = max_display_size;
162 if (wallpaper_mode_ == WALLPAPER_IMAGE && current_wallpaper_) {
163 timer_.Stop();
164 timer_.Start(FROM_HERE,
165 base::TimeDelta::FromMilliseconds(wallpaper_reload_delay_),
166 base::Bind(&WallpaperController::UpdateWallpaper,
167 base::Unretained(this), false /* clear cache */));
168 }
169 }
170 }
171
172 void WallpaperController::OnRootWindowAdded(WmWindow* root_window) {
173 // The wallpaper hasn't been set yet.
174 if (wallpaper_mode_ == WALLPAPER_NONE)
175 return;
176
177 // Handle resolution change for "built-in" images.
178 gfx::Size max_display_size = GetMaxDisplaySizeInNative();
179 if (current_max_display_size_ != max_display_size) {
180 current_max_display_size_ = max_display_size;
181 if (wallpaper_mode_ == WALLPAPER_IMAGE && current_wallpaper_)
182 UpdateWallpaper(true /* clear cache */);
183 }
184
185 InstallDesktopController(root_window);
186 }
187
188 // static
189 gfx::Size WallpaperController::GetMaxDisplaySizeInNative() {
190 // Return an empty size for test environments where the screen is null.
191 if (!display::Screen::GetScreen())
192 return gfx::Size();
193
194 // Note that |shell| is null when this is called from Chrome running in Mash.
195 WmShell* shell = WmShell::Get();
196
197 gfx::Size max;
198 for (const auto& display : display::Screen::GetScreen()->GetAllDisplays()) {
199 // Use the native size, not ManagedDisplayInfo::size_in_pixel or
200 // Display::size.
201 // TODO(msw): Avoid using Display::size here; see http://crbug.com/613657.
202 gfx::Size size = display.size();
203 if (shell) {
204 display::ManagedDisplayInfo info = shell->GetDisplayInfo(display.id());
205 // TODO(mash): Mash returns a fake ManagedDisplayInfo. crbug.com/622480
206 if (info.id() == display.id())
207 size = info.bounds_in_native().size();
208 }
209 if (display.rotation() == display::Display::ROTATE_90 ||
210 display.rotation() == display::Display::ROTATE_270) {
211 size = gfx::Size(size.height(), size.width());
212 }
213 max.SetToMax(size);
214 }
215
216 return max;
217 }
218
219 bool WallpaperController::WallpaperIsAlreadyLoaded(
220 const gfx::ImageSkia& image,
221 bool compare_layouts,
222 wallpaper::WallpaperLayout layout) const {
223 if (!current_wallpaper_)
224 return false;
225
226 // Compare layouts only if necessary.
227 if (compare_layouts && layout != current_wallpaper_->layout())
228 return false;
229
230 return wallpaper::WallpaperResizer::GetImageId(image) ==
231 current_wallpaper_->original_image_id();
232 }
233
234 void WallpaperController::OpenSetWallpaperPage() {
235 if (wallpaper_picker_ &&
236 WmShell::Get()->wallpaper_delegate()->CanOpenSetWallpaperPage()) {
237 wallpaper_picker_->Open();
238 }
239 }
240
241 void WallpaperController::SetWallpaperPicker(mojom::WallpaperPickerPtr picker) {
242 wallpaper_picker_ = std::move(picker);
243 }
244
245 void WallpaperController::SetWallpaper(const SkBitmap& wallpaper,
246 wallpaper::WallpaperLayout layout) {
247 if (wallpaper.isNull())
248 return;
249
250 SetWallpaperImage(gfx::ImageSkia::CreateFrom1xBitmap(wallpaper), layout);
251 }
252
253 void WallpaperController::OnWallpaperResized() {
254 CalculateWallpaperColors();
255 }
256
257 void WallpaperController::OnColorCalculationComplete() {
258 const SkColor color = color_calculator_->prominent_color();
259 color_calculator_.reset();
260 SetProminentColor(color);
261 }
262
263 void WallpaperController::InstallDesktopController(WmWindow* root_window) {
264 WallpaperWidgetController* component = nullptr;
265 int container_id = GetWallpaperContainerId(locked_);
266
267 switch (wallpaper_mode_) {
268 case WALLPAPER_IMAGE: {
269 component = new WallpaperWidgetController(
270 CreateWallpaper(root_window, container_id));
271 break;
272 }
273 case WALLPAPER_NONE:
274 NOTREACHED();
275 return;
276 }
277
278 RootWindowController* controller = root_window->GetRootWindowController();
279 controller->SetAnimatingWallpaperWidgetController(
280 new AnimatingWallpaperWidgetController(component));
281 component->StartAnimating(controller);
282 }
283
284 void WallpaperController::InstallDesktopControllerForAllWindows() {
285 for (WmWindow* root : WmShell::Get()->GetAllRootWindows())
286 InstallDesktopController(root);
287 current_max_display_size_ = GetMaxDisplaySizeInNative();
288 }
289
290 bool WallpaperController::ReparentWallpaper(int container) {
291 bool moved = false;
292 for (WmWindow* root_window : WmShell::Get()->GetAllRootWindows()) {
293 RootWindowController* root_window_controller =
294 root_window->GetRootWindowController();
295 // In the steady state (no animation playing) the wallpaper widget
296 // controller exists in the RootWindowController.
297 WallpaperWidgetController* wallpaper_widget_controller =
298 root_window_controller->wallpaper_widget_controller();
299 if (wallpaper_widget_controller) {
300 moved |= wallpaper_widget_controller->Reparent(
301 root_window_controller->GetWindow(), container);
302 }
303 // During wallpaper show animations the controller lives in
304 // AnimatingWallpaperWidgetController owned by RootWindowController.
305 // NOTE: If an image load happens during a wallpaper show animation there
306 // can temporarily be two wallpaper widgets. We must reparent both of them,
307 // one above and one here.
308 WallpaperWidgetController* animating_controller =
309 root_window_controller->animating_wallpaper_widget_controller()
310 ? root_window_controller->animating_wallpaper_widget_controller()
311 ->GetController(false)
312 : nullptr;
313 if (animating_controller) {
314 moved |= animating_controller->Reparent(
315 root_window_controller->GetWindow(), container);
316 }
317 }
318 return moved;
319 }
320
321 int WallpaperController::GetWallpaperContainerId(bool locked) {
322 return locked ? kShellWindowId_LockScreenWallpaperContainer
323 : kShellWindowId_WallpaperContainer;
324 }
325
326 void WallpaperController::UpdateWallpaper(bool clear_cache) {
327 current_wallpaper_.reset();
328 WmShell::Get()->wallpaper_delegate()->UpdateWallpaper(clear_cache);
329 }
330
331 void WallpaperController::SetProminentColor(SkColor color) {
332 if (prominent_color_ == color)
333 return;
334
335 prominent_color_ = color;
336 for (auto& observer : observers_)
337 observer.OnWallpaperColorsChanged();
338 }
339
340 void WallpaperController::CalculateWallpaperColors() {
341 color_utils::LumaRange luma;
342 color_utils::SaturationRange saturation;
343 if (!GetProminentColorProfile(&luma, &saturation))
344 return;
345
346 if (color_calculator_)
347 color_calculator_->RemoveObserver(this);
348
349 color_calculator_ = base::MakeUnique<wallpaper::WallpaperColorCalculator>(
350 GetWallpaper(), luma, saturation, task_runner_);
351 color_calculator_->AddObserver(this);
352 if (!color_calculator_->StartCalculation())
353 SetProminentColor(SK_ColorTRANSPARENT);
354 }
355
356 } // namespace ash
OLDNEW
« no previous file with comments | « ash/common/wallpaper/wallpaper_controller.h ('k') | ash/common/wallpaper/wallpaper_controller_observer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698