| Index: ash/desktop_background/desktop_background_controller_unittest.cc
|
| diff --git a/ash/desktop_background/desktop_background_controller_unittest.cc b/ash/desktop_background/desktop_background_controller_unittest.cc
|
| index d513a9cac7c106e80978c7be178e9994d9375935..be85341143eead107c8f617872b8dc614aaed403 100644
|
| --- a/ash/desktop_background/desktop_background_controller_unittest.cc
|
| +++ b/ash/desktop_background/desktop_background_controller_unittest.cc
|
| @@ -4,17 +4,37 @@
|
|
|
| #include "ash/desktop_background/desktop_background_controller.h"
|
|
|
| +#include <cmath>
|
| +#include <cstdlib>
|
| +
|
| +#include "ash/ash_switches.h"
|
| +#include "ash/desktop_background/desktop_background_controller_observer.h"
|
| #include "ash/desktop_background/desktop_background_widget_controller.h"
|
| #include "ash/shell.h"
|
| #include "ash/shell_window_ids.h"
|
| #include "ash/test/ash_test_base.h"
|
| +#include "ash/test/display_manager_test_api.h"
|
| +#include "base/command_line.h"
|
| +#include "base/file_util.h"
|
| +#include "base/files/file_path.h"
|
| +#include "base/files/scoped_temp_dir.h"
|
| +#include "base/message_loop/message_loop.h"
|
| +#include "content/public/test/test_browser_thread.h"
|
| +#include "third_party/skia/include/core/SkBitmap.h"
|
| +#include "third_party/skia/include/core/SkColor.h"
|
| #include "ui/aura/root_window.h"
|
| #include "ui/compositor/scoped_animation_duration_scale_mode.h"
|
| #include "ui/compositor/test/layer_animator_test_controller.h"
|
| +#include "ui/gfx/codec/jpeg_codec.h"
|
| +#include "ui/gfx/point.h"
|
| +#include "ui/gfx/rect.h"
|
|
|
| using aura::RootWindow;
|
| using aura::Window;
|
|
|
| +namespace ash {
|
| +namespace internal {
|
| +
|
| namespace {
|
|
|
| // Containers IDs used for tests.
|
| @@ -30,6 +50,31 @@ int ChildCountForContainer(int container_id) {
|
| return static_cast<int>(container->children().size());
|
| }
|
|
|
| +class TestObserver : public DesktopBackgroundControllerObserver {
|
| + public:
|
| + explicit TestObserver(DesktopBackgroundController* controller)
|
| + : controller_(controller) {
|
| + DCHECK(controller_);
|
| + controller_->AddObserver(this);
|
| + }
|
| +
|
| + virtual ~TestObserver() {
|
| + controller_->RemoveObserver(this);
|
| + }
|
| +
|
| + void WaitForWallpaperDataChanged() {
|
| + base::MessageLoop::current()->Run();
|
| + }
|
| +
|
| + // DesktopBackgroundControllerObserver overrides:
|
| + virtual void OnWallpaperDataChanged() OVERRIDE {
|
| + base::MessageLoop::current()->Quit();
|
| + }
|
| +
|
| + private:
|
| + DesktopBackgroundController* controller_;
|
| +};
|
| +
|
| // Steps a widget's layer animation until it is completed. Animations must be
|
| // enabled.
|
| void RunAnimationForWidget(views::Widget* widget) {
|
| @@ -51,12 +96,13 @@ void RunAnimationForWidget(views::Widget* widget) {
|
|
|
| } // namespace
|
|
|
| -namespace ash {
|
| -namespace internal {
|
| -
|
| class DesktopBackgroundControllerTest : public test::AshTestBase {
|
| public:
|
| - DesktopBackgroundControllerTest() {}
|
| + DesktopBackgroundControllerTest()
|
| + : ui_thread_(content::BrowserThread::UI, base::MessageLoop::current()),
|
| + command_line_(CommandLine::NO_PROGRAM),
|
| + controller_(NULL) {
|
| + }
|
| virtual ~DesktopBackgroundControllerTest() {}
|
|
|
| virtual void SetUp() OVERRIDE {
|
| @@ -68,8 +114,152 @@ class DesktopBackgroundControllerTest : public test::AshTestBase {
|
| static_cast<DesktopBackgroundWidgetController*>(NULL));
|
| root->SetProperty(kAnimatingDesktopController,
|
| static_cast<AnimatingDesktopController*>(NULL));
|
| +
|
| + controller_ = Shell::GetInstance()->desktop_background_controller();
|
| + }
|
| +
|
| + protected:
|
| + // Colors used for different default wallpapers by
|
| + // WriteWallpapersAndSetFlags().
|
| + static const SkColor kLargeWallpaperColor = SK_ColorRED;
|
| + static const SkColor kSmallWallpaperColor = SK_ColorGREEN;
|
| + static const SkColor kLargeGuestWallpaperColor = SK_ColorBLUE;
|
| + static const SkColor kSmallGuestWallpaperColor = SK_ColorYELLOW;
|
| +
|
| + // Dimension used for width and height of default wallpaper images. A
|
| + // small value is used to minimize the amount of time spent compressing
|
| + // and writing images.
|
| + static const int kWallpaperSize = 2;
|
| +
|
| + // Runs kAnimatingDesktopController's animation to completion.
|
| + // TODO(bshe): Don't require tests to run animations; it's slow.
|
| + void RunDesktopControllerAnimation() {
|
| + RootWindow* root = Shell::GetPrimaryRootWindow();
|
| + DesktopBackgroundWidgetController* controller =
|
| + root->GetProperty(kAnimatingDesktopController)->GetController(false);
|
| + ASSERT_NO_FATAL_FAILURE(RunAnimationForWidget(controller->widget()));
|
| }
|
|
|
| + // Returns true if the color at the center of |image| is close to
|
| + // |expected_color|. (The center is used so small wallpaper images can be
|
| + // used.)
|
| + bool ImageIsNearColor(gfx::ImageSkia image, SkColor expected_color) {
|
| + if (image.size().IsEmpty()) {
|
| + LOG(ERROR) << "Image is empty";
|
| + return false;
|
| + }
|
| +
|
| + const SkBitmap* bitmap = image.bitmap();
|
| + if (!bitmap) {
|
| + LOG(ERROR) << "Unable to get bitmap from image";
|
| + return false;
|
| + }
|
| +
|
| + bitmap->lockPixels();
|
| + gfx::Point center = gfx::Rect(image.size()).CenterPoint();
|
| + SkColor image_color = bitmap->getColor(center.x(), center.y());
|
| + bitmap->unlockPixels();
|
| +
|
| + const int kDiff = 3;
|
| + if (std::abs(static_cast<int>(SkColorGetA(image_color)) -
|
| + static_cast<int>(SkColorGetA(expected_color))) > kDiff ||
|
| + std::abs(static_cast<int>(SkColorGetR(image_color)) -
|
| + static_cast<int>(SkColorGetR(expected_color))) > kDiff ||
|
| + std::abs(static_cast<int>(SkColorGetG(image_color)) -
|
| + static_cast<int>(SkColorGetG(expected_color))) > kDiff ||
|
| + std::abs(static_cast<int>(SkColorGetB(image_color)) -
|
| + static_cast<int>(SkColorGetB(expected_color))) > kDiff) {
|
| + LOG(ERROR) << "Expected color near 0x" << std::hex << expected_color
|
| + << " but got 0x" << image_color;
|
| + return false;
|
| + }
|
| +
|
| + return true;
|
| + }
|
| +
|
| + // Writes a JPEG image of the specified size and color to |path|. Returns
|
| + // true on success.
|
| + bool WriteJPEGFile(const base::FilePath& path,
|
| + int width,
|
| + int height,
|
| + SkColor color) {
|
| + SkBitmap bitmap;
|
| + bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height, 0);
|
| + bitmap.allocPixels();
|
| + bitmap.eraseColor(color);
|
| +
|
| + const int kQuality = 80;
|
| + std::vector<unsigned char> output;
|
| + if (!gfx::JPEGCodec::Encode(
|
| + static_cast<const unsigned char*>(bitmap.getPixels()),
|
| + gfx::JPEGCodec::FORMAT_SkBitmap, width, height, bitmap.rowBytes(),
|
| + kQuality, &output)) {
|
| + LOG(ERROR) << "Unable to encode " << width << "x" << height << " bitmap";
|
| + return false;
|
| + }
|
| +
|
| + size_t bytes_written = file_util::WriteFile(
|
| + path, reinterpret_cast<const char*>(&output[0]), output.size());
|
| + if (bytes_written != output.size()) {
|
| + LOG(ERROR) << "Wrote " << bytes_written << " byte(s) instead of "
|
| + << output.size() << " to " << path.value();
|
| + return false;
|
| + }
|
| +
|
| + return true;
|
| + }
|
| +
|
| + // Initializes |wallpaper_dir_|, writes JPEG wallpaper images to it, and
|
| + // passes |controller_| a command line instructing it to use the images.
|
| + // Only needs to be called (once) by tests that want to test loading of
|
| + // default wallpapers.
|
| + void WriteWallpapersAndSetFlags() {
|
| + wallpaper_dir_.reset(new base::ScopedTempDir);
|
| + ASSERT_TRUE(wallpaper_dir_->CreateUniqueTempDir());
|
| +
|
| + const base::FilePath kLargePath =
|
| + wallpaper_dir_->path().Append(FILE_PATH_LITERAL("large.jpg"));
|
| + ASSERT_TRUE(WriteJPEGFile(kLargePath, kWallpaperSize, kWallpaperSize,
|
| + kLargeWallpaperColor));
|
| + command_line_.AppendSwitchPath(
|
| + switches::kAshDefaultWallpaperLarge, kLargePath);
|
| +
|
| + const base::FilePath kSmallPath =
|
| + wallpaper_dir_->path().Append(FILE_PATH_LITERAL("small.jpg"));
|
| + ASSERT_TRUE(WriteJPEGFile(kSmallPath, kWallpaperSize, kWallpaperSize,
|
| + kSmallWallpaperColor));
|
| + command_line_.AppendSwitchPath(
|
| + switches::kAshDefaultWallpaperSmall, kSmallPath);
|
| +
|
| + const base::FilePath kLargeGuestPath =
|
| + wallpaper_dir_->path().Append(FILE_PATH_LITERAL("guest_large.jpg"));
|
| + ASSERT_TRUE(WriteJPEGFile(kLargeGuestPath, kWallpaperSize, kWallpaperSize,
|
| + kLargeGuestWallpaperColor));
|
| + command_line_.AppendSwitchPath(
|
| + switches::kAshDefaultGuestWallpaperLarge, kLargeGuestPath);
|
| +
|
| + const base::FilePath kSmallGuestPath =
|
| + wallpaper_dir_->path().Append(FILE_PATH_LITERAL("guest_small.jpg"));
|
| + ASSERT_TRUE(WriteJPEGFile(kSmallGuestPath, kWallpaperSize, kWallpaperSize,
|
| + kSmallGuestWallpaperColor));
|
| + command_line_.AppendSwitchPath(
|
| + switches::kAshDefaultGuestWallpaperSmall, kSmallGuestPath);
|
| +
|
| + controller_->set_command_line_for_testing(&command_line_);
|
| + }
|
| +
|
| + content::TestBrowserThread ui_thread_;
|
| +
|
| + // Custom command line passed to DesktopBackgroundController by
|
| + // WriteWallpapersAndSetFlags().
|
| + CommandLine command_line_;
|
| +
|
| + // Directory created by WriteWallpapersAndSetFlags() to store default
|
| + // wallpaper images.
|
| + scoped_ptr<base::ScopedTempDir> wallpaper_dir_;
|
| +
|
| + DesktopBackgroundController* controller_; // Not owned.
|
| +
|
| private:
|
| DISALLOW_COPY_AND_ASSIGN(DesktopBackgroundControllerTest);
|
| };
|
| @@ -123,10 +313,7 @@ TEST_F(DesktopBackgroundControllerTest, ControllerOwnership) {
|
| EXPECT_FALSE(root->GetProperty(kDesktopController));
|
|
|
| // Force the widget's layer animation to play to completion.
|
| - ASSERT_NO_FATAL_FAILURE(
|
| - RunAnimationForWidget(
|
| - root->GetProperty(kAnimatingDesktopController)->GetController(false)->
|
| - widget()));
|
| + RunDesktopControllerAnimation();
|
|
|
| // Ownership has moved from kAnimatingDesktopController to kDesktopController.
|
| EXPECT_FALSE(
|
| @@ -147,11 +334,7 @@ TEST_F(DesktopBackgroundControllerTest, BackgroundMovementDuringUnlock) {
|
| controller->CreateEmptyWallpaper();
|
|
|
| // Run wallpaper show animation to completion.
|
| - RootWindow* root = Shell::GetPrimaryRootWindow();
|
| - ASSERT_NO_FATAL_FAILURE(
|
| - RunAnimationForWidget(
|
| - root->GetProperty(kAnimatingDesktopController)->GetController(false)->
|
| - widget()));
|
| + RunDesktopControllerAnimation();
|
|
|
| // User locks the screen, which moves the background forward.
|
| controller->MoveDesktopToLockedContainer();
|
| @@ -162,6 +345,7 @@ TEST_F(DesktopBackgroundControllerTest, BackgroundMovementDuringUnlock) {
|
|
|
| // In this state we have two desktop background views stored in different
|
| // properties. Both are in the lock screen background container.
|
| + RootWindow* root = Shell::GetPrimaryRootWindow();
|
| EXPECT_TRUE(
|
| root->GetProperty(kAnimatingDesktopController)->GetController(false));
|
| EXPECT_TRUE(root->GetProperty(kDesktopController));
|
| @@ -177,10 +361,7 @@ TEST_F(DesktopBackgroundControllerTest, BackgroundMovementDuringUnlock) {
|
| EXPECT_EQ(0, ChildCountForContainer(kLockScreenBackgroundId));
|
|
|
| // Finish the new desktop background animation.
|
| - ASSERT_NO_FATAL_FAILURE(
|
| - RunAnimationForWidget(
|
| - root->GetProperty(kAnimatingDesktopController)->GetController(false)->
|
| - widget()));
|
| + RunDesktopControllerAnimation();
|
|
|
| // Now there is one desktop background, in the back.
|
| EXPECT_EQ(1, ChildCountForContainer(kDesktopBackgroundId));
|
| @@ -200,28 +381,25 @@ TEST_F(DesktopBackgroundControllerTest, ChangeWallpaperQuick) {
|
| controller->CreateEmptyWallpaper();
|
|
|
| // Run wallpaper show animation to completion.
|
| - RootWindow* root = Shell::GetPrimaryRootWindow();
|
| - ASSERT_NO_FATAL_FAILURE(
|
| - RunAnimationForWidget(
|
| - root->GetProperty(kAnimatingDesktopController)->GetController(false)->
|
| - widget()));
|
| + RunDesktopControllerAnimation();
|
|
|
| // Change to a new wallpaper.
|
| controller->CreateEmptyWallpaper();
|
|
|
| - DesktopBackgroundWidgetController* animatingController =
|
| + RootWindow* root = Shell::GetPrimaryRootWindow();
|
| + DesktopBackgroundWidgetController* animating_controller =
|
| root->GetProperty(kAnimatingDesktopController)->GetController(false);
|
| - EXPECT_TRUE(animatingController);
|
| + EXPECT_TRUE(animating_controller);
|
| EXPECT_TRUE(root->GetProperty(kDesktopController));
|
|
|
| // Change to another wallpaper before animation finished.
|
| controller->CreateEmptyWallpaper();
|
|
|
| // The animating controller should immediately move to desktop controller.
|
| - EXPECT_EQ(animatingController, root->GetProperty(kDesktopController));
|
| + EXPECT_EQ(animating_controller, root->GetProperty(kDesktopController));
|
|
|
| // Cache the new animating controller.
|
| - animatingController =
|
| + animating_controller =
|
| root->GetProperty(kAnimatingDesktopController)->GetController(false);
|
|
|
| // Run wallpaper show animation to completion.
|
| @@ -234,7 +412,114 @@ TEST_F(DesktopBackgroundControllerTest, ChangeWallpaperQuick) {
|
| EXPECT_FALSE(
|
| root->GetProperty(kAnimatingDesktopController)->GetController(false));
|
| // The desktop controller should be the last created animating controller.
|
| - EXPECT_EQ(animatingController, root->GetProperty(kDesktopController));
|
| + EXPECT_EQ(animating_controller, root->GetProperty(kDesktopController));
|
| +}
|
| +
|
| +TEST_F(DesktopBackgroundControllerTest, GetAppropriateResolution) {
|
| + // TODO(derat|oshima|bshe): Configuring desktops seems busted on Win8,
|
| + // even when just a single display is being used -- the small wallpaper
|
| + // is used instead of the large one. Track down the cause of the problem
|
| + // and only use a SupportsMultipleDisplays() clause for the dual-display
|
| + // code below.
|
| + if (!SupportsMultipleDisplays())
|
| + return;
|
| +
|
| + test::DisplayManagerTestApi display_manager_test_api(
|
| + Shell::GetInstance()->display_manager());
|
| +
|
| + // Small wallpaper images should be used for configurations less than or
|
| + // equal to kSmallWallpaperMaxWidth by kSmallWallpaperMaxHeight, even if
|
| + // multiple displays are connected.
|
| + display_manager_test_api.UpdateDisplay("800x600");
|
| + EXPECT_EQ(WALLPAPER_RESOLUTION_SMALL,
|
| + controller_->GetAppropriateResolution());
|
| + display_manager_test_api.UpdateDisplay("800x600,800x600");
|
| + EXPECT_EQ(WALLPAPER_RESOLUTION_SMALL,
|
| + controller_->GetAppropriateResolution());
|
| + display_manager_test_api.UpdateDisplay("1366x800");
|
| + EXPECT_EQ(WALLPAPER_RESOLUTION_SMALL,
|
| + controller_->GetAppropriateResolution());
|
| +
|
| + // At larger sizes, large wallpapers should be used.
|
| + display_manager_test_api.UpdateDisplay("1367x800");
|
| + EXPECT_EQ(WALLPAPER_RESOLUTION_LARGE,
|
| + controller_->GetAppropriateResolution());
|
| + display_manager_test_api.UpdateDisplay("1367x801");
|
| + EXPECT_EQ(WALLPAPER_RESOLUTION_LARGE,
|
| + controller_->GetAppropriateResolution());
|
| + display_manager_test_api.UpdateDisplay("2560x1700");
|
| + EXPECT_EQ(WALLPAPER_RESOLUTION_LARGE,
|
| + controller_->GetAppropriateResolution());
|
| +}
|
| +
|
| +// Test that DesktopBackgroundController loads the appropriate wallpaper
|
| +// images as specified via command-line flags in various situations.
|
| +// Splitting these into separate tests avoids needing to run animations.
|
| +// TODO(derat): Combine these into a single test -- see
|
| +// RunDesktopControllerAnimation()'s TODO.
|
| +TEST_F(DesktopBackgroundControllerTest, SmallDefaultWallpaper) {
|
| + if (!SupportsMultipleDisplays())
|
| + return;
|
| +
|
| + WriteWallpapersAndSetFlags();
|
| + TestObserver observer(controller_);
|
| +
|
| + // At 800x600, the small wallpaper should be loaded.
|
| + test::DisplayManagerTestApi display_manager_test_api(
|
| + Shell::GetInstance()->display_manager());
|
| + display_manager_test_api.UpdateDisplay("800x600");
|
| + ASSERT_TRUE(controller_->SetDefaultWallpaper(false));
|
| + observer.WaitForWallpaperDataChanged();
|
| + EXPECT_TRUE(ImageIsNearColor(controller_->GetWallpaper(),
|
| + kSmallWallpaperColor));
|
| +
|
| + // Requesting the same wallpaper again should be a no-op.
|
| + ASSERT_FALSE(controller_->SetDefaultWallpaper(false));
|
| +}
|
| +
|
| +TEST_F(DesktopBackgroundControllerTest, LargeDefaultWallpaper) {
|
| + if (!SupportsMultipleDisplays())
|
| + return;
|
| +
|
| + WriteWallpapersAndSetFlags();
|
| + TestObserver observer(controller_);
|
| + test::DisplayManagerTestApi display_manager_test_api(
|
| + Shell::GetInstance()->display_manager());
|
| + display_manager_test_api.UpdateDisplay("1600x1200");
|
| + ASSERT_TRUE(controller_->SetDefaultWallpaper(false));
|
| + observer.WaitForWallpaperDataChanged();
|
| + EXPECT_TRUE(ImageIsNearColor(controller_->GetWallpaper(),
|
| + kLargeWallpaperColor));
|
| +}
|
| +
|
| +TEST_F(DesktopBackgroundControllerTest, SmallGuestWallpaper) {
|
| + if (!SupportsMultipleDisplays())
|
| + return;
|
| +
|
| + WriteWallpapersAndSetFlags();
|
| + TestObserver observer(controller_);
|
| + test::DisplayManagerTestApi display_manager_test_api(
|
| + Shell::GetInstance()->display_manager());
|
| + display_manager_test_api.UpdateDisplay("800x600");
|
| + ASSERT_TRUE(controller_->SetDefaultWallpaper(true));
|
| + observer.WaitForWallpaperDataChanged();
|
| + EXPECT_TRUE(ImageIsNearColor(controller_->GetWallpaper(),
|
| + kSmallGuestWallpaperColor));
|
| +}
|
| +
|
| +TEST_F(DesktopBackgroundControllerTest, LargeGuestWallpaper) {
|
| + if (!SupportsMultipleDisplays())
|
| + return;
|
| +
|
| + WriteWallpapersAndSetFlags();
|
| + TestObserver observer(controller_);
|
| + test::DisplayManagerTestApi display_manager_test_api(
|
| + Shell::GetInstance()->display_manager());
|
| + display_manager_test_api.UpdateDisplay("1600x1200");
|
| + ASSERT_TRUE(controller_->SetDefaultWallpaper(true));
|
| + observer.WaitForWallpaperDataChanged();
|
| + EXPECT_TRUE(ImageIsNearColor(controller_->GetWallpaper(),
|
| + kLargeGuestWallpaperColor));
|
| }
|
|
|
| } // namespace internal
|
|
|