diff options
Diffstat (limited to 'chromium/ash/desktop_background/desktop_background_controller.cc')
-rw-r--r-- | chromium/ash/desktop_background/desktop_background_controller.cc | 463 |
1 files changed, 0 insertions, 463 deletions
diff --git a/chromium/ash/desktop_background/desktop_background_controller.cc b/chromium/ash/desktop_background/desktop_background_controller.cc deleted file mode 100644 index d1c67a93f0d..00000000000 --- a/chromium/ash/desktop_background/desktop_background_controller.cc +++ /dev/null @@ -1,463 +0,0 @@ -// 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/desktop_background/desktop_background_controller.h" - -#include "ash/ash_switches.h" -#include "ash/desktop_background/desktop_background_controller_observer.h" -#include "ash/desktop_background/desktop_background_view.h" -#include "ash/desktop_background/desktop_background_widget_controller.h" -#include "ash/desktop_background/user_wallpaper_delegate.h" -#include "ash/desktop_background/wallpaper_resizer.h" -#include "ash/display/display_info.h" -#include "ash/display/display_manager.h" -#include "ash/root_window_controller.h" -#include "ash/shell.h" -#include "ash/shell_factory.h" -#include "ash/shell_window_ids.h" -#include "ash/wm/root_window_layout_manager.h" -#include "base/bind.h" -#include "base/command_line.h" -#include "base/file_util.h" -#include "base/logging.h" -#include "base/synchronization/cancellation_flag.h" -#include "base/threading/worker_pool.h" -#include "content/public/browser/browser_thread.h" -#include "grit/ash_resources.h" -#include "ui/aura/root_window.h" -#include "ui/aura/window.h" -#include "ui/compositor/layer.h" -#include "ui/gfx/codec/jpeg_codec.h" -#include "ui/gfx/image/image_skia.h" -#include "ui/gfx/rect.h" -#include "ui/views/widget/widget.h" - -using ash::internal::DesktopBackgroundWidgetController; -using content::BrowserThread; - -namespace ash { -namespace { - -// How long to wait reloading the wallpaper after the max display has -// changed? -const int kWallpaperReloadDelayMs = 2000; - -} // namespace - -const int kSmallWallpaperMaxWidth = 1366; -const int kSmallWallpaperMaxHeight = 800; -const int kLargeWallpaperMaxWidth = 2560; -const int kLargeWallpaperMaxHeight = 1700; -const int kWallpaperThumbnailWidth = 108; -const int kWallpaperThumbnailHeight = 68; - -// DesktopBackgroundController::WallpaperLoader wraps background wallpaper -// loading. -class DesktopBackgroundController::WallpaperLoader - : public base::RefCountedThreadSafe< - DesktopBackgroundController::WallpaperLoader> { - public: - // If set, |file_path| must be a trusted (i.e. read-only, - // non-user-controlled) file containing a JPEG image. - WallpaperLoader(const base::FilePath& file_path, - WallpaperLayout file_layout, - int resource_id, - WallpaperLayout resource_layout) - : file_path_(file_path), - file_layout_(file_layout), - resource_id_(resource_id), - resource_layout_(resource_layout) { - } - - static void LoadOnWorkerPoolThread(scoped_refptr<WallpaperLoader> loader) { - DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI)); - loader->LoadWallpaper(); - } - - const base::FilePath& file_path() const { return file_path_; } - int resource_id() const { return resource_id_; } - - void Cancel() { - cancel_flag_.Set(); - } - - WallpaperResizer* ReleaseWallpaperResizer() { - return wallpaper_resizer_.release(); - } - - private: - friend class base::RefCountedThreadSafe< - DesktopBackgroundController::WallpaperLoader>; - - // Loads a JPEG image from |path|, a trusted file -- note that the image - // is not loaded in a sandboxed process. Returns an empty pointer on - // error. - static scoped_ptr<SkBitmap> LoadSkBitmapFromJPEGFile( - const base::FilePath& path) { - std::string data; - if (!base::ReadFileToString(path, &data)) { - LOG(ERROR) << "Unable to read data from " << path.value(); - return scoped_ptr<SkBitmap>(); - } - - scoped_ptr<SkBitmap> bitmap(gfx::JPEGCodec::Decode( - reinterpret_cast<const unsigned char*>(data.data()), data.size())); - if (!bitmap) - LOG(ERROR) << "Unable to decode JPEG data from " << path.value(); - return bitmap.Pass(); - } - - void LoadWallpaper() { - if (cancel_flag_.IsSet()) - return; - - if (!file_path_.empty()) - file_bitmap_ = LoadSkBitmapFromJPEGFile(file_path_); - - if (cancel_flag_.IsSet()) - return; - - if (file_bitmap_) { - gfx::ImageSkia image = gfx::ImageSkia::CreateFrom1xBitmap(*file_bitmap_); - wallpaper_resizer_.reset(new WallpaperResizer( - image, GetMaxDisplaySizeInNative(), file_layout_)); - } else { - wallpaper_resizer_.reset(new WallpaperResizer( - resource_id_, GetMaxDisplaySizeInNative(), resource_layout_)); - } - } - - ~WallpaperLoader() {} - - base::CancellationFlag cancel_flag_; - - // Bitmap loaded from |file_path_|. - scoped_ptr<SkBitmap> file_bitmap_; - - scoped_ptr<WallpaperResizer> wallpaper_resizer_; - - // Path to a trusted JPEG file. - base::FilePath file_path_; - - // Layout to be used when displaying the image from |file_path_|. - WallpaperLayout file_layout_; - - // ID of an image resource to use if |file_path_| is empty or unloadable. - int resource_id_; - - // Layout to be used when displaying |resource_id_|. - WallpaperLayout resource_layout_; - - DISALLOW_COPY_AND_ASSIGN(WallpaperLoader); -}; - -DesktopBackgroundController::DesktopBackgroundController() - : command_line_for_testing_(NULL), - locked_(false), - desktop_background_mode_(BACKGROUND_NONE), - current_default_wallpaper_resource_id_(-1), - weak_ptr_factory_(this), - wallpaper_reload_delay_(kWallpaperReloadDelayMs) { - Shell::GetInstance()->display_controller()->AddObserver(this); -} - -DesktopBackgroundController::~DesktopBackgroundController() { - CancelPendingWallpaperOperation(); - Shell::GetInstance()->display_controller()->RemoveObserver(this); -} - -gfx::ImageSkia DesktopBackgroundController::GetWallpaper() const { - if (current_wallpaper_) - return current_wallpaper_->image(); - return gfx::ImageSkia(); -} - -void DesktopBackgroundController::AddObserver( - DesktopBackgroundControllerObserver* observer) { - observers_.AddObserver(observer); -} - -void DesktopBackgroundController::RemoveObserver( - DesktopBackgroundControllerObserver* observer) { - observers_.RemoveObserver(observer); -} - -WallpaperLayout DesktopBackgroundController::GetWallpaperLayout() const { - if (current_wallpaper_) - return current_wallpaper_->layout(); - return WALLPAPER_LAYOUT_CENTER_CROPPED; -} - -void DesktopBackgroundController::OnRootWindowAdded(aura::Window* root_window) { - // The background hasn't been set yet. - if (desktop_background_mode_ == BACKGROUND_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 (desktop_background_mode_ == BACKGROUND_IMAGE && - current_wallpaper_.get()) - UpdateWallpaper(); - } - - InstallDesktopController(root_window); -} - -bool DesktopBackgroundController::SetDefaultWallpaper(bool is_guest) { - const bool use_large = - GetAppropriateResolution() == WALLPAPER_RESOLUTION_LARGE; - - base::FilePath file_path; - WallpaperLayout file_layout = use_large ? WALLPAPER_LAYOUT_CENTER_CROPPED : - WALLPAPER_LAYOUT_CENTER; - int resource_id = use_large ? IDR_AURA_WALLPAPER_DEFAULT_LARGE : - IDR_AURA_WALLPAPER_DEFAULT_SMALL; - WallpaperLayout resource_layout = WALLPAPER_LAYOUT_TILE; - - CommandLine* command_line = command_line_for_testing_ ? - command_line_for_testing_ : CommandLine::ForCurrentProcess(); - const char* switch_name = NULL; - if (is_guest) { - switch_name = use_large ? switches::kAshGuestWallpaperLarge : - switches::kAshGuestWallpaperSmall; - } else { - switch_name = use_large ? switches::kAshDefaultWallpaperLarge : - switches::kAshDefaultWallpaperSmall; - } - file_path = command_line->GetSwitchValuePath(switch_name); - - if (DefaultWallpaperIsAlreadyLoadingOrLoaded(file_path, resource_id)) - return false; - - CancelPendingWallpaperOperation(); - wallpaper_loader_ = new WallpaperLoader( - file_path, file_layout, resource_id, resource_layout); - base::WorkerPool::PostTaskAndReply( - FROM_HERE, - base::Bind(&WallpaperLoader::LoadOnWorkerPoolThread, wallpaper_loader_), - base::Bind(&DesktopBackgroundController::OnDefaultWallpaperLoadCompleted, - weak_ptr_factory_.GetWeakPtr(), - wallpaper_loader_), - true /* task_is_slow */); - return true; -} - -void DesktopBackgroundController::SetCustomWallpaper( - const gfx::ImageSkia& image, - WallpaperLayout layout) { - CancelPendingWallpaperOperation(); - if (CustomWallpaperIsAlreadyLoaded(image)) - return; - - current_wallpaper_.reset(new WallpaperResizer( - image, GetMaxDisplaySizeInNative(), layout)); - current_wallpaper_->StartResize(); - - current_default_wallpaper_path_ = base::FilePath(); - current_default_wallpaper_resource_id_ = -1; - - FOR_EACH_OBSERVER(DesktopBackgroundControllerObserver, observers_, - OnWallpaperDataChanged()); - SetDesktopBackgroundImageMode(); -} - -void DesktopBackgroundController::CancelPendingWallpaperOperation() { - // Set canceled flag of previous request to skip unneeded loading. - if (wallpaper_loader_.get()) - wallpaper_loader_->Cancel(); - - // Cancel reply callback for previous request. - weak_ptr_factory_.InvalidateWeakPtrs(); -} - -void DesktopBackgroundController::CreateEmptyWallpaper() { - current_wallpaper_.reset(NULL); - SetDesktopBackgroundImageMode(); -} - -WallpaperResolution DesktopBackgroundController::GetAppropriateResolution() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - gfx::Size size = GetMaxDisplaySizeInNative(); - return (size.width() > kSmallWallpaperMaxWidth || - size.height() > kSmallWallpaperMaxHeight) ? - WALLPAPER_RESOLUTION_LARGE : WALLPAPER_RESOLUTION_SMALL; -} - -bool DesktopBackgroundController::MoveDesktopToLockedContainer() { - if (locked_) - return false; - locked_ = true; - return ReparentBackgroundWidgets(GetBackgroundContainerId(false), - GetBackgroundContainerId(true)); -} - -bool DesktopBackgroundController::MoveDesktopToUnlockedContainer() { - if (!locked_) - return false; - locked_ = false; - return ReparentBackgroundWidgets(GetBackgroundContainerId(true), - GetBackgroundContainerId(false)); -} - -void DesktopBackgroundController::OnDisplayConfigurationChanged() { - gfx::Size max_display_size = GetMaxDisplaySizeInNative(); - if (current_max_display_size_ != max_display_size) { - current_max_display_size_ = max_display_size; - if (desktop_background_mode_ == BACKGROUND_IMAGE && - current_wallpaper_.get()) { - timer_.Stop(); - timer_.Start(FROM_HERE, - base::TimeDelta::FromMilliseconds(wallpaper_reload_delay_), - this, - &DesktopBackgroundController::UpdateWallpaper); - } - } -} - -bool DesktopBackgroundController::DefaultWallpaperIsAlreadyLoadingOrLoaded( - const base::FilePath& image_file, int image_resource_id) const { - return (wallpaper_loader_.get() && - wallpaper_loader_->file_path() == image_file && - wallpaper_loader_->resource_id() == image_resource_id) || - (current_wallpaper_.get() && - current_default_wallpaper_path_ == image_file && - current_default_wallpaper_resource_id_ == image_resource_id); -} - -bool DesktopBackgroundController::CustomWallpaperIsAlreadyLoaded( - const gfx::ImageSkia& image) const { - return current_wallpaper_.get() && - (WallpaperResizer::GetImageId(image) == - current_wallpaper_->original_image_id()); -} - -void DesktopBackgroundController::SetDesktopBackgroundImageMode() { - desktop_background_mode_ = BACKGROUND_IMAGE; - InstallDesktopControllerForAllWindows(); -} - -void DesktopBackgroundController::OnDefaultWallpaperLoadCompleted( - scoped_refptr<WallpaperLoader> loader) { - current_wallpaper_.reset(loader->ReleaseWallpaperResizer()); - current_wallpaper_->StartResize(); - current_default_wallpaper_path_ = loader->file_path(); - current_default_wallpaper_resource_id_ = loader->resource_id(); - FOR_EACH_OBSERVER(DesktopBackgroundControllerObserver, observers_, - OnWallpaperDataChanged()); - - SetDesktopBackgroundImageMode(); - - DCHECK(loader.get() == wallpaper_loader_.get()); - wallpaper_loader_ = NULL; -} - -void DesktopBackgroundController::InstallDesktopController( - aura::Window* root_window) { - internal::DesktopBackgroundWidgetController* component = NULL; - int container_id = GetBackgroundContainerId(locked_); - - switch (desktop_background_mode_) { - case BACKGROUND_IMAGE: { - views::Widget* widget = internal::CreateDesktopBackground(root_window, - container_id); - component = new internal::DesktopBackgroundWidgetController(widget); - break; - } - case BACKGROUND_NONE: - NOTREACHED(); - return; - } - internal::GetRootWindowController(root_window)-> - SetAnimatingWallpaperController( - new internal::AnimatingDesktopController(component)); - - component->StartAnimating(internal::GetRootWindowController(root_window)); -} - -void DesktopBackgroundController::InstallDesktopControllerForAllWindows() { - aura::Window::Windows root_windows = Shell::GetAllRootWindows(); - for (aura::Window::Windows::iterator iter = root_windows.begin(); - iter != root_windows.end(); ++iter) { - InstallDesktopController(*iter); - } - current_max_display_size_ = GetMaxDisplaySizeInNative(); -} - -bool DesktopBackgroundController::ReparentBackgroundWidgets(int src_container, - int dst_container) { - bool moved = false; - Shell::RootWindowControllerList controllers = - Shell::GetAllRootWindowControllers(); - for (Shell::RootWindowControllerList::iterator iter = controllers.begin(); - iter != controllers.end(); ++iter) { - internal::RootWindowController* root_window_controller = *iter; - // In the steady state (no animation playing) the background widget - // controller exists in the RootWindowController. - DesktopBackgroundWidgetController* desktop_controller = - root_window_controller->wallpaper_controller(); - if (desktop_controller) { - moved |= desktop_controller->Reparent( - root_window_controller->root_window(), - src_container, - dst_container); - } - // During desktop show animations the controller lives in - // AnimatingDesktopController owned by RootWindowController. - // NOTE: If a wallpaper load happens during a desktop show animation there - // can temporarily be two desktop background widgets. We must reparent - // both of them - one above and one here. - DesktopBackgroundWidgetController* animating_controller = - root_window_controller->animating_wallpaper_controller() ? - root_window_controller->animating_wallpaper_controller()-> - GetController(false) : - NULL; - if (animating_controller) { - moved |= animating_controller->Reparent( - root_window_controller->root_window(), - src_container, - dst_container); - } - } - return moved; -} - -int DesktopBackgroundController::GetBackgroundContainerId(bool locked) { - return locked ? internal::kShellWindowId_LockScreenBackgroundContainer : - internal::kShellWindowId_DesktopBackgroundContainer; -} - -void DesktopBackgroundController::UpdateWallpaper() { - current_wallpaper_.reset(NULL); - current_default_wallpaper_path_ = base::FilePath(); - current_default_wallpaper_resource_id_ = -1; - ash::Shell::GetInstance()->user_wallpaper_delegate()-> - UpdateWallpaper(); -} - -// static -gfx::Size DesktopBackgroundController::GetMaxDisplaySizeInNative() { - int width = 0; - int height = 0; - std::vector<gfx::Display> displays = Shell::GetScreen()->GetAllDisplays(); - internal::DisplayManager* display_manager = - Shell::GetInstance()->display_manager(); - - for (std::vector<gfx::Display>::iterator iter = displays.begin(); - iter != displays.end(); ++iter) { - // Don't use size_in_pixel because we want to use the native pixel size. - gfx::Size size_in_pixel = - display_manager->GetDisplayInfo(iter->id()).bounds_in_native().size(); - if (iter->rotation() == gfx::Display::ROTATE_90 || - iter->rotation() == gfx::Display::ROTATE_270) { - size_in_pixel = gfx::Size(size_in_pixel.height(), size_in_pixel.width()); - } - width = std::max(size_in_pixel.width(), width); - height = std::max(size_in_pixel.height(), height); - } - return gfx::Size(width, height); -} - -} // namespace ash |