OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ash/wallpaper/wallpaper_controller.h" | 5 #include "ash/wallpaper/wallpaper_controller.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "ash/ash_switches.h" | 10 #include "ash/ash_switches.h" |
(...skipping 10 matching lines...) Expand all Loading... |
21 #include "base/command_line.h" | 21 #include "base/command_line.h" |
22 #include "base/logging.h" | 22 #include "base/logging.h" |
23 #include "base/sequenced_task_runner.h" | 23 #include "base/sequenced_task_runner.h" |
24 #include "base/task_scheduler/post_task.h" | 24 #include "base/task_scheduler/post_task.h" |
25 #include "components/wallpaper/wallpaper_color_calculator.h" | 25 #include "components/wallpaper/wallpaper_color_calculator.h" |
26 #include "components/wallpaper/wallpaper_resizer.h" | 26 #include "components/wallpaper/wallpaper_resizer.h" |
27 #include "ui/display/manager/display_manager.h" | 27 #include "ui/display/manager/display_manager.h" |
28 #include "ui/display/manager/managed_display_info.h" | 28 #include "ui/display/manager/managed_display_info.h" |
29 #include "ui/display/screen.h" | 29 #include "ui/display/screen.h" |
30 #include "ui/gfx/color_analysis.h" | 30 #include "ui/gfx/color_analysis.h" |
| 31 #include "ui/gfx/image/image_skia.h" |
31 #include "ui/views/widget/widget.h" | 32 #include "ui/views/widget/widget.h" |
32 | 33 |
| 34 using color_utils::ColorProfile; |
| 35 using color_utils::LumaRange; |
| 36 using color_utils::SaturationRange; |
| 37 |
33 namespace ash { | 38 namespace ash { |
34 | 39 |
35 namespace { | 40 namespace { |
36 | 41 |
37 // How long to wait reloading the wallpaper after the display size has changed. | 42 // How long to wait reloading the wallpaper after the display size has changed. |
38 constexpr int kWallpaperReloadDelayMs = 100; | 43 constexpr int kWallpaperReloadDelayMs = 100; |
39 | 44 |
40 // How long to wait for resizing of the the wallpaper. | 45 // How long to wait for resizing of the the wallpaper. |
41 constexpr int kCompositorLockTimeoutMs = 750; | 46 constexpr int kCompositorLockTimeoutMs = 750; |
42 | 47 |
| 48 // This enum is used to get the corresponding prominent color from the |
| 49 // calculation results. |
| 50 enum ColorProfileIndex { |
| 51 COLOR_PROFILE_INDEX_DARK_VIBRANT = 0, |
| 52 COLOR_PROFILE_INDEX_NORMAL_VIBRANT, |
| 53 COLOR_PROFILE_INDEX_LIGHT_VIBRANT, |
| 54 COLOR_PROFILE_INDEX_DARK_MUTED, |
| 55 COLOR_PROFILE_INDEX_NORMAL_MUTED, |
| 56 COLOR_PROFILE_INDEX_LIGHT_MUTED, |
| 57 }; |
| 58 |
43 // Returns true if a color should be extracted from the wallpaper based on the | 59 // Returns true if a color should be extracted from the wallpaper based on the |
44 // command kAshShelfColor line arg. | 60 // command kAshShelfColor line arg. |
45 bool IsShelfColoringEnabled() { | 61 bool IsShelfColoringEnabled() { |
46 const bool kDefaultValue = true; | 62 const bool kDefaultValue = true; |
47 | 63 |
48 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( | 64 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( |
49 switches::kAshShelfColor)) { | 65 switches::kAshShelfColor)) { |
50 return kDefaultValue; | 66 return kDefaultValue; |
51 } | 67 } |
52 | 68 |
53 const std::string switch_value = | 69 const std::string switch_value = |
54 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 70 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
55 switches::kAshShelfColor); | 71 switches::kAshShelfColor); |
56 if (switch_value != switches::kAshShelfColorEnabled && | 72 if (switch_value != switches::kAshShelfColorEnabled && |
57 switch_value != switches::kAshShelfColorDisabled) { | 73 switch_value != switches::kAshShelfColorDisabled) { |
58 LOG(WARNING) << "Invalid '--" << switches::kAshShelfColor << "' value of '" | 74 LOG(WARNING) << "Invalid '--" << switches::kAshShelfColor << "' value of '" |
59 << switch_value << "'. Defaulting to " | 75 << switch_value << "'. Defaulting to " |
60 << (kDefaultValue ? "enabled." : "disabled."); | 76 << (kDefaultValue ? "enabled." : "disabled."); |
61 return kDefaultValue; | 77 return kDefaultValue; |
62 } | 78 } |
63 | 79 |
64 return switch_value == switches::kAshShelfColorEnabled; | 80 return switch_value == switches::kAshShelfColorEnabled; |
65 } | 81 } |
66 | 82 |
67 // Returns the |luma| and |saturation| output parameters based on the | 83 // Gets the color profiles for extracting wallpaper prominent colors. |
68 // kAshShelfColorScheme command line arg. | 84 std::vector<ColorProfile> GetProminentColorProfiles() { |
69 void GetProminentColorProfile(color_utils::LumaRange* luma, | 85 return {ColorProfile(LumaRange::DARK, SaturationRange::VIBRANT), |
70 color_utils::SaturationRange* saturation) { | 86 ColorProfile(LumaRange::NORMAL, SaturationRange::VIBRANT), |
71 const std::string switch_value = | 87 ColorProfile(LumaRange::LIGHT, SaturationRange::VIBRANT), |
72 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 88 ColorProfile(LumaRange::DARK, SaturationRange::MUTED), |
73 switches::kAshShelfColorScheme); | 89 ColorProfile(LumaRange::NORMAL, SaturationRange::MUTED), |
| 90 ColorProfile(LumaRange::LIGHT, SaturationRange::MUTED)}; |
| 91 } |
74 | 92 |
75 *luma = color_utils::LumaRange::DARK; | 93 // Gets the corresponding color profile index based on the given |
76 *saturation = color_utils::SaturationRange::MUTED; | 94 // |color_profile|. |
77 | 95 ColorProfileIndex GetColorProfileIndex(ColorProfile color_profile) { |
78 if (switch_value.find("light") != std::string::npos) | 96 if (color_profile.saturation == SaturationRange::VIBRANT) { |
79 *luma = color_utils::LumaRange::LIGHT; | 97 switch (color_profile.luma) { |
80 else if (switch_value.find("normal") != std::string::npos) | 98 case LumaRange::DARK: |
81 *luma = color_utils::LumaRange::NORMAL; | 99 return COLOR_PROFILE_INDEX_DARK_VIBRANT; |
82 else if (switch_value.find("dark") != std::string::npos) | 100 case LumaRange::NORMAL: |
83 *luma = color_utils::LumaRange::DARK; | 101 return COLOR_PROFILE_INDEX_NORMAL_VIBRANT; |
84 | 102 case LumaRange::LIGHT: |
85 if (switch_value.find("vibrant") != std::string::npos) | 103 return COLOR_PROFILE_INDEX_LIGHT_VIBRANT; |
86 *saturation = color_utils::SaturationRange::VIBRANT; | 104 } |
87 else if (switch_value.find("muted") != std::string::npos) | 105 } else { |
88 *saturation = color_utils::SaturationRange::MUTED; | 106 switch (color_profile.luma) { |
| 107 case LumaRange::DARK: |
| 108 return COLOR_PROFILE_INDEX_DARK_MUTED; |
| 109 case LumaRange::NORMAL: |
| 110 return COLOR_PROFILE_INDEX_NORMAL_MUTED; |
| 111 case LumaRange::LIGHT: |
| 112 return COLOR_PROFILE_INDEX_LIGHT_MUTED; |
| 113 } |
| 114 } |
| 115 NOTREACHED(); |
| 116 return COLOR_PROFILE_INDEX_DARK_MUTED; |
89 } | 117 } |
90 | 118 |
91 } // namespace | 119 } // namespace |
92 | 120 |
| 121 const SkColor WallpaperController::kInvalidColor = SK_ColorTRANSPARENT; |
| 122 |
93 WallpaperController::WallpaperController() | 123 WallpaperController::WallpaperController() |
94 : locked_(false), | 124 : locked_(false), |
95 wallpaper_mode_(WALLPAPER_NONE), | 125 wallpaper_mode_(WALLPAPER_NONE), |
96 prominent_color_(kInvalidColor), | 126 color_profiles_(GetProminentColorProfiles()), |
97 wallpaper_reload_delay_(kWallpaperReloadDelayMs), | 127 wallpaper_reload_delay_(kWallpaperReloadDelayMs), |
98 sequenced_task_runner_(base::CreateSequencedTaskRunnerWithTraits( | 128 sequenced_task_runner_(base::CreateSequencedTaskRunnerWithTraits( |
99 {base::TaskPriority::USER_VISIBLE, | 129 {base::TaskPriority::USER_VISIBLE, |
100 // Don't need to finish resize or color extraction during shutdown. | 130 // Don't need to finish resize or color extraction during shutdown. |
101 base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})), | 131 base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})), |
102 scoped_session_observer_(this) { | 132 scoped_session_observer_(this) { |
| 133 prominent_colors_ = |
| 134 std::vector<SkColor>(color_profiles_.size(), kInvalidColor); |
103 Shell::Get()->window_tree_host_manager()->AddObserver(this); | 135 Shell::Get()->window_tree_host_manager()->AddObserver(this); |
104 Shell::Get()->AddShellObserver(this); | 136 Shell::Get()->AddShellObserver(this); |
105 } | 137 } |
106 | 138 |
107 WallpaperController::~WallpaperController() { | 139 WallpaperController::~WallpaperController() { |
108 if (current_wallpaper_) | 140 if (current_wallpaper_) |
109 current_wallpaper_->RemoveObserver(this); | 141 current_wallpaper_->RemoveObserver(this); |
110 if (color_calculator_) | 142 if (color_calculator_) |
111 color_calculator_->RemoveObserver(this); | 143 color_calculator_->RemoveObserver(this); |
112 Shell::Get()->window_tree_host_manager()->RemoveObserver(this); | 144 Shell::Get()->window_tree_host_manager()->RemoveObserver(this); |
(...skipping 19 matching lines...) Expand all Loading... |
132 | 164 |
133 void WallpaperController::AddObserver(WallpaperControllerObserver* observer) { | 165 void WallpaperController::AddObserver(WallpaperControllerObserver* observer) { |
134 observers_.AddObserver(observer); | 166 observers_.AddObserver(observer); |
135 } | 167 } |
136 | 168 |
137 void WallpaperController::RemoveObserver( | 169 void WallpaperController::RemoveObserver( |
138 WallpaperControllerObserver* observer) { | 170 WallpaperControllerObserver* observer) { |
139 observers_.RemoveObserver(observer); | 171 observers_.RemoveObserver(observer); |
140 } | 172 } |
141 | 173 |
| 174 SkColor WallpaperController::GetProminentColor( |
| 175 ColorProfile color_profile) const { |
| 176 ColorProfileIndex index = GetColorProfileIndex(color_profile); |
| 177 return prominent_colors_[index]; |
| 178 } |
| 179 |
142 wallpaper::WallpaperLayout WallpaperController::GetWallpaperLayout() const { | 180 wallpaper::WallpaperLayout WallpaperController::GetWallpaperLayout() const { |
143 if (current_wallpaper_) | 181 if (current_wallpaper_) |
144 return current_wallpaper_->layout(); | 182 return current_wallpaper_->layout(); |
145 return wallpaper::WALLPAPER_LAYOUT_CENTER_CROPPED; | 183 return wallpaper::WALLPAPER_LAYOUT_CENTER_CROPPED; |
146 } | 184 } |
147 | 185 |
148 void WallpaperController::SetWallpaperImage(const gfx::ImageSkia& image, | 186 void WallpaperController::SetWallpaperImage(const gfx::ImageSkia& image, |
149 wallpaper::WallpaperLayout layout) { | 187 wallpaper::WallpaperLayout layout) { |
150 VLOG(1) << "SetWallpaper: image_id=" | 188 VLOG(1) << "SetWallpaper: image_id=" |
151 << wallpaper::WallpaperResizer::GetImageId(image) | 189 << wallpaper::WallpaperResizer::GetImageId(image) |
152 << " layout=" << layout; | 190 << " layout=" << layout; |
153 | 191 |
154 if (WallpaperIsAlreadyLoaded(image, true /* compare_layouts */, layout)) { | 192 if (WallpaperIsAlreadyLoaded(image, true /* compare_layouts */, layout)) { |
155 VLOG(1) << "Wallpaper is already loaded"; | 193 VLOG(1) << "Wallpaper is already loaded"; |
156 return; | 194 return; |
157 } | 195 } |
158 | 196 |
159 current_wallpaper_.reset(new wallpaper::WallpaperResizer( | 197 current_wallpaper_.reset(new wallpaper::WallpaperResizer( |
160 image, GetMaxDisplaySizeInNative(), layout, sequenced_task_runner_)); | 198 image, GetMaxDisplaySizeInNative(), layout, sequenced_task_runner_)); |
161 current_wallpaper_->AddObserver(this); | 199 current_wallpaper_->AddObserver(this); |
162 current_wallpaper_->StartResize(); | 200 current_wallpaper_->StartResize(); |
163 | 201 |
164 for (auto& observer : observers_) | 202 for (auto& observer : observers_) |
165 observer.OnWallpaperDataChanged(); | 203 observer.OnWallpaperDataChanged(); |
166 wallpaper_mode_ = WALLPAPER_IMAGE; | 204 wallpaper_mode_ = WALLPAPER_IMAGE; |
167 InstallDesktopControllerForAllWindows(); | 205 InstallDesktopControllerForAllWindows(); |
168 } | 206 } |
169 | 207 |
170 void WallpaperController::CreateEmptyWallpaper() { | 208 void WallpaperController::CreateEmptyWallpaper() { |
171 SetProminentColor(kInvalidColor); | 209 SetProminentColors( |
| 210 std::vector<SkColor>(color_profiles_.size(), kInvalidColor)); |
172 current_wallpaper_.reset(); | 211 current_wallpaper_.reset(); |
173 wallpaper_mode_ = WALLPAPER_IMAGE; | 212 wallpaper_mode_ = WALLPAPER_IMAGE; |
174 InstallDesktopControllerForAllWindows(); | 213 InstallDesktopControllerForAllWindows(); |
175 } | 214 } |
176 | 215 |
177 void WallpaperController::OnDisplayConfigurationChanged() { | 216 void WallpaperController::OnDisplayConfigurationChanged() { |
178 gfx::Size max_display_size = GetMaxDisplaySizeInNative(); | 217 gfx::Size max_display_size = GetMaxDisplaySizeInNative(); |
179 if (current_max_display_size_ != max_display_size) { | 218 if (current_max_display_size_ != max_display_size) { |
180 current_max_display_size_ = max_display_size; | 219 current_max_display_size_ = max_display_size; |
181 if (wallpaper_mode_ == WALLPAPER_IMAGE && current_wallpaper_) { | 220 if (wallpaper_mode_ == WALLPAPER_IMAGE && current_wallpaper_) { |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 | 316 |
278 SetWallpaperImage(gfx::ImageSkia::CreateFrom1xBitmap(wallpaper), layout); | 317 SetWallpaperImage(gfx::ImageSkia::CreateFrom1xBitmap(wallpaper), layout); |
279 } | 318 } |
280 | 319 |
281 void WallpaperController::OnWallpaperResized() { | 320 void WallpaperController::OnWallpaperResized() { |
282 CalculateWallpaperColors(); | 321 CalculateWallpaperColors(); |
283 compositor_lock_.reset(); | 322 compositor_lock_.reset(); |
284 } | 323 } |
285 | 324 |
286 void WallpaperController::OnColorCalculationComplete() { | 325 void WallpaperController::OnColorCalculationComplete() { |
287 const SkColor color = color_calculator_->prominent_color(); | 326 const std::vector<SkColor> colors = color_calculator_->prominent_colors(); |
288 color_calculator_.reset(); | 327 color_calculator_.reset(); |
289 SetProminentColor(color); | 328 SetProminentColors(colors); |
290 } | 329 } |
291 | 330 |
292 void WallpaperController::InstallDesktopController(aura::Window* root_window) { | 331 void WallpaperController::InstallDesktopController(aura::Window* root_window) { |
293 WallpaperWidgetController* component = nullptr; | 332 WallpaperWidgetController* component = nullptr; |
294 int container_id = GetWallpaperContainerId(locked_); | 333 int container_id = GetWallpaperContainerId(locked_); |
295 | 334 |
296 switch (wallpaper_mode_) { | 335 switch (wallpaper_mode_) { |
297 case WALLPAPER_IMAGE: { | 336 case WALLPAPER_IMAGE: { |
298 component = new WallpaperWidgetController( | 337 component = new WallpaperWidgetController( |
299 CreateWallpaper(root_window, container_id)); | 338 CreateWallpaper(root_window, container_id)); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 int WallpaperController::GetWallpaperContainerId(bool locked) { | 388 int WallpaperController::GetWallpaperContainerId(bool locked) { |
350 return locked ? kShellWindowId_LockScreenWallpaperContainer | 389 return locked ? kShellWindowId_LockScreenWallpaperContainer |
351 : kShellWindowId_WallpaperContainer; | 390 : kShellWindowId_WallpaperContainer; |
352 } | 391 } |
353 | 392 |
354 void WallpaperController::UpdateWallpaper(bool clear_cache) { | 393 void WallpaperController::UpdateWallpaper(bool clear_cache) { |
355 current_wallpaper_.reset(); | 394 current_wallpaper_.reset(); |
356 Shell::Get()->wallpaper_delegate()->UpdateWallpaper(clear_cache); | 395 Shell::Get()->wallpaper_delegate()->UpdateWallpaper(clear_cache); |
357 } | 396 } |
358 | 397 |
359 void WallpaperController::SetProminentColor(SkColor color) { | 398 void WallpaperController::SetProminentColors( |
360 if (prominent_color_ == color) | 399 const std::vector<SkColor>& colors) { |
| 400 if (prominent_colors_ == colors) |
361 return; | 401 return; |
362 | 402 |
363 prominent_color_ = color; | 403 prominent_colors_ = colors; |
364 for (auto& observer : observers_) | 404 for (auto& observer : observers_) |
365 observer.OnWallpaperColorsChanged(); | 405 observer.OnWallpaperColorsChanged(); |
366 } | 406 } |
367 | 407 |
368 void WallpaperController::CalculateWallpaperColors() { | 408 void WallpaperController::CalculateWallpaperColors() { |
369 if (color_calculator_) { | 409 if (color_calculator_) { |
370 color_calculator_->RemoveObserver(this); | 410 color_calculator_->RemoveObserver(this); |
371 color_calculator_.reset(); | 411 color_calculator_.reset(); |
372 } | 412 } |
373 | 413 |
374 if (!ShouldCalculateColors()) { | 414 if (!ShouldCalculateColors()) { |
375 SetProminentColor(kInvalidColor); | 415 SetProminentColors( |
| 416 std::vector<SkColor>(color_profiles_.size(), kInvalidColor)); |
376 return; | 417 return; |
377 } | 418 } |
378 | 419 |
379 color_utils::LumaRange luma; | |
380 color_utils::SaturationRange saturation; | |
381 GetProminentColorProfile(&luma, &saturation); | |
382 | |
383 color_calculator_ = base::MakeUnique<wallpaper::WallpaperColorCalculator>( | 420 color_calculator_ = base::MakeUnique<wallpaper::WallpaperColorCalculator>( |
384 GetWallpaper(), luma, saturation, sequenced_task_runner_); | 421 GetWallpaper(), color_profiles_, sequenced_task_runner_); |
385 color_calculator_->AddObserver(this); | 422 color_calculator_->AddObserver(this); |
386 if (!color_calculator_->StartCalculation()) | 423 if (!color_calculator_->StartCalculation()) { |
387 SetProminentColor(kInvalidColor); | 424 SetProminentColors( |
| 425 std::vector<SkColor>(color_profiles_.size(), kInvalidColor)); |
| 426 } |
388 } | 427 } |
389 | 428 |
390 bool WallpaperController::ShouldCalculateColors() const { | 429 bool WallpaperController::ShouldCalculateColors() const { |
| 430 if (color_profiles_.empty()) |
| 431 return false; |
| 432 |
391 gfx::ImageSkia image = GetWallpaper(); | 433 gfx::ImageSkia image = GetWallpaper(); |
392 return IsShelfColoringEnabled() && | 434 return IsShelfColoringEnabled() && |
393 Shell::Get()->session_controller()->GetSessionState() == | 435 Shell::Get()->session_controller()->GetSessionState() == |
394 session_manager::SessionState::ACTIVE && | 436 session_manager::SessionState::ACTIVE && |
395 !image.isNull(); | 437 !image.isNull(); |
396 } | 438 } |
397 | 439 |
398 bool WallpaperController::MoveToLockedContainer() { | 440 bool WallpaperController::MoveToLockedContainer() { |
399 if (locked_) | 441 if (locked_) |
400 return false; | 442 return false; |
(...skipping 21 matching lines...) Expand all Loading... |
422 base::TimeDelta::FromMilliseconds(kCompositorLockTimeoutMs)); | 464 base::TimeDelta::FromMilliseconds(kCompositorLockTimeoutMs)); |
423 } | 465 } |
424 } | 466 } |
425 } | 467 } |
426 | 468 |
427 void WallpaperController::CompositorLockTimedOut() { | 469 void WallpaperController::CompositorLockTimedOut() { |
428 compositor_lock_.reset(); | 470 compositor_lock_.reset(); |
429 } | 471 } |
430 | 472 |
431 } // namespace ash | 473 } // namespace ash |
OLD | NEW |