summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbshe@chromium.org <bshe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-04 03:46:24 +0000
committerbshe@chromium.org <bshe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-04 03:46:24 +0000
commite430a7ceeb0d3b368ab3ec2b2b90b4750ec18f46 (patch)
tree9a377380681d88cf717bc90d8ac42a698377634b
parenteb5c96871668a7952c24c1266005c4d3cbdcb005 (diff)
downloadchromium_src-e430a7ceeb0d3b368ab3ec2b2b90b4750ec18f46.zip
chromium_src-e430a7ceeb0d3b368ab3ec2b2b90b4750ec18f46.tar.gz
chromium_src-e430a7ceeb0d3b368ab3ec2b2b90b4750ec18f46.tar.bz2
Resize Wallpaper to reduce memory usage
This CL resizes the decoded wallpaper to a size that perfectly fit into all connected screens. By doing this, we could reduce the memory usage of wallpaper and sometimes speedup the wallpaper OnPaint function (if resize operation finishes before OnPaint get called). BUG=174156 Review URL: https://chromiumcodereview.appspot.com/12258011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@185832 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--ash/ash.gyp3
-rw-r--r--ash/desktop_background/desktop_background_controller.cc48
-rw-r--r--ash/desktop_background/desktop_background_controller.h10
-rw-r--r--ash/desktop_background/desktop_background_controller_unittest.cc87
-rw-r--r--ash/desktop_background/wallpaper_resizer.cc154
-rw-r--r--ash/desktop_background/wallpaper_resizer.h57
-rw-r--r--ash/desktop_background/wallpaper_resizer_observer.h23
-rw-r--r--chrome/browser/chromeos/login/wallpaper_manager_browsertest.cc8
8 files changed, 356 insertions, 34 deletions
diff --git a/ash/ash.gyp b/ash/ash.gyp
index 84172ad..0b0d775 100644
--- a/ash/ash.gyp
+++ b/ash/ash.gyp
@@ -75,6 +75,9 @@
'desktop_background/desktop_background_widget_controller.cc',
'desktop_background/desktop_background_widget_controller.h',
'desktop_background/user_wallpaper_delegate.h',
+ 'desktop_background/wallpaper_resizer.cc',
+ 'desktop_background/wallpaper_resizer.h',
+ 'desktop_background/wallpaper_resizer_observer.h',
'display/display_change_observer_x11.cc',
'display/display_change_observer_x11.h',
'display/display_controller.cc',
diff --git a/ash/desktop_background/desktop_background_controller.cc b/ash/desktop_background/desktop_background_controller.cc
index 4e64345..9c89b71 100644
--- a/ash/desktop_background/desktop_background_controller.cc
+++ b/ash/desktop_background/desktop_background_controller.cc
@@ -8,6 +8,7 @@
#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/root_window_controller.h"
#include "ash/shell.h"
#include "ash/shell_factory.h"
@@ -21,7 +22,6 @@
#include "grit/ash_wallpaper_resources.h"
#include "ui/aura/root_window.h"
#include "ui/aura/window.h"
-#include "ui/base/resource/resource_bundle.h"
#include "ui/compositor/layer.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/image/image.h"
@@ -69,21 +69,6 @@ const int kLargeWallpaperMaxHeight = 1700;
const int kWallpaperThumbnailWidth = 108;
const int kWallpaperThumbnailHeight = 68;
-// Stores the current wallpaper data.
-struct DesktopBackgroundController::WallpaperData {
- explicit WallpaperData(const WallpaperInfo& info)
- : wallpaper_info(info),
- wallpaper_image(*(ui::ResourceBundle::GetSharedInstance().GetImageNamed(
- info.idr).ToImageSkia())) {
- }
- WallpaperData(const WallpaperInfo& info, const gfx::ImageSkia& image)
- : wallpaper_info(info),
- wallpaper_image(image) {
- }
- const WallpaperInfo wallpaper_info;
- const gfx::ImageSkia wallpaper_image;
-};
-
// DesktopBackgroundController::WallpaperLoader wraps background wallpaper
// loading.
class DesktopBackgroundController::WallpaperLoader
@@ -107,8 +92,8 @@ class DesktopBackgroundController::WallpaperLoader
return info_.idr;
}
- WallpaperData* ReleaseWallpaperData() {
- return wallpaper_data_.release();
+ WallpaperResizer* ReleaseWallpaperResizer() {
+ return wallpaper_resizer_.release();
}
private:
@@ -118,14 +103,14 @@ class DesktopBackgroundController::WallpaperLoader
void LoadingWallpaper() {
if (cancel_flag_.IsSet())
return;
- wallpaper_data_.reset(new WallpaperData(info_));
+ wallpaper_resizer_.reset(new WallpaperResizer(info_));
}
~WallpaperLoader() {}
base::CancellationFlag cancel_flag_;
- scoped_ptr<WallpaperData> wallpaper_data_;
+ scoped_ptr<WallpaperResizer> wallpaper_resizer_;
const WallpaperInfo info_;
@@ -145,7 +130,7 @@ DesktopBackgroundController::~DesktopBackgroundController() {
gfx::ImageSkia DesktopBackgroundController::GetWallpaper() const {
if (current_wallpaper_.get())
- return current_wallpaper_->wallpaper_image;
+ return current_wallpaper_->wallpaper_image();
return gfx::ImageSkia();
}
@@ -161,7 +146,7 @@ void DesktopBackgroundController::RemoveObserver(
WallpaperLayout DesktopBackgroundController::GetWallpaperLayout() const {
if (current_wallpaper_.get())
- return current_wallpaper_->wallpaper_info.layout;
+ return current_wallpaper_->wallpaper_info().layout;
return WALLPAPER_LAYOUT_CENTER_CROPPED;
}
@@ -175,7 +160,7 @@ int DesktopBackgroundController::GetWallpaperIDR() const {
if (wallpaper_loader_.get())
return wallpaper_loader_->idr();
else if (current_wallpaper_.get())
- return current_wallpaper_->wallpaper_info.idr;
+ return current_wallpaper_->wallpaper_info().idr;
else
return -1;
}
@@ -190,10 +175,12 @@ void DesktopBackgroundController::OnRootWindowAdded(
if (BACKGROUND_IMAGE == desktop_background_mode_ &&
current_wallpaper_.get()) {
gfx::Size root_window_size = root_window->GetHostSize();
- // Loads a higher resolution wallpaper if new root window is larger than
- // small screen.
- if (kSmallWallpaperMaxWidth < root_window_size.width() ||
- kSmallWallpaperMaxHeight < root_window_size.height()) {
+ int width = current_wallpaper_->wallpaper_image().width();
+ int height = current_wallpaper_->wallpaper_image().height();
+ // Reloads wallpaper if current wallpaper is smaller than the new added root
+ // window.
+ if (width < root_window_size.width() ||
+ height < root_window_size.height()) {
current_wallpaper_.reset(NULL);
ash::Shell::GetInstance()->user_wallpaper_delegate()->
UpdateWallpaper();
@@ -223,12 +210,13 @@ void DesktopBackgroundController::SetCustomWallpaper(
WallpaperLayout layout) {
CancelPendingWallpaperOperation();
if (current_wallpaper_.get() &&
- current_wallpaper_->wallpaper_image.BackedBySameObjectAs(wallpaper)) {
+ current_wallpaper_->wallpaper_image().BackedBySameObjectAs(wallpaper)) {
return;
}
WallpaperInfo info = { -1, layout };
- current_wallpaper_.reset(new WallpaperData(info, wallpaper));
+ current_wallpaper_.reset(new WallpaperResizer(info, wallpaper));
+ current_wallpaper_->StartResize();
FOR_EACH_OBSERVER(DesktopBackgroundControllerObserver, observers_,
OnWallpaperDataChanged());
SetDesktopBackgroundImageMode();
@@ -301,7 +289,7 @@ void DesktopBackgroundController::SetDesktopBackgroundImageMode() {
void DesktopBackgroundController::OnWallpaperLoadCompleted(
scoped_refptr<WallpaperLoader> wl) {
- current_wallpaper_.reset(wl->ReleaseWallpaperData());
+ current_wallpaper_.reset(wl->ReleaseWallpaperResizer());
FOR_EACH_OBSERVER(DesktopBackgroundControllerObserver, observers_,
OnWallpaperDataChanged());
diff --git a/ash/desktop_background/desktop_background_controller.h b/ash/desktop_background/desktop_background_controller.h
index 2820062..b877898 100644
--- a/ash/desktop_background/desktop_background_controller.h
+++ b/ash/desktop_background/desktop_background_controller.h
@@ -22,6 +22,9 @@ class RootWindow;
}
namespace ash {
+namespace internal {
+class DesktopBackgroundControllerTest;
+} // namespace internal
enum WallpaperLayout {
WALLPAPER_LAYOUT_CENTER,
@@ -62,6 +65,7 @@ ASH_EXPORT extern const int kWallpaperThumbnailWidth;
ASH_EXPORT extern const int kWallpaperThumbnailHeight;
class DesktopBackgroundControllerObserver;
+class WallpaperResizer;
// Loads selected desktop wallpaper from file system asynchronously and updates
// background layer if loaded successfully.
@@ -139,11 +143,11 @@ class ASH_EXPORT DesktopBackgroundController : public aura::WindowObserver {
virtual void OnWindowDestroying(aura::Window* window) OVERRIDE;
private:
+ friend class internal::DesktopBackgroundControllerTest;
+
// An operation to asynchronously loads wallpaper.
class WallpaperLoader;
- struct WallpaperData;
-
// Creates view for all root windows, or notifies them to repaint if they
// already exist.
void SetDesktopBackgroundImageMode();
@@ -185,7 +189,7 @@ class ASH_EXPORT DesktopBackgroundController : public aura::WindowObserver {
ObserverList<DesktopBackgroundControllerObserver> observers_;
// The current wallpaper.
- scoped_ptr<WallpaperData> current_wallpaper_;
+ scoped_ptr<WallpaperResizer> current_wallpaper_;
scoped_refptr<WallpaperLoader> wallpaper_loader_;
diff --git a/ash/desktop_background/desktop_background_controller_unittest.cc b/ash/desktop_background/desktop_background_controller_unittest.cc
index 237126e..077f495 100644
--- a/ash/desktop_background/desktop_background_controller_unittest.cc
+++ b/ash/desktop_background/desktop_background_controller_unittest.cc
@@ -5,11 +5,14 @@
#include "ash/desktop_background/desktop_background_controller.h"
#include "ash/desktop_background/desktop_background_widget_controller.h"
+#include "ash/desktop_background/wallpaper_resizer.h"
+#include "ash/desktop_background/wallpaper_resizer_observer.h"
#include "ash/shell.h"
#include "ash/shell_window_ids.h"
#include "ash/test/ash_test_base.h"
#include "ui/aura/root_window.h"
#include "ui/compositor/test/layer_animator_test_controller.h"
+#include "ui/gfx/image/image_skia_rep.h"
using aura::RootWindow;
using aura::Window;
@@ -52,7 +55,8 @@ void RunAnimationForWidget(views::Widget* widget) {
namespace ash {
namespace internal {
-class DesktopBackgroundControllerTest : public test::AshTestBase {
+class DesktopBackgroundControllerTest : public test::AshTestBase,
+ public WallpaperResizerObserver {
public:
DesktopBackgroundControllerTest() {}
virtual ~DesktopBackgroundControllerTest() {}
@@ -68,6 +72,26 @@ class DesktopBackgroundControllerTest : public test::AshTestBase {
static_cast<AnimatingDesktopController*>(NULL));
}
+ void WaitForResize() {
+ MessageLoop::current()->Run();
+ }
+
+ virtual void OnWallpaperResized() OVERRIDE {
+ MessageLoop::current()->Quit();
+ }
+
+ void AddWallpaperResizerObserver() {
+ DesktopBackgroundController* controller =
+ Shell::GetInstance()->desktop_background_controller();
+ controller->current_wallpaper_->AddObserver(this);
+ }
+
+ void RemoveWallpaperResizerObserver() {
+ DesktopBackgroundController* controller =
+ Shell::GetInstance()->desktop_background_controller();
+ controller->current_wallpaper_->RemoveObserver(this);
+ }
+
private:
DISALLOW_COPY_AND_ASSIGN(DesktopBackgroundControllerTest);
};
@@ -227,5 +251,66 @@ TEST_F(DesktopBackgroundControllerTest, ChangeWallpaperQuick) {
EXPECT_EQ(animatingController, root->GetProperty(kDesktopController));
}
+TEST_F(DesktopBackgroundControllerTest, ResizeToFitScreens) {
+ // We cannot short-circuit animations for this test.
+ ui::LayerAnimator::set_disable_animations_for_test(false);
+
+ // Keeps in sync with WallpaperLayout enum.
+ WallpaperLayout layouts[4] = {
+ WALLPAPER_LAYOUT_CENTER,
+ WALLPAPER_LAYOUT_CENTER_CROPPED,
+ WALLPAPER_LAYOUT_STRETCH,
+ WALLPAPER_LAYOUT_TILE,
+ };
+ const int length = arraysize(layouts);
+ for (int i = 0; i < length; i++) {
+ WallpaperLayout layout = layouts[i];
+ UpdateDisplay("800x600");
+ gfx::ImageSkia small_wallpaper(gfx::ImageSkiaRep(gfx::Size(10, 20),
+ ui::SCALE_FACTOR_100P));
+ DesktopBackgroundController* controller =
+ Shell::GetInstance()->desktop_background_controller();
+ controller->SetCustomWallpaper(small_wallpaper, layout);
+
+ // Run wallpaper show animation to completion.
+ RootWindow* root = Shell::GetPrimaryRootWindow();
+ RunAnimationForWidget(
+ root->GetProperty(kAnimatingDesktopController)->GetController(false)->
+ widget());
+
+ // Resize is not needed.
+ EXPECT_EQ(10, controller->GetWallpaper().width());
+ EXPECT_EQ(20, controller->GetWallpaper().height());
+
+ gfx::ImageSkia large(gfx::ImageSkiaRep(gfx::Size(1000, 1000),
+ ui::SCALE_FACTOR_100P));
+
+ controller->SetCustomWallpaper(large, layout);
+ AddWallpaperResizerObserver();
+ RunAnimationForWidget(
+ root->GetProperty(kAnimatingDesktopController)->GetController(false)->
+ widget());
+ WaitForResize();
+ RemoveWallpaperResizerObserver();
+ EXPECT_EQ(800, controller->GetWallpaper().width());
+ EXPECT_EQ(600, controller->GetWallpaper().height());
+
+ UpdateDisplay("800x600,500x700");
+ controller->SetCustomWallpaper(large, layout);
+ AddWallpaperResizerObserver();
+ Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
+ for (Shell::RootWindowList::iterator iter = root_windows.begin();
+ iter != root_windows.end(); ++iter) {
+ RunAnimationForWidget(
+ (*iter)->GetProperty(kAnimatingDesktopController)->
+ GetController(false)->widget());
+ }
+ WaitForResize();
+ RemoveWallpaperResizerObserver();
+ EXPECT_EQ(800, controller->GetWallpaper().width());
+ EXPECT_EQ(700, controller->GetWallpaper().height());
+ }
+}
+
} // namespace internal
} // namespace ash
diff --git a/ash/desktop_background/wallpaper_resizer.cc b/ash/desktop_background/wallpaper_resizer.cc
new file mode 100644
index 0000000..eb88932c
--- /dev/null
+++ b/ash/desktop_background/wallpaper_resizer.cc
@@ -0,0 +1,154 @@
+// Copyright (c) 2013 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/wallpaper_resizer.h"
+
+#include "ash/desktop_background/wallpaper_resizer_observer.h"
+#include "ash/root_window_controller.h"
+#include "ash/shell.h"
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/threading/sequenced_worker_pool.h"
+#include "base/threading/worker_pool.h"
+#include "content/public/browser/browser_thread.h"
+#include "ui/aura/root_window.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/gfx/skia_util.h"
+
+using content::BrowserThread;
+
+namespace ash {
+namespace {
+
+// Callback used to indicate that wallpaper has been resized.
+typedef base::Callback<void(const SkBitmap&)> ResizedCallback;
+
+// For our scaling ratios we need to round positive numbers.
+int RoundPositive(double x) {
+ return static_cast<int>(floor(x + 0.5));
+}
+
+// Resizes |wallpaper| to fit all screens and calls the callback.
+void ResizeToFitScreens(const SkBitmap& wallpaper,
+ WallpaperLayout layout,
+ int width,
+ int height,
+ MessageLoop* origin_loop,
+ const ResizedCallback& callback) {
+ SkBitmap resized_wallpaper = wallpaper;
+ if (wallpaper.width() > width || wallpaper.height() > height) {
+ gfx::Rect wallpaper_rect(0, 0, wallpaper.width(), wallpaper.height());
+ gfx::Size cropped_size = gfx::Size(std::min(width, wallpaper.width()),
+ std::min(height, wallpaper.height()));
+ switch (layout) {
+ case WALLPAPER_LAYOUT_CENTER:
+ wallpaper_rect.ClampToCenteredSize(cropped_size);
+ wallpaper.extractSubset(&resized_wallpaper,
+ gfx::RectToSkIRect(wallpaper_rect));
+ break;
+ case WALLPAPER_LAYOUT_TILE:
+ wallpaper_rect.set_size(cropped_size);
+ wallpaper.extractSubset(&resized_wallpaper,
+ gfx::RectToSkIRect(wallpaper_rect));
+ break;
+ case WALLPAPER_LAYOUT_STRETCH:
+ resized_wallpaper = skia::ImageOperations::Resize(
+ wallpaper, skia::ImageOperations::RESIZE_LANCZOS3,
+ width, height);
+ break;
+ case WALLPAPER_LAYOUT_CENTER_CROPPED:
+ if (wallpaper.width() > width && wallpaper.height() > height) {
+ // The dimension with the smallest ratio must be cropped, the other
+ // one is preserved. Both are set in gfx::Size cropped_size.
+ double horizontal_ratio = static_cast<double>(width) /
+ static_cast<double>(wallpaper.width());
+ double vertical_ratio = static_cast<double>(height) /
+ static_cast<double>(wallpaper.height());
+
+ if (vertical_ratio > horizontal_ratio) {
+ cropped_size = gfx::Size(
+ RoundPositive(static_cast<double>(width) / vertical_ratio),
+ wallpaper.height());
+ } else {
+ cropped_size = gfx::Size(wallpaper.width(),
+ RoundPositive(static_cast<double>(height) / horizontal_ratio));
+ }
+ gfx::Rect wallpaper_cropped_rect = wallpaper_rect;
+ wallpaper_cropped_rect.ClampToCenteredSize(cropped_size);
+ SkBitmap sub_image;
+ wallpaper.extractSubset(&sub_image,
+ gfx::RectToSkIRect(wallpaper_rect));
+ resized_wallpaper = skia::ImageOperations::Resize(
+ sub_image, skia::ImageOperations::RESIZE_LANCZOS3,
+ width, height);
+ }
+ }
+ }
+ resized_wallpaper.setImmutable();
+ origin_loop->PostTask(FROM_HERE, base::Bind(callback, resized_wallpaper));
+}
+
+} // namespace
+
+WallpaperResizer::WallpaperResizer(const WallpaperInfo& info)
+ : wallpaper_info_(info),
+ wallpaper_image_(*(ui::ResourceBundle::GetSharedInstance().
+ GetImageNamed(info.idr).ToImageSkia())),
+ weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
+}
+
+WallpaperResizer::WallpaperResizer(const WallpaperInfo& info,
+ const gfx::ImageSkia& image)
+ : wallpaper_info_(info),
+ wallpaper_image_(image),
+ weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
+}
+
+WallpaperResizer::~WallpaperResizer() {
+}
+
+void WallpaperResizer::StartResize() {
+ int width = 0;
+ int height = 0;
+ Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
+ for (Shell::RootWindowList::iterator iter = root_windows.begin();
+ iter != root_windows.end(); ++iter) {
+ gfx::Size root_window_size = (*iter)->GetHostSize();
+ if (root_window_size.width() > width)
+ width = root_window_size.width();
+ if (root_window_size.height() > height)
+ height = root_window_size.height();
+ }
+
+ if (!BrowserThread::GetBlockingPool()->PostWorkerTaskWithShutdownBehavior(
+ FROM_HERE,
+ base::Bind(&ResizeToFitScreens,
+ *wallpaper_image_.bitmap(),
+ wallpaper_info_.layout,
+ width,
+ height,
+ MessageLoop::current(),
+ base::Bind(&WallpaperResizer::OnResizeFinished,
+ weak_ptr_factory_.GetWeakPtr())),
+ base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)) {
+ LOG(WARNING) << "PostSequencedWorkerTask failed. " <<
+ "Wallpaper may not be resized.";
+ }
+}
+
+void WallpaperResizer::AddObserver(WallpaperResizerObserver* observer) {
+ observers_.AddObserver(observer);
+}
+
+void WallpaperResizer::RemoveObserver(WallpaperResizerObserver* observer) {
+ observers_.RemoveObserver(observer);
+}
+
+void WallpaperResizer::OnResizeFinished(const SkBitmap& resized_wallpaper) {
+ wallpaper_image_ = gfx::ImageSkia::CreateFrom1xBitmap(resized_wallpaper);
+ FOR_EACH_OBSERVER(WallpaperResizerObserver, observers_,
+ OnWallpaperResized());
+}
+
+} // namespace ash
diff --git a/ash/desktop_background/wallpaper_resizer.h b/ash/desktop_background/wallpaper_resizer.h
new file mode 100644
index 0000000..eb7e1d5
--- /dev/null
+++ b/ash/desktop_background/wallpaper_resizer.h
@@ -0,0 +1,57 @@
+// Copyright (c) 2013 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.
+
+#ifndef ASH_DESKTOP_BACKGROUND_DESKTOP_WALLPAPER_RESIZER_H_
+#define ASH_DESKTOP_BACKGROUND_DESKTOP_WALLPAPER_RESIZER_H_
+
+#include "ash/ash_export.h"
+#include "ash/desktop_background/desktop_background_controller.h"
+#include "base/memory/weak_ptr.h"
+#include "base/observer_list.h"
+#include "skia/ext/image_operations.h"
+#include "ui/gfx/image/image_skia.h"
+
+namespace ash {
+
+class WallpaperResizerObserver;
+
+// Stores the current wallpaper data and resize it to fit all screens if needed.
+class ASH_EXPORT WallpaperResizer {
+ public:
+ explicit WallpaperResizer(const WallpaperInfo& info);
+
+ WallpaperResizer(const WallpaperInfo& info, const gfx::ImageSkia& image);
+
+ virtual ~WallpaperResizer();
+
+ const WallpaperInfo& wallpaper_info() const { return wallpaper_info_; }
+
+ const gfx::ImageSkia& wallpaper_image() const { return wallpaper_image_; }
+
+ // Starts resize task on UI thread. It posts task to worker pool.
+ void StartResize();
+
+ // Add/Remove observers.
+ void AddObserver(WallpaperResizerObserver* observer);
+ void RemoveObserver(WallpaperResizerObserver* observer);
+
+ private:
+ // Replaces the orginal uncompressed wallpaper to |resized_wallpaper|.
+ void OnResizeFinished(const SkBitmap& resized_wallpaper);
+
+ ObserverList<WallpaperResizerObserver> observers_;
+
+ const WallpaperInfo wallpaper_info_;
+
+ gfx::ImageSkia wallpaper_image_;
+
+ base::WeakPtrFactory<WallpaperResizer> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(WallpaperResizer);
+};
+
+} // namespace ash
+
+
+#endif // ASH_DESKTOP_BACKGROUND_DESKTOP_WALLPAPER_RESIZER_H_
diff --git a/ash/desktop_background/wallpaper_resizer_observer.h b/ash/desktop_background/wallpaper_resizer_observer.h
new file mode 100644
index 0000000..5a10651
--- /dev/null
+++ b/ash/desktop_background/wallpaper_resizer_observer.h
@@ -0,0 +1,23 @@
+// Copyright (c) 2013 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.
+
+#ifndef ASH_DESKTOP_BACKGROUND_WALLPAPER_RESIZER_OBSERVER_H_
+#define ASH_DESKTOP_BACKGROUND_WALLPAPER_RESIZER_OBSERVER_H_
+
+#include "ash/ash_export.h"
+
+namespace ash {
+
+class ASH_EXPORT WallpaperResizerObserver {
+ public:
+ // Invoked when the wallpaper is resized.
+ virtual void OnWallpaperResized() = 0;
+
+ protected:
+ virtual ~WallpaperResizerObserver() {}
+};
+
+} // namespace ash
+
+#endif // ASH_DESKTOP_BACKGROUND_WALLPAPER_RESIZER_OBSERVER_H_
diff --git a/chrome/browser/chromeos/login/wallpaper_manager_browsertest.cc b/chrome/browser/chromeos/login/wallpaper_manager_browsertest.cc
index 2e5a9a2..b2ab709 100644
--- a/chrome/browser/chromeos/login/wallpaper_manager_browsertest.cc
+++ b/chrome/browser/chromeos/login/wallpaper_manager_browsertest.cc
@@ -150,6 +150,10 @@ IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTest,
// Hook up another 800x600 display.
UpdateDisplay("800x600,800x600");
+#if !defined(GOOGLE_CHROME_BUILD)
+ // wallpaper.width() < 800, expect to reload wallpaper.
+ WaitAsyncWallpaperLoad();
+#endif
// The small resolution wallpaper is expected.
EXPECT_EQ(kExpectedSmallWallpaperWidth, wallpaper.width());
EXPECT_EQ(kExpectedSmallWallpaperHeight, wallpaper.height());
@@ -227,6 +231,10 @@ IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTest,
// Hook up another 800x600 display.
UpdateDisplay("800x600,800x600");
+#if !defined(GOOGLE_CHROME_BUILD)
+ // wallpaper.width() < 800, expect to reload wallpaper.
+ WaitAsyncWallpaperLoad();
+#endif
// The small resolution custom wallpaper is expected.
EXPECT_EQ(kExpectedSmallWallpaperWidth, wallpaper.width());
EXPECT_EQ(kExpectedSmallWallpaperHeight, wallpaper.height());