| // 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. |
| |
| #include "ash/wallpaper/wallpaper_controller.h" |
| |
| #include <memory> |
| #include <string> |
| #include <utility> |
| |
| #include "ash/display/window_tree_host_manager.h" |
| #include "ash/login/ui/login_constants.h" |
| #include "ash/public/cpp/ash_pref_names.h" |
| #include "ash/public/cpp/ash_switches.h" |
| #include "ash/public/cpp/config.h" |
| #include "ash/public/cpp/shell_window_ids.h" |
| #include "ash/root_window_controller.h" |
| #include "ash/session/session_controller.h" |
| #include "ash/shell.h" |
| #include "ash/wallpaper/wallpaper_controller_observer.h" |
| #include "ash/wallpaper/wallpaper_delegate.h" |
| #include "ash/wallpaper/wallpaper_view.h" |
| #include "ash/wallpaper/wallpaper_widget_controller.h" |
| #include "base/bind.h" |
| #include "base/command_line.h" |
| #include "base/logging.h" |
| #include "base/sequenced_task_runner.h" |
| #include "base/task_scheduler/post_task.h" |
| #include "base/values.h" |
| #include "components/prefs/pref_registry_simple.h" |
| #include "components/prefs/scoped_user_pref_update.h" |
| #include "components/wallpaper/wallpaper_color_calculator.h" |
| #include "components/wallpaper/wallpaper_color_profile.h" |
| #include "components/wallpaper/wallpaper_resizer.h" |
| #include "ui/display/manager/display_manager.h" |
| #include "ui/display/manager/managed_display_info.h" |
| #include "ui/display/screen.h" |
| #include "ui/gfx/color_analysis.h" |
| #include "ui/gfx/image/image_skia.h" |
| #include "ui/views/widget/widget.h" |
| |
| using color_utils::ColorProfile; |
| using color_utils::LumaRange; |
| using color_utils::SaturationRange; |
| using wallpaper::ColorProfileType; |
| |
| namespace ash { |
| |
| namespace { |
| |
| // How long to wait reloading the wallpaper after the display size has changed. |
| constexpr int kWallpaperReloadDelayMs = 100; |
| |
| // How long to wait for resizing of the the wallpaper. |
| constexpr int kCompositorLockTimeoutMs = 750; |
| |
| // Caches color calculation results in local state pref service. |
| void CacheProminentColors(const std::vector<SkColor>& colors, |
| const std::string& current_location) { |
| // Local state can be null during startup. |
| if (!Shell::Get()->GetLocalStatePrefService()) { |
| return; |
| } |
| DictionaryPrefUpdate wallpaper_colors_update( |
| Shell::Get()->GetLocalStatePrefService(), prefs::kWallpaperColors); |
| auto wallpaper_colors = std::make_unique<base::ListValue>(); |
| for (SkColor color : colors) |
| wallpaper_colors->AppendDouble(static_cast<double>(color)); |
| wallpaper_colors_update->SetWithoutPathExpansion(current_location, |
| std::move(wallpaper_colors)); |
| } |
| |
| // Gets prominent color cache from local state pref service. Returns an empty |
| // value if cache is not available. |
| base::Optional<std::vector<SkColor>> GetCachedColors( |
| const std::string& current_location) { |
| base::Optional<std::vector<SkColor>> cached_colors_out; |
| const base::ListValue* prominent_colors = nullptr; |
| // Local state can be null during startup. |
| if (!Shell::Get()->GetLocalStatePrefService() || |
| !Shell::Get() |
| ->GetLocalStatePrefService() |
| ->GetDictionary(prefs::kWallpaperColors) |
| ->GetListWithoutPathExpansion(current_location, &prominent_colors)) { |
| return cached_colors_out; |
| } |
| cached_colors_out = std::vector<SkColor>(); |
| for (base::ListValue::const_iterator iter = prominent_colors->begin(); |
| iter != prominent_colors->end(); ++iter) { |
| cached_colors_out.value().push_back( |
| static_cast<SkColor>(iter->GetDouble())); |
| } |
| return cached_colors_out; |
| } |
| |
| // Returns true if a color should be extracted from the wallpaper based on the |
| // command kAshShelfColor line arg. |
| bool IsShelfColoringEnabled() { |
| const bool kDefaultValue = true; |
| |
| if (!base::CommandLine::ForCurrentProcess()->HasSwitch( |
| switches::kAshShelfColor)) { |
| return kDefaultValue; |
| } |
| |
| const std::string switch_value = |
| base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| switches::kAshShelfColor); |
| if (switch_value != switches::kAshShelfColorEnabled && |
| switch_value != switches::kAshShelfColorDisabled) { |
| LOG(WARNING) << "Invalid '--" << switches::kAshShelfColor << "' value of '" |
| << switch_value << "'. Defaulting to " |
| << (kDefaultValue ? "enabled." : "disabled."); |
| return kDefaultValue; |
| } |
| |
| return switch_value == switches::kAshShelfColorEnabled; |
| } |
| |
| // Gets the color profiles for extracting wallpaper prominent colors. |
| std::vector<ColorProfile> GetProminentColorProfiles() { |
| return {ColorProfile(LumaRange::DARK, SaturationRange::VIBRANT), |
| ColorProfile(LumaRange::NORMAL, SaturationRange::VIBRANT), |
| ColorProfile(LumaRange::LIGHT, SaturationRange::VIBRANT), |
| ColorProfile(LumaRange::DARK, SaturationRange::MUTED), |
| ColorProfile(LumaRange::NORMAL, SaturationRange::MUTED), |
| ColorProfile(LumaRange::LIGHT, SaturationRange::MUTED)}; |
| } |
| |
| // Gets the corresponding color profile type based on the given |
| // |color_profile|. |
| ColorProfileType GetColorProfileType(ColorProfile color_profile) { |
| if (color_profile.saturation == SaturationRange::VIBRANT) { |
| switch (color_profile.luma) { |
| case LumaRange::DARK: |
| return ColorProfileType::DARK_VIBRANT; |
| case LumaRange::NORMAL: |
| return ColorProfileType::NORMAL_VIBRANT; |
| case LumaRange::LIGHT: |
| return ColorProfileType::LIGHT_VIBRANT; |
| } |
| } else { |
| switch (color_profile.luma) { |
| case LumaRange::DARK: |
| return ColorProfileType::DARK_MUTED; |
| case LumaRange::NORMAL: |
| return ColorProfileType::NORMAL_MUTED; |
| case LumaRange::LIGHT: |
| return ColorProfileType::LIGHT_MUTED; |
| } |
| } |
| NOTREACHED(); |
| return ColorProfileType::DARK_MUTED; |
| } |
| |
| } // namespace |
| |
| const SkColor WallpaperController::kInvalidColor = SK_ColorTRANSPARENT; |
| |
| WallpaperController::WallpaperController() |
| : locked_(false), |
| wallpaper_mode_(WALLPAPER_NONE), |
| color_profiles_(GetProminentColorProfiles()), |
| wallpaper_reload_delay_(kWallpaperReloadDelayMs), |
| sequenced_task_runner_(base::CreateSequencedTaskRunnerWithTraits( |
| {base::TaskPriority::USER_VISIBLE, |
| // Don't need to finish resize or color extraction during shutdown. |
| base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})), |
| scoped_session_observer_(this) { |
| prominent_colors_ = |
| std::vector<SkColor>(color_profiles_.size(), kInvalidColor); |
| Shell::Get()->window_tree_host_manager()->AddObserver(this); |
| Shell::Get()->AddShellObserver(this); |
| } |
| |
| WallpaperController::~WallpaperController() { |
| if (current_wallpaper_) |
| current_wallpaper_->RemoveObserver(this); |
| if (color_calculator_) |
| color_calculator_->RemoveObserver(this); |
| Shell::Get()->window_tree_host_manager()->RemoveObserver(this); |
| Shell::Get()->RemoveShellObserver(this); |
| } |
| |
| // static |
| void WallpaperController::RegisterLocalStatePrefs( |
| PrefRegistrySimple* registry) { |
| registry->RegisterForeignPref(prefs::kWallpaperColors); |
| } |
| |
| void WallpaperController::BindRequest( |
| mojom::WallpaperControllerRequest request) { |
| bindings_.AddBinding(this, std::move(request)); |
| } |
| |
| gfx::ImageSkia WallpaperController::GetWallpaper() const { |
| if (current_wallpaper_) |
| return current_wallpaper_->image(); |
| return gfx::ImageSkia(); |
| } |
| |
| uint32_t WallpaperController::GetWallpaperOriginalImageId() const { |
| if (current_wallpaper_) |
| return current_wallpaper_->original_image_id(); |
| return 0; |
| } |
| |
| void WallpaperController::AddObserver(WallpaperControllerObserver* observer) { |
| observers_.AddObserver(observer); |
| } |
| |
| void WallpaperController::RemoveObserver( |
| WallpaperControllerObserver* observer) { |
| observers_.RemoveObserver(observer); |
| } |
| |
| SkColor WallpaperController::GetProminentColor( |
| ColorProfile color_profile) const { |
| ColorProfileType type = GetColorProfileType(color_profile); |
| return prominent_colors_[static_cast<int>(type)]; |
| } |
| |
| wallpaper::WallpaperLayout WallpaperController::GetWallpaperLayout() const { |
| if (current_wallpaper_) |
| return current_wallpaper_->wallpaper_info().layout; |
| return wallpaper::WALLPAPER_LAYOUT_CENTER_CROPPED; |
| } |
| |
| void WallpaperController::SetWallpaperImage( |
| const gfx::ImageSkia& image, |
| const wallpaper::WallpaperInfo& info) { |
| wallpaper::WallpaperLayout layout = info.layout; |
| VLOG(1) << "SetWallpaper: image_id=" |
| << wallpaper::WallpaperResizer::GetImageId(image) |
| << " layout=" << layout; |
| |
| if (WallpaperIsAlreadyLoaded(image, true /* compare_layouts */, layout)) { |
| VLOG(1) << "Wallpaper is already loaded"; |
| return; |
| } |
| |
| current_location_ = info.location; |
| // Cancel any in-flight color calculation because we have a new wallpaper. |
| if (color_calculator_) { |
| color_calculator_->RemoveObserver(this); |
| color_calculator_.reset(); |
| } |
| current_wallpaper_.reset(new wallpaper::WallpaperResizer( |
| image, GetMaxDisplaySizeInNative(), info, sequenced_task_runner_)); |
| current_wallpaper_->AddObserver(this); |
| current_wallpaper_->StartResize(); |
| |
| for (auto& observer : observers_) |
| observer.OnWallpaperDataChanged(); |
| wallpaper_mode_ = WALLPAPER_IMAGE; |
| InstallDesktopControllerForAllWindows(); |
| } |
| |
| void WallpaperController::CreateEmptyWallpaper() { |
| SetProminentColors( |
| std::vector<SkColor>(color_profiles_.size(), kInvalidColor)); |
| current_wallpaper_.reset(); |
| wallpaper_mode_ = WALLPAPER_IMAGE; |
| InstallDesktopControllerForAllWindows(); |
| } |
| |
| void WallpaperController::OnDisplayConfigurationChanged() { |
| gfx::Size max_display_size = GetMaxDisplaySizeInNative(); |
| if (current_max_display_size_ != max_display_size) { |
| current_max_display_size_ = max_display_size; |
| if (wallpaper_mode_ == WALLPAPER_IMAGE && current_wallpaper_) { |
| timer_.Stop(); |
| GetInternalDisplayCompositorLock(); |
| timer_.Start(FROM_HERE, |
| base::TimeDelta::FromMilliseconds(wallpaper_reload_delay_), |
| base::Bind(&WallpaperController::UpdateWallpaper, |
| base::Unretained(this), false /* clear cache */)); |
| } |
| } |
| } |
| |
| void WallpaperController::OnRootWindowAdded(aura::Window* root_window) { |
| // The wallpaper hasn't been set yet. |
| if (wallpaper_mode_ == WALLPAPER_NONE) |
| return; |
| |
| // Handle resolution change for "built-in" images. |
| gfx::Size max_display_size = GetMaxDisplaySizeInNative(); |
| if (current_max_display_size_ != max_display_size) { |
| current_max_display_size_ = max_display_size; |
| if (wallpaper_mode_ == WALLPAPER_IMAGE && current_wallpaper_) |
| UpdateWallpaper(true /* clear cache */); |
| } |
| |
| InstallDesktopController(root_window); |
| } |
| |
| void WallpaperController::OnLocalStatePrefServiceInitialized( |
| PrefService* pref_service) { |
| CalculateWallpaperColors(); |
| } |
| |
| void WallpaperController::OnSessionStateChanged( |
| session_manager::SessionState state) { |
| CalculateWallpaperColors(); |
| |
| // The wallpaper may be dimmed/blurred based on session state. The color of |
| // the dimming overlay depends on the prominent color cached from a previous |
| // calculation, or a default color if cache is not available. It should never |
| // depend on any in-flight color calculation. |
| if (wallpaper_mode_ == WALLPAPER_IMAGE && |
| (state == session_manager::SessionState::ACTIVE || |
| state == session_manager::SessionState::LOCKED || |
| state == session_manager::SessionState::LOGIN_SECONDARY)) { |
| // TODO(crbug.com/753518): Reuse the existing WallpaperWidgetController for |
| // dimming/blur purpose. |
| InstallDesktopControllerForAllWindows(); |
| } |
| |
| if (state == session_manager::SessionState::ACTIVE) |
| MoveToUnlockedContainer(); |
| else |
| MoveToLockedContainer(); |
| } |
| |
| // static |
| gfx::Size WallpaperController::GetMaxDisplaySizeInNative() { |
| // Return an empty size for test environments where the screen is null. |
| if (!display::Screen::GetScreen()) |
| return gfx::Size(); |
| |
| gfx::Size max; |
| for (const auto& display : display::Screen::GetScreen()->GetAllDisplays()) { |
| // Use the native size, not ManagedDisplayInfo::size_in_pixel or |
| // Display::size. |
| // TODO(msw): Avoid using Display::size here; see http://crbug.com/613657. |
| gfx::Size size = display.size(); |
| if (Shell::HasInstance()) { |
| display::ManagedDisplayInfo info = |
| Shell::Get()->display_manager()->GetDisplayInfo(display.id()); |
| // TODO(mash): Mash returns a fake ManagedDisplayInfo. crbug.com/622480 |
| if (info.id() == display.id()) |
| size = info.bounds_in_native().size(); |
| } |
| if (display.rotation() == display::Display::ROTATE_90 || |
| display.rotation() == display::Display::ROTATE_270) { |
| size = gfx::Size(size.height(), size.width()); |
| } |
| max.SetToMax(size); |
| } |
| |
| return max; |
| } |
| |
| bool WallpaperController::WallpaperIsAlreadyLoaded( |
| const gfx::ImageSkia& image, |
| bool compare_layouts, |
| wallpaper::WallpaperLayout layout) const { |
| if (!current_wallpaper_) |
| return false; |
| |
| // Compare layouts only if necessary. |
| if (compare_layouts && layout != current_wallpaper_->wallpaper_info().layout) |
| return false; |
| |
| return wallpaper::WallpaperResizer::GetImageId(image) == |
| current_wallpaper_->original_image_id(); |
| } |
| |
| void WallpaperController::OpenSetWallpaperPage() { |
| if (wallpaper_controller_client_ && |
| Shell::Get()->wallpaper_delegate()->CanOpenSetWallpaperPage()) { |
| wallpaper_controller_client_->OpenWallpaperPicker(); |
| } |
| } |
| |
| bool WallpaperController::ShouldApplyDimming() const { |
| return Shell::Get()->session_controller()->IsUserSessionBlocked() && |
| !base::CommandLine::ForCurrentProcess()->HasSwitch( |
| switches::kAshDisableLoginDimAndBlur); |
| } |
| |
| bool WallpaperController::ShouldApplyBlur() const { |
| return Shell::Get()->session_controller()->IsUserSessionBlocked() && |
| !IsDevicePolicyWallpaper() && |
| !base::CommandLine::ForCurrentProcess()->HasSwitch( |
| switches::kAshDisableLoginDimAndBlur); |
| } |
| |
| void WallpaperController::SetClient( |
| mojom::WallpaperControllerClientPtr client) { |
| wallpaper_controller_client_ = std::move(client); |
| } |
| |
| void WallpaperController::SetCustomWallpaper( |
| mojom::WallpaperUserInfoPtr user_info, |
| const std::string& wallpaper_files_id, |
| const std::string& file_name, |
| wallpaper::WallpaperLayout layout, |
| wallpaper::WallpaperType type, |
| const SkBitmap& image, |
| bool show_wallpaper) { |
| NOTIMPLEMENTED(); |
| } |
| |
| void WallpaperController::SetOnlineWallpaper( |
| mojom::WallpaperUserInfoPtr user_info, |
| const SkBitmap& image, |
| const std::string& url, |
| wallpaper::WallpaperLayout layout, |
| bool show_wallpaper) { |
| NOTIMPLEMENTED(); |
| } |
| |
| void WallpaperController::SetDefaultWallpaper( |
| mojom::WallpaperUserInfoPtr user_info, |
| bool show_wallpaper) { |
| NOTIMPLEMENTED(); |
| } |
| |
| void WallpaperController::SetCustomizedDefaultWallpaper( |
| const GURL& wallpaper_url, |
| const base::FilePath& file_path, |
| const base::FilePath& resized_directory) { |
| NOTIMPLEMENTED(); |
| } |
| |
| void WallpaperController::ShowUserWallpaper( |
| mojom::WallpaperUserInfoPtr user_info) { |
| NOTIMPLEMENTED(); |
| } |
| |
| void WallpaperController::ShowSigninWallpaper() { |
| NOTIMPLEMENTED(); |
| } |
| |
| void WallpaperController::RemoveUserWallpaper( |
| mojom::WallpaperUserInfoPtr user_info) { |
| NOTIMPLEMENTED(); |
| } |
| |
| void WallpaperController::SetWallpaper(const SkBitmap& wallpaper, |
| const wallpaper::WallpaperInfo& info) { |
| if (wallpaper.isNull()) |
| return; |
| SetWallpaperImage(gfx::ImageSkia::CreateFrom1xBitmap(wallpaper), info); |
| } |
| |
| void WallpaperController::AddObserver( |
| mojom::WallpaperObserverAssociatedPtrInfo observer) { |
| mojom::WallpaperObserverAssociatedPtr observer_ptr; |
| observer_ptr.Bind(std::move(observer)); |
| observer_ptr->OnWallpaperColorsChanged(prominent_colors_); |
| mojo_observers_.AddPtr(std::move(observer_ptr)); |
| } |
| |
| void WallpaperController::GetWallpaperColors( |
| GetWallpaperColorsCallback callback) { |
| std::move(callback).Run(prominent_colors_); |
| } |
| |
| void WallpaperController::OnWallpaperResized() { |
| CalculateWallpaperColors(); |
| compositor_lock_.reset(); |
| } |
| |
| void WallpaperController::OnColorCalculationComplete() { |
| const std::vector<SkColor> colors = color_calculator_->prominent_colors(); |
| color_calculator_.reset(); |
| if (!current_location_.empty()) |
| CacheProminentColors(colors, current_location_); |
| SetProminentColors(colors); |
| } |
| |
| void WallpaperController::FlushForTesting() { |
| wallpaper_controller_client_.FlushForTesting(); |
| } |
| |
| void WallpaperController::InstallDesktopController(aura::Window* root_window) { |
| WallpaperWidgetController* component = nullptr; |
| int container_id = GetWallpaperContainerId(locked_); |
| |
| switch (wallpaper_mode_) { |
| case WALLPAPER_IMAGE: { |
| component = new WallpaperWidgetController( |
| CreateWallpaper(root_window, container_id)); |
| break; |
| } |
| case WALLPAPER_NONE: |
| NOTREACHED(); |
| return; |
| } |
| |
| bool is_wallpaper_blurred; |
| if (ShouldApplyBlur()) { |
| component->SetWallpaperBlur(login_constants::kBlurSigma); |
| is_wallpaper_blurred = true; |
| } else { |
| is_wallpaper_blurred = false; |
| } |
| |
| if (is_wallpaper_blurred_ != is_wallpaper_blurred) { |
| is_wallpaper_blurred_ = is_wallpaper_blurred; |
| // TODO(crbug.com/776464): Replace the observer with mojo calls so that it |
| // works under mash and it's easier to add tests. |
| for (auto& observer : observers_) |
| observer.OnWallpaperBlurChanged(); |
| } |
| |
| RootWindowController* controller = |
| RootWindowController::ForWindow(root_window); |
| controller->SetAnimatingWallpaperWidgetController( |
| new AnimatingWallpaperWidgetController(component)); |
| component->StartAnimating(controller); |
| } |
| |
| void WallpaperController::InstallDesktopControllerForAllWindows() { |
| for (aura::Window* root : Shell::GetAllRootWindows()) |
| InstallDesktopController(root); |
| current_max_display_size_ = GetMaxDisplaySizeInNative(); |
| } |
| |
| bool WallpaperController::ReparentWallpaper(int container) { |
| bool moved = false; |
| for (auto* root_window_controller : Shell::GetAllRootWindowControllers()) { |
| // In the steady state (no animation playing) the wallpaper widget |
| // controller exists in the RootWindowController. |
| WallpaperWidgetController* wallpaper_widget_controller = |
| root_window_controller->wallpaper_widget_controller(); |
| if (wallpaper_widget_controller) { |
| moved |= wallpaper_widget_controller->Reparent( |
| root_window_controller->GetRootWindow(), container); |
| } |
| // During wallpaper show animations the controller lives in |
| // AnimatingWallpaperWidgetController owned by RootWindowController. |
| // NOTE: If an image load happens during a wallpaper show animation there |
| // can temporarily be two wallpaper widgets. We must reparent both of them, |
| // one above and one here. |
| WallpaperWidgetController* animating_controller = |
| root_window_controller->animating_wallpaper_widget_controller() |
| ? root_window_controller->animating_wallpaper_widget_controller() |
| ->GetController(false) |
| : nullptr; |
| if (animating_controller) { |
| moved |= animating_controller->Reparent( |
| root_window_controller->GetRootWindow(), container); |
| } |
| } |
| return moved; |
| } |
| |
| int WallpaperController::GetWallpaperContainerId(bool locked) { |
| return locked ? kShellWindowId_LockScreenWallpaperContainer |
| : kShellWindowId_WallpaperContainer; |
| } |
| |
| void WallpaperController::UpdateWallpaper(bool clear_cache) { |
| current_wallpaper_.reset(); |
| Shell::Get()->wallpaper_delegate()->UpdateWallpaper(clear_cache); |
| } |
| |
| void WallpaperController::SetProminentColors( |
| const std::vector<SkColor>& colors) { |
| if (prominent_colors_ == colors) |
| return; |
| |
| prominent_colors_ = colors; |
| for (auto& observer : observers_) |
| observer.OnWallpaperColorsChanged(); |
| mojo_observers_.ForAllPtrs([this](mojom::WallpaperObserver* observer) { |
| observer->OnWallpaperColorsChanged(prominent_colors_); |
| }); |
| } |
| |
| void WallpaperController::CalculateWallpaperColors() { |
| if (color_calculator_) { |
| color_calculator_->RemoveObserver(this); |
| color_calculator_.reset(); |
| } |
| |
| if (!current_location_.empty()) { |
| base::Optional<std::vector<SkColor>> cached_colors = |
| GetCachedColors(current_location_); |
| if (cached_colors.has_value()) { |
| SetProminentColors(cached_colors.value()); |
| return; |
| } |
| } |
| |
| // Color calculation is only allowed during an active session for performance |
| // reasons. Observers outside an active session are notified of the cache, or |
| // an invalid color if a previous calculation during active session failed. |
| if (!ShouldCalculateColors()) { |
| SetProminentColors( |
| std::vector<SkColor>(color_profiles_.size(), kInvalidColor)); |
| return; |
| } |
| |
| color_calculator_ = std::make_unique<wallpaper::WallpaperColorCalculator>( |
| GetWallpaper(), color_profiles_, sequenced_task_runner_); |
| color_calculator_->AddObserver(this); |
| if (!color_calculator_->StartCalculation()) { |
| SetProminentColors( |
| std::vector<SkColor>(color_profiles_.size(), kInvalidColor)); |
| } |
| } |
| |
| bool WallpaperController::ShouldCalculateColors() const { |
| if (color_profiles_.empty()) |
| return false; |
| |
| gfx::ImageSkia image = GetWallpaper(); |
| return IsShelfColoringEnabled() && |
| Shell::Get()->session_controller()->GetSessionState() == |
| session_manager::SessionState::ACTIVE && |
| !image.isNull(); |
| } |
| |
| bool WallpaperController::MoveToLockedContainer() { |
| if (locked_) |
| return false; |
| |
| locked_ = true; |
| return ReparentWallpaper(GetWallpaperContainerId(true)); |
| } |
| |
| bool WallpaperController::MoveToUnlockedContainer() { |
| if (!locked_) |
| return false; |
| |
| locked_ = false; |
| return ReparentWallpaper(GetWallpaperContainerId(false)); |
| } |
| |
| bool WallpaperController::IsDevicePolicyWallpaper() const { |
| if (current_wallpaper_) |
| return current_wallpaper_->wallpaper_info().type == |
| wallpaper::WallpaperType::DEVICE; |
| return false; |
| } |
| |
| void WallpaperController::GetInternalDisplayCompositorLock() { |
| if (display::Display::HasInternalDisplay()) { |
| aura::Window* root_window = |
| Shell::GetRootWindowForDisplayId(display::Display::InternalDisplayId()); |
| if (root_window) { |
| compositor_lock_ = |
| root_window->layer()->GetCompositor()->GetCompositorLock( |
| this, |
| base::TimeDelta::FromMilliseconds(kCompositorLockTimeoutMs)); |
| } |
| } |
| } |
| |
| void WallpaperController::CompositorLockTimedOut() { |
| compositor_lock_.reset(); |
| } |
| |
| } // namespace ash |