Home | History | Annotate | Download | only in desktop_background
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "ash/desktop_background/desktop_background_controller.h"
      6 
      7 #include <cmath>
      8 #include <cstdlib>
      9 
     10 #include "ash/ash_switches.h"
     11 #include "ash/desktop_background/desktop_background_controller_observer.h"
     12 #include "ash/desktop_background/desktop_background_widget_controller.h"
     13 #include "ash/root_window_controller.h"
     14 #include "ash/shell.h"
     15 #include "ash/shell_window_ids.h"
     16 #include "ash/test/ash_test_base.h"
     17 #include "ash/test/display_manager_test_api.h"
     18 #include "ash/test/test_user_wallpaper_delegate.h"
     19 #include "base/command_line.h"
     20 #include "base/file_util.h"
     21 #include "base/files/file_path.h"
     22 #include "base/files/scoped_temp_dir.h"
     23 #include "base/message_loop/message_loop.h"
     24 #include "base/threading/sequenced_worker_pool.h"
     25 #include "content/public/browser/browser_thread.h"
     26 #include "content/public/test/test_browser_thread.h"
     27 #include "content/public/test/test_utils.h"
     28 #include "third_party/skia/include/core/SkBitmap.h"
     29 #include "third_party/skia/include/core/SkColor.h"
     30 #include "ui/aura/root_window.h"
     31 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
     32 #include "ui/compositor/test/layer_animator_test_controller.h"
     33 #include "ui/gfx/codec/jpeg_codec.h"
     34 #include "ui/gfx/point.h"
     35 #include "ui/gfx/rect.h"
     36 
     37 using aura::RootWindow;
     38 using aura::Window;
     39 
     40 namespace ash {
     41 namespace {
     42 
     43 // Containers IDs used for tests.
     44 const int kDesktopBackgroundId =
     45     ash::internal::kShellWindowId_DesktopBackgroundContainer;
     46 const int kLockScreenBackgroundId =
     47     ash::internal::kShellWindowId_LockScreenBackgroundContainer;
     48 
     49 // Returns number of child windows in a shell window container.
     50 int ChildCountForContainer(int container_id) {
     51   Window* root = ash::Shell::GetPrimaryRootWindow();
     52   Window* container = root->GetChildById(container_id);
     53   return static_cast<int>(container->children().size());
     54 }
     55 
     56 class TestObserver : public DesktopBackgroundControllerObserver {
     57  public:
     58   explicit TestObserver(DesktopBackgroundController* controller)
     59       : controller_(controller) {
     60     DCHECK(controller_);
     61     controller_->AddObserver(this);
     62   }
     63 
     64   virtual ~TestObserver() {
     65     controller_->RemoveObserver(this);
     66   }
     67 
     68   void WaitForWallpaperDataChanged() {
     69     base::MessageLoop::current()->Run();
     70   }
     71 
     72   // DesktopBackgroundControllerObserver overrides:
     73   virtual void OnWallpaperDataChanged() OVERRIDE {
     74     base::MessageLoop::current()->Quit();
     75   }
     76 
     77  private:
     78   DesktopBackgroundController* controller_;
     79 };
     80 
     81 // Steps a widget's layer animation until it is completed. Animations must be
     82 // enabled.
     83 void RunAnimationForWidget(views::Widget* widget) {
     84   // Animations must be enabled for stepping to work.
     85   ASSERT_NE(ui::ScopedAnimationDurationScaleMode::duration_scale_mode(),
     86             ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
     87 
     88   ui::Layer* layer = widget->GetNativeView()->layer();
     89   ui::LayerAnimatorTestController controller(layer->GetAnimator());
     90   gfx::AnimationContainerElement* element = layer->GetAnimator();
     91   // Multiple steps are required to complete complex animations.
     92   // TODO(vollick): This should not be necessary. crbug.com/154017
     93   while (controller.animator()->is_animating()) {
     94     controller.StartThreadedAnimationsIfNeeded();
     95     base::TimeTicks step_time = controller.animator()->last_step_time();
     96     element->Step(step_time + base::TimeDelta::FromMilliseconds(1000));
     97   }
     98 }
     99 
    100 }  // namespace
    101 
    102 class DesktopBackgroundControllerTest : public test::AshTestBase {
    103  public:
    104   DesktopBackgroundControllerTest()
    105       : command_line_(CommandLine::NO_PROGRAM),
    106         controller_(NULL) {
    107   }
    108   virtual ~DesktopBackgroundControllerTest() {}
    109 
    110   virtual void SetUp() OVERRIDE {
    111     test::AshTestBase::SetUp();
    112     // Ash shell initialization creates wallpaper. Reset it so we can manually
    113     // control wallpaper creation and animation in our tests.
    114     internal::RootWindowController* root_window_controller =
    115         Shell::GetPrimaryRootWindowController();
    116     root_window_controller->SetWallpaperController(NULL);
    117     root_window_controller->SetAnimatingWallpaperController(NULL);
    118     controller_ = Shell::GetInstance()->desktop_background_controller();
    119     wallpaper_delegate_ = static_cast<test::TestUserWallpaperDelegate*>(
    120         Shell::GetInstance()->user_wallpaper_delegate());
    121     controller_->set_wallpaper_reload_delay_for_test(0);
    122   }
    123 
    124  protected:
    125   // Colors used for different default wallpapers by
    126   // WriteWallpapersAndSetFlags().
    127   static const SkColor kLargeWallpaperColor = SK_ColorRED;
    128   static const SkColor kSmallWallpaperColor = SK_ColorGREEN;
    129   static const SkColor kLargeGuestWallpaperColor = SK_ColorBLUE;
    130   static const SkColor kSmallGuestWallpaperColor = SK_ColorYELLOW;
    131 
    132   // Dimension used for width and height of default wallpaper images. A
    133   // small value is used to minimize the amount of time spent compressing
    134   // and writing images.
    135   static const int kWallpaperSize = 2;
    136 
    137   // Creates an image of size |size|.
    138   gfx::ImageSkia CreateImage(int width, int height) {
    139     SkBitmap bitmap;
    140     bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
    141     bitmap.allocPixels();
    142     gfx::ImageSkia image = gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
    143     return image;
    144   }
    145 
    146   // Runs kAnimatingDesktopController's animation to completion.
    147   // TODO(bshe): Don't require tests to run animations; it's slow.
    148   void RunDesktopControllerAnimation() {
    149     internal::DesktopBackgroundWidgetController* controller =
    150         Shell::GetPrimaryRootWindowController()->
    151         animating_wallpaper_controller()->GetController(false);
    152     ASSERT_NO_FATAL_FAILURE(RunAnimationForWidget(controller->widget()));
    153   }
    154 
    155   // Returns true if the color at the center of |image| is close to
    156   // |expected_color|. (The center is used so small wallpaper images can be
    157   // used.)
    158   bool ImageIsNearColor(gfx::ImageSkia image, SkColor expected_color) {
    159     if (image.size().IsEmpty()) {
    160       LOG(ERROR) << "Image is empty";
    161       return false;
    162     }
    163 
    164     const SkBitmap* bitmap = image.bitmap();
    165     if (!bitmap) {
    166       LOG(ERROR) << "Unable to get bitmap from image";
    167       return false;
    168     }
    169 
    170     bitmap->lockPixels();
    171     gfx::Point center = gfx::Rect(image.size()).CenterPoint();
    172     SkColor image_color = bitmap->getColor(center.x(), center.y());
    173     bitmap->unlockPixels();
    174 
    175     const int kDiff = 3;
    176     if (std::abs(static_cast<int>(SkColorGetA(image_color)) -
    177                  static_cast<int>(SkColorGetA(expected_color))) > kDiff ||
    178         std::abs(static_cast<int>(SkColorGetR(image_color)) -
    179                  static_cast<int>(SkColorGetR(expected_color))) > kDiff ||
    180         std::abs(static_cast<int>(SkColorGetG(image_color)) -
    181                  static_cast<int>(SkColorGetG(expected_color))) > kDiff ||
    182         std::abs(static_cast<int>(SkColorGetB(image_color)) -
    183                  static_cast<int>(SkColorGetB(expected_color))) > kDiff) {
    184       LOG(ERROR) << "Expected color near 0x" << std::hex << expected_color
    185                  << " but got 0x" << image_color;
    186       return false;
    187     }
    188 
    189     return true;
    190   }
    191 
    192   // Writes a JPEG image of the specified size and color to |path|. Returns
    193   // true on success.
    194   bool WriteJPEGFile(const base::FilePath& path,
    195                      int width,
    196                      int height,
    197                      SkColor color) {
    198     SkBitmap bitmap;
    199     bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height, 0);
    200     bitmap.allocPixels();
    201     bitmap.eraseColor(color);
    202 
    203     const int kQuality = 80;
    204     std::vector<unsigned char> output;
    205     if (!gfx::JPEGCodec::Encode(
    206             static_cast<const unsigned char*>(bitmap.getPixels()),
    207             gfx::JPEGCodec::FORMAT_SkBitmap, width, height, bitmap.rowBytes(),
    208             kQuality, &output)) {
    209       LOG(ERROR) << "Unable to encode " << width << "x" << height << " bitmap";
    210       return false;
    211     }
    212 
    213     size_t bytes_written = file_util::WriteFile(
    214         path, reinterpret_cast<const char*>(&output[0]), output.size());
    215     if (bytes_written != output.size()) {
    216       LOG(ERROR) << "Wrote " << bytes_written << " byte(s) instead of "
    217                  << output.size() << " to " << path.value();
    218       return false;
    219     }
    220 
    221     return true;
    222   }
    223 
    224   // Initializes |wallpaper_dir_|, writes JPEG wallpaper images to it, and
    225   // passes |controller_| a command line instructing it to use the images.
    226   // Only needs to be called (once) by tests that want to test loading of
    227   // default wallpapers.
    228   void WriteWallpapersAndSetFlags() {
    229     wallpaper_dir_.reset(new base::ScopedTempDir);
    230     ASSERT_TRUE(wallpaper_dir_->CreateUniqueTempDir());
    231 
    232     const base::FilePath kLargePath =
    233         wallpaper_dir_->path().Append(FILE_PATH_LITERAL("large.jpg"));
    234     ASSERT_TRUE(WriteJPEGFile(kLargePath, kWallpaperSize, kWallpaperSize,
    235                               kLargeWallpaperColor));
    236     command_line_.AppendSwitchPath(
    237         switches::kAshDefaultWallpaperLarge, kLargePath);
    238 
    239     const base::FilePath kSmallPath =
    240         wallpaper_dir_->path().Append(FILE_PATH_LITERAL("small.jpg"));
    241     ASSERT_TRUE(WriteJPEGFile(kSmallPath, kWallpaperSize, kWallpaperSize,
    242                               kSmallWallpaperColor));
    243     command_line_.AppendSwitchPath(
    244         switches::kAshDefaultWallpaperSmall, kSmallPath);
    245 
    246     const base::FilePath kLargeGuestPath =
    247         wallpaper_dir_->path().Append(FILE_PATH_LITERAL("guest_large.jpg"));
    248     ASSERT_TRUE(WriteJPEGFile(kLargeGuestPath, kWallpaperSize, kWallpaperSize,
    249                               kLargeGuestWallpaperColor));
    250     command_line_.AppendSwitchPath(
    251         switches::kAshGuestWallpaperLarge, kLargeGuestPath);
    252 
    253     const base::FilePath kSmallGuestPath =
    254         wallpaper_dir_->path().Append(FILE_PATH_LITERAL("guest_small.jpg"));
    255     ASSERT_TRUE(WriteJPEGFile(kSmallGuestPath, kWallpaperSize, kWallpaperSize,
    256                               kSmallGuestWallpaperColor));
    257     command_line_.AppendSwitchPath(
    258         switches::kAshGuestWallpaperSmall, kSmallGuestPath);
    259 
    260     controller_->set_command_line_for_testing(&command_line_);
    261   }
    262 
    263   // Custom command line passed to DesktopBackgroundController by
    264   // WriteWallpapersAndSetFlags().
    265   CommandLine command_line_;
    266 
    267   // Directory created by WriteWallpapersAndSetFlags() to store default
    268   // wallpaper images.
    269   scoped_ptr<base::ScopedTempDir> wallpaper_dir_;
    270 
    271   DesktopBackgroundController* controller_;  // Not owned.
    272 
    273   test::TestUserWallpaperDelegate* wallpaper_delegate_;
    274 
    275  private:
    276   DISALLOW_COPY_AND_ASSIGN(DesktopBackgroundControllerTest);
    277 };
    278 
    279 TEST_F(DesktopBackgroundControllerTest, BasicReparenting) {
    280   DesktopBackgroundController* controller =
    281       Shell::GetInstance()->desktop_background_controller();
    282   controller->CreateEmptyWallpaper();
    283 
    284   // Wallpaper view/window exists in the desktop background container and
    285   // nothing is in the lock screen background container.
    286   EXPECT_EQ(1, ChildCountForContainer(kDesktopBackgroundId));
    287   EXPECT_EQ(0, ChildCountForContainer(kLockScreenBackgroundId));
    288 
    289   // Moving background to lock container should succeed the first time but
    290   // subsequent calls should do nothing.
    291   EXPECT_TRUE(controller->MoveDesktopToLockedContainer());
    292   EXPECT_FALSE(controller->MoveDesktopToLockedContainer());
    293 
    294   // One window is moved from desktop to lock container.
    295   EXPECT_EQ(0, ChildCountForContainer(kDesktopBackgroundId));
    296   EXPECT_EQ(1, ChildCountForContainer(kLockScreenBackgroundId));
    297 
    298   // Moving background to desktop container should succeed the first time.
    299   EXPECT_TRUE(controller->MoveDesktopToUnlockedContainer());
    300   EXPECT_FALSE(controller->MoveDesktopToUnlockedContainer());
    301 
    302   // One window is moved from lock to desktop container.
    303   EXPECT_EQ(1, ChildCountForContainer(kDesktopBackgroundId));
    304   EXPECT_EQ(0, ChildCountForContainer(kLockScreenBackgroundId));
    305 }
    306 
    307 TEST_F(DesktopBackgroundControllerTest, ControllerOwnership) {
    308   // We cannot short-circuit animations for this test.
    309   ui::ScopedAnimationDurationScaleMode normal_duration_mode(
    310       ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
    311 
    312   // Create wallpaper and background view.
    313   DesktopBackgroundController* controller =
    314       Shell::GetInstance()->desktop_background_controller();
    315   controller->CreateEmptyWallpaper();
    316 
    317   // The new wallpaper is ready to start animating. kAnimatingDesktopController
    318   // holds the widget controller instance. kDesktopController will get it later.
    319   internal::RootWindowController* root_window_controller =
    320       Shell::GetPrimaryRootWindowController();
    321   EXPECT_TRUE(root_window_controller->animating_wallpaper_controller()->
    322               GetController(false));
    323 
    324   // kDesktopController will receive the widget controller when the animation
    325   // is done.
    326   EXPECT_FALSE(root_window_controller->wallpaper_controller());
    327 
    328   // Force the widget's layer animation to play to completion.
    329   RunDesktopControllerAnimation();
    330 
    331   // Ownership has moved from kAnimatingDesktopController to kDesktopController.
    332   EXPECT_FALSE(root_window_controller->animating_wallpaper_controller()->
    333                GetController(false));
    334   EXPECT_TRUE(root_window_controller->wallpaper_controller());
    335 }
    336 
    337 // Test for crbug.com/149043 "Unlock screen, no launcher appears". Ensure we
    338 // move all desktop views if there are more than one.
    339 TEST_F(DesktopBackgroundControllerTest, BackgroundMovementDuringUnlock) {
    340   // We cannot short-circuit animations for this test.
    341   ui::ScopedAnimationDurationScaleMode normal_duration_mode(
    342       ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
    343 
    344   // Reset wallpaper state, see ControllerOwnership above.
    345   DesktopBackgroundController* controller =
    346       Shell::GetInstance()->desktop_background_controller();
    347   controller->CreateEmptyWallpaper();
    348 
    349   // Run wallpaper show animation to completion.
    350   RunDesktopControllerAnimation();
    351 
    352   // User locks the screen, which moves the background forward.
    353   controller->MoveDesktopToLockedContainer();
    354 
    355   // Suspend/resume cycle causes wallpaper to refresh, loading a new desktop
    356   // background that will animate in on top of the old one.
    357   controller->CreateEmptyWallpaper();
    358 
    359   // In this state we have two desktop background views stored in different
    360   // properties. Both are in the lock screen background container.
    361   internal::RootWindowController* root_window_controller =
    362       Shell::GetPrimaryRootWindowController();
    363   EXPECT_TRUE(root_window_controller->animating_wallpaper_controller()->
    364               GetController(false));
    365   EXPECT_TRUE(root_window_controller->wallpaper_controller());
    366   EXPECT_EQ(0, ChildCountForContainer(kDesktopBackgroundId));
    367   EXPECT_EQ(2, ChildCountForContainer(kLockScreenBackgroundId));
    368 
    369   // Before the wallpaper's animation completes, user unlocks the screen, which
    370   // moves the desktop to the back.
    371   controller->MoveDesktopToUnlockedContainer();
    372 
    373   // Ensure both desktop backgrounds have moved.
    374   EXPECT_EQ(2, ChildCountForContainer(kDesktopBackgroundId));
    375   EXPECT_EQ(0, ChildCountForContainer(kLockScreenBackgroundId));
    376 
    377   // Finish the new desktop background animation.
    378   RunDesktopControllerAnimation();
    379 
    380   // Now there is one desktop background, in the back.
    381   EXPECT_EQ(1, ChildCountForContainer(kDesktopBackgroundId));
    382   EXPECT_EQ(0, ChildCountForContainer(kLockScreenBackgroundId));
    383 }
    384 
    385 // Test for crbug.com/156542. Animating wallpaper should immediately finish
    386 // animation and replace current wallpaper before next animation starts.
    387 TEST_F(DesktopBackgroundControllerTest, ChangeWallpaperQuick) {
    388   // We cannot short-circuit animations for this test.
    389   ui::ScopedAnimationDurationScaleMode normal_duration_mode(
    390       ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
    391 
    392   // Reset wallpaper state, see ControllerOwnership above.
    393   DesktopBackgroundController* controller =
    394       Shell::GetInstance()->desktop_background_controller();
    395   controller->CreateEmptyWallpaper();
    396 
    397   // Run wallpaper show animation to completion.
    398   RunDesktopControllerAnimation();
    399 
    400   // Change to a new wallpaper.
    401   controller->CreateEmptyWallpaper();
    402 
    403   internal::RootWindowController* root_window_controller =
    404       Shell::GetPrimaryRootWindowController();
    405   internal::DesktopBackgroundWidgetController* animating_controller =
    406       root_window_controller->animating_wallpaper_controller()->
    407       GetController(false);
    408   EXPECT_TRUE(animating_controller);
    409   EXPECT_TRUE(root_window_controller->wallpaper_controller());
    410 
    411   // Change to another wallpaper before animation finished.
    412   controller->CreateEmptyWallpaper();
    413 
    414   // The animating controller should immediately move to desktop controller.
    415   EXPECT_EQ(animating_controller,
    416             root_window_controller->wallpaper_controller());
    417 
    418   // Cache the new animating controller.
    419   animating_controller = root_window_controller->
    420       animating_wallpaper_controller()->GetController(false);
    421 
    422   // Run wallpaper show animation to completion.
    423   ASSERT_NO_FATAL_FAILURE(
    424       RunAnimationForWidget(
    425           root_window_controller->animating_wallpaper_controller()->
    426               GetController(false)->widget()));
    427 
    428   EXPECT_TRUE(root_window_controller->wallpaper_controller());
    429   EXPECT_FALSE(root_window_controller->animating_wallpaper_controller()->
    430                GetController(false));
    431   // The desktop controller should be the last created animating controller.
    432   EXPECT_EQ(animating_controller,
    433             root_window_controller->wallpaper_controller());
    434 }
    435 
    436 TEST_F(DesktopBackgroundControllerTest, DisplayChange) {
    437   // TODO(derat|oshima|bshe): Host windows can't be resized on Win8.
    438   if (!SupportsHostWindowResize())
    439     return;
    440 
    441   // Set the wallpaper to ensure that UpdateWallpaper() will be called when the
    442   // display configuration changes.
    443   gfx::ImageSkia image = CreateImage(640, 480);
    444   wallpaper_delegate_->set_custom_wallpaper(image);
    445   controller_->SetCustomWallpaper(image, WALLPAPER_LAYOUT_STRETCH);
    446 
    447   // Small wallpaper images should be used for configurations less than or
    448   // equal to kSmallWallpaperMaxWidth by kSmallWallpaperMaxHeight, even if
    449   // multiple displays are connected.
    450   test::DisplayManagerTestApi display_manager_test_api(
    451       Shell::GetInstance()->display_manager());
    452   display_manager_test_api.UpdateDisplay("800x600");
    453   RunAllPendingInMessageLoop();
    454   EXPECT_EQ(WALLPAPER_RESOLUTION_SMALL,
    455             controller_->GetAppropriateResolution());
    456   EXPECT_EQ(0, wallpaper_delegate_->GetUpdateWallpaperCountAndReset());
    457 
    458   display_manager_test_api.UpdateDisplay("800x600,800x600");
    459   RunAllPendingInMessageLoop();
    460   EXPECT_EQ(WALLPAPER_RESOLUTION_SMALL,
    461             controller_->GetAppropriateResolution());
    462   EXPECT_EQ(0, wallpaper_delegate_->GetUpdateWallpaperCountAndReset());
    463 
    464   display_manager_test_api.UpdateDisplay("1366x800");
    465   RunAllPendingInMessageLoop();
    466   EXPECT_EQ(WALLPAPER_RESOLUTION_SMALL,
    467             controller_->GetAppropriateResolution());
    468   EXPECT_EQ(1, wallpaper_delegate_->GetUpdateWallpaperCountAndReset());
    469 
    470   // At larger sizes, large wallpapers should be used.
    471   display_manager_test_api.UpdateDisplay("1367x800");
    472   RunAllPendingInMessageLoop();
    473   EXPECT_EQ(WALLPAPER_RESOLUTION_LARGE,
    474             controller_->GetAppropriateResolution());
    475   EXPECT_EQ(1, wallpaper_delegate_->GetUpdateWallpaperCountAndReset());
    476 
    477   display_manager_test_api.UpdateDisplay("1367x801");
    478   RunAllPendingInMessageLoop();
    479   EXPECT_EQ(WALLPAPER_RESOLUTION_LARGE,
    480             controller_->GetAppropriateResolution());
    481   EXPECT_EQ(1, wallpaper_delegate_->GetUpdateWallpaperCountAndReset());
    482 
    483   display_manager_test_api.UpdateDisplay("2560x1700");
    484   RunAllPendingInMessageLoop();
    485   EXPECT_EQ(WALLPAPER_RESOLUTION_LARGE,
    486             controller_->GetAppropriateResolution());
    487   EXPECT_EQ(1, wallpaper_delegate_->GetUpdateWallpaperCountAndReset());
    488 
    489   // Rotated smaller screen may use larger image.
    490   display_manager_test_api.UpdateDisplay("800x600/r");
    491   RunAllPendingInMessageLoop();
    492   EXPECT_EQ(WALLPAPER_RESOLUTION_SMALL,
    493             controller_->GetAppropriateResolution());
    494   EXPECT_EQ(1, wallpaper_delegate_->GetUpdateWallpaperCountAndReset());
    495 
    496   display_manager_test_api.UpdateDisplay("800x600/r,800x600");
    497   RunAllPendingInMessageLoop();
    498   EXPECT_EQ(WALLPAPER_RESOLUTION_SMALL,
    499             controller_->GetAppropriateResolution());
    500   EXPECT_EQ(1, wallpaper_delegate_->GetUpdateWallpaperCountAndReset());
    501   display_manager_test_api.UpdateDisplay("1366x800/r");
    502   RunAllPendingInMessageLoop();
    503   EXPECT_EQ(WALLPAPER_RESOLUTION_LARGE,
    504             controller_->GetAppropriateResolution());
    505   EXPECT_EQ(1, wallpaper_delegate_->GetUpdateWallpaperCountAndReset());
    506 
    507   // Max display size didn't chagne.
    508   display_manager_test_api.UpdateDisplay("900x800/r,400x1366");
    509   RunAllPendingInMessageLoop();
    510   EXPECT_EQ(0, wallpaper_delegate_->GetUpdateWallpaperCountAndReset());
    511 }
    512 
    513 // Test that DesktopBackgroundController loads the appropriate wallpaper
    514 // images as specified via command-line flags in various situations.
    515 // Splitting these into separate tests avoids needing to run animations.
    516 // TODO(derat): Combine these into a single test -- see
    517 // RunDesktopControllerAnimation()'s TODO.
    518 TEST_F(DesktopBackgroundControllerTest, SmallDefaultWallpaper) {
    519   if (!SupportsMultipleDisplays())
    520     return;
    521 
    522   WriteWallpapersAndSetFlags();
    523   TestObserver observer(controller_);
    524 
    525   // At 800x600, the small wallpaper should be loaded.
    526   test::DisplayManagerTestApi display_manager_test_api(
    527       Shell::GetInstance()->display_manager());
    528   display_manager_test_api.UpdateDisplay("800x600");
    529   ASSERT_TRUE(controller_->SetDefaultWallpaper(false));
    530   observer.WaitForWallpaperDataChanged();
    531   EXPECT_TRUE(ImageIsNearColor(controller_->GetWallpaper(),
    532                                kSmallWallpaperColor));
    533 
    534   // Requesting the same wallpaper again should be a no-op.
    535   ASSERT_FALSE(controller_->SetDefaultWallpaper(false));
    536 }
    537 
    538 TEST_F(DesktopBackgroundControllerTest, LargeDefaultWallpaper) {
    539   if (!SupportsMultipleDisplays())
    540     return;
    541 
    542   WriteWallpapersAndSetFlags();
    543   TestObserver observer(controller_);
    544   test::DisplayManagerTestApi display_manager_test_api(
    545       Shell::GetInstance()->display_manager());
    546   display_manager_test_api.UpdateDisplay("1600x1200");
    547   ASSERT_TRUE(controller_->SetDefaultWallpaper(false));
    548   observer.WaitForWallpaperDataChanged();
    549   EXPECT_TRUE(ImageIsNearColor(controller_->GetWallpaper(),
    550                                kLargeWallpaperColor));
    551 }
    552 
    553 TEST_F(DesktopBackgroundControllerTest, LargeDefaultWallpaperWhenRotated) {
    554   if (!SupportsMultipleDisplays())
    555     return;
    556   WriteWallpapersAndSetFlags();
    557   TestObserver observer(controller_);
    558   test::DisplayManagerTestApi display_manager_test_api(
    559       Shell::GetInstance()->display_manager());
    560 
    561   display_manager_test_api.UpdateDisplay("1200x800/r");
    562   ASSERT_TRUE(controller_->SetDefaultWallpaper(false));
    563   observer.WaitForWallpaperDataChanged();
    564   EXPECT_TRUE(ImageIsNearColor(controller_->GetWallpaper(),
    565                                kLargeWallpaperColor));
    566 }
    567 
    568 TEST_F(DesktopBackgroundControllerTest, SmallGuestWallpaper) {
    569   if (!SupportsMultipleDisplays())
    570     return;
    571 
    572   WriteWallpapersAndSetFlags();
    573   TestObserver observer(controller_);
    574   test::DisplayManagerTestApi display_manager_test_api(
    575       Shell::GetInstance()->display_manager());
    576   display_manager_test_api.UpdateDisplay("800x600");
    577   ASSERT_TRUE(controller_->SetDefaultWallpaper(true));
    578   observer.WaitForWallpaperDataChanged();
    579   EXPECT_TRUE(ImageIsNearColor(controller_->GetWallpaper(),
    580                                kSmallGuestWallpaperColor));
    581 }
    582 
    583 TEST_F(DesktopBackgroundControllerTest, LargeGuestWallpaper) {
    584   if (!SupportsMultipleDisplays())
    585     return;
    586 
    587   WriteWallpapersAndSetFlags();
    588   TestObserver observer(controller_);
    589   test::DisplayManagerTestApi display_manager_test_api(
    590       Shell::GetInstance()->display_manager());
    591   display_manager_test_api.UpdateDisplay("1600x1200");
    592   ASSERT_TRUE(controller_->SetDefaultWallpaper(true));
    593   observer.WaitForWallpaperDataChanged();
    594   EXPECT_TRUE(ImageIsNearColor(controller_->GetWallpaper(),
    595                                kLargeGuestWallpaperColor));
    596 }
    597 
    598 TEST_F(DesktopBackgroundControllerTest, ResizeCustomWallpaper) {
    599   if (!SupportsMultipleDisplays())
    600     return;
    601 
    602   test::DisplayManagerTestApi display_manager_test_api(
    603       Shell::GetInstance()->display_manager());
    604   display_manager_test_api.UpdateDisplay("320x200");
    605 
    606   gfx::ImageSkia image = CreateImage(640, 480);
    607 
    608   // Set the image as custom wallpaper, wait for the resize to finish, and check
    609   // that the resized image is the expected size.
    610   controller_->SetCustomWallpaper(image, WALLPAPER_LAYOUT_STRETCH);
    611   EXPECT_TRUE(image.BackedBySameObjectAs(controller_->GetWallpaper()));
    612   content::BrowserThread::GetBlockingPool()->FlushForTesting();
    613   content::RunAllPendingInMessageLoop();
    614   gfx::ImageSkia resized_image = controller_->GetWallpaper();
    615   EXPECT_FALSE(image.BackedBySameObjectAs(resized_image));
    616   EXPECT_EQ(gfx::Size(320, 200).ToString(), resized_image.size().ToString());
    617 
    618   // Load the original wallpaper again and check that we're still using the
    619   // previously-resized image instead of doing another resize
    620   // (http://crbug.com/321402).
    621   controller_->SetCustomWallpaper(image, WALLPAPER_LAYOUT_STRETCH);
    622   content::BrowserThread::GetBlockingPool()->FlushForTesting();
    623   content::RunAllPendingInMessageLoop();
    624   EXPECT_TRUE(resized_image.BackedBySameObjectAs(controller_->GetWallpaper()));
    625 }
    626 
    627 TEST_F(DesktopBackgroundControllerTest, GetMaxDisplaySize) {
    628   // Device scale factor shouldn't affect the native size.
    629   UpdateDisplay("1000x300*2");
    630   EXPECT_EQ(
    631       "1000x300",
    632       DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString());
    633 
    634   // Rotated display should return the rotated size.
    635   UpdateDisplay("1000x300*2/r");
    636   EXPECT_EQ(
    637       "300x1000",
    638       DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString());
    639 
    640   // UI Scaling shouldn't affect the native size.
    641   UpdateDisplay("1000x300*2 (at) 1.5");
    642   EXPECT_EQ(
    643       "1000x300",
    644       DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString());
    645 
    646   if (!SupportsMultipleDisplays())
    647     return;
    648 
    649   // First display has maximum size.
    650   UpdateDisplay("400x300,100x100");
    651   EXPECT_EQ(
    652       "400x300",
    653       DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString());
    654 
    655   // Second display has maximum size.
    656   UpdateDisplay("400x300,500x600");
    657   EXPECT_EQ(
    658       "500x600",
    659       DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString());
    660 
    661   // Maximum width and height belongs to different displays.
    662   UpdateDisplay("400x300,100x500");
    663   EXPECT_EQ(
    664       "400x500",
    665       DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString());
    666 }
    667 
    668 }  // namespace ash
    669