| 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 |