Chromium Code Reviews| Index: ash/desktop_background/desktop_background_controller.cc |
| diff --git a/ash/desktop_background/desktop_background_controller.cc b/ash/desktop_background/desktop_background_controller.cc |
| index f6b56fd07a8cbb414f65d1662a2830edefa74d7c..bda2fe9b83a3c1df11932e9e575330a8fe1336ac 100644 |
| --- a/ash/desktop_background/desktop_background_controller.cc |
| +++ b/ash/desktop_background/desktop_background_controller.cc |
| @@ -9,7 +9,10 @@ |
| #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/logging.h" |
| +#include "base/synchronization/cancellation_flag.h" |
| +#include "base/threading/worker_pool.h" |
| #include "grit/ui_resources.h" |
| #include "ui/aura/window.h" |
| #include "ui/gfx/compositor/layer.h" |
| @@ -19,22 +22,99 @@ |
| namespace ash { |
| -DesktopBackgroundController::DesktopBackgroundController() : |
| - desktop_background_mode_(BACKGROUND_IMAGE) { |
| +// DesktopBackgroundController::WallpaperOperation wraps background wallpaper |
| +// loading. |
| +class DesktopBackgroundController::WallpaperOperation |
| + : public base::RefCountedThreadSafe< |
| + DesktopBackgroundController::WallpaperOperation> { |
| + public: |
| + WallpaperOperation(int index) |
| + : wallpaper_(NULL), |
| + layout_(CENTER_CROPPED), |
| + index_(index) { |
| + } |
| + |
| + static void Run(scoped_refptr<WallpaperOperation> wo) { |
| + wo->LoadingWallpaper(); |
| + } |
| + |
| + void LoadingWallpaper() { |
|
Ben Goodger (Google)
2012/05/01 19:40:12
I think you need to lock when you read/write to da
bshe
2012/05/01 20:52:02
I thought the cancel_flag_ is already thread safe
Nikita (slow)
2012/05/02 09:22:23
I've also checked that CancellationFlag is thread-
|
| + if (cancel_flag_.IsSet()) |
| + return; |
| + wallpaper_ = ui::ResourceBundle::GetSharedInstance().GetImageNamed( |
| + GetWallpaperInfo(index_).id).ToSkBitmap(); |
| + if (cancel_flag_.IsSet()) |
| + return; |
| + layout_ = GetWallpaperInfo(index_).layout; |
| + } |
| + |
| + void Cancel() { |
| + cancel_flag_.Set(); |
| + } |
| + |
| + const SkBitmap* wallpaper() { |
| + return wallpaper_; |
| + } |
| + |
| + ImageLayout image_layout() { |
| + return layout_; |
| + } |
| + |
| + int index() { |
| + return index_; |
| + } |
| + |
| + private: |
| + friend class base::RefCountedThreadSafe< |
| + DesktopBackgroundController::WallpaperOperation>; |
| + |
| + base::CancellationFlag cancel_flag_; |
| + |
| + const SkBitmap* wallpaper_; |
| + ImageLayout layout_; |
| + int index_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(WallpaperOperation); |
| +}; |
| + |
| +DesktopBackgroundController::DesktopBackgroundController() |
| + : desktop_background_mode_(BACKGROUND_IMAGE), |
| + previous_index_(-1), |
| + weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
| } |
| DesktopBackgroundController::~DesktopBackgroundController() { |
| } |
| -void DesktopBackgroundController::SetDesktopBackgroundImageMode() { |
| - internal::RootWindowLayoutManager* root_window_layout = |
| - Shell::GetInstance()->root_window_layout(); |
| +void DesktopBackgroundController::SetDefaultWallpaper(int index) { |
| + if (previous_index_ == index) |
| + return; |
| + |
| + CancelPendingWallpaperOperation(); |
| + |
| + wallpaper_op_ = new WallpaperOperation(index); |
| + base::WorkerPool::PostTaskAndReply( |
| + FROM_HERE, |
| + base::Bind(&WallpaperOperation::Run, wallpaper_op_), |
| + base::Bind(&DesktopBackgroundController::OnWallpaperLoadCompleted, |
| + weak_ptr_factory_.GetWeakPtr(), |
| + wallpaper_op_), |
| + true /* task_is_slow */); |
| +} |
| + |
| +void DesktopBackgroundController::CancelPendingWallpaperOperation() { |
| + // Set canceled flag of previous request to skip unneeded loading. |
| + if (wallpaper_op_.get()) |
| + wallpaper_op_->Cancel(); |
| + |
| + // Cancel reply callback for previous request. |
| + weak_ptr_factory_.InvalidateWeakPtrs(); |
| +} |
| + |
| +void DesktopBackgroundController::SetLoggedInUserWallpaper() { |
| int index = Shell::GetInstance()->user_wallpaper_delegate()-> |
| GetUserWallpaperIndex(); |
| - root_window_layout->SetBackgroundLayer(NULL); |
| - internal::CreateDesktopBackground(GetWallpaper(index), |
| - GetWallpaperInfo(index).layout); |
| - desktop_background_mode_ = BACKGROUND_IMAGE; |
| + SetDefaultWallpaper(index); |
| } |
| void DesktopBackgroundController::SetDesktopBackgroundSolidColorMode() { |
| @@ -52,4 +132,24 @@ void DesktopBackgroundController::SetDesktopBackgroundSolidColorMode() { |
| desktop_background_mode_ = BACKGROUND_SOLID_COLOR; |
| } |
| +void DesktopBackgroundController::SetDesktopBackgroundImageMode( |
| + scoped_refptr<WallpaperOperation> wo) { |
| + internal::RootWindowLayoutManager* root_window_layout = |
| + Shell::GetInstance()->root_window_layout(); |
| + root_window_layout->SetBackgroundLayer(NULL); |
| + if(wo->wallpaper()) { |
| + internal::CreateDesktopBackground(*wo->wallpaper(), wo->image_layout()); |
| + desktop_background_mode_ = BACKGROUND_IMAGE; |
| + } |
| +} |
| + |
| +void DesktopBackgroundController::OnWallpaperLoadCompleted( |
| + scoped_refptr<WallpaperOperation> wo) { |
| + SetDesktopBackgroundImageMode(wo); |
| + previous_index_ = wo->index(); |
| + |
| + DCHECK(wo.get() == wallpaper_op_.get()); |
| + wallpaper_op_ = NULL; |
| +} |
| + |
| } // namespace ash |