Home | History | Annotate | Download | only in wallpaper
      1 // Copyright 2014 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 "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h"
      6 
      7 #include "ash/desktop_background/desktop_background_controller.h"
      8 #include "ash/desktop_background/desktop_background_controller_observer.h"
      9 #include "ash/desktop_background/desktop_background_controller_test_api.h"
     10 #include "ash/display/display_manager.h"
     11 #include "ash/shell.h"
     12 #include "ash/test/ash_test_base.h"
     13 #include "ash/test/ash_test_helper.h"
     14 #include "ash/test/display_manager_test_api.h"
     15 #include "ash/test/test_user_wallpaper_delegate.h"
     16 #include "base/command_line.h"
     17 #include "base/compiler_specific.h"
     18 #include "base/files/file_path.h"
     19 #include "base/files/file_util.h"
     20 #include "base/macros.h"
     21 #include "base/message_loop/message_loop.h"
     22 #include "base/path_service.h"
     23 #include "base/prefs/scoped_user_pref_update.h"
     24 #include "base/strings/string_number_conversions.h"
     25 #include "base/time/time.h"
     26 #include "base/values.h"
     27 #include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_test_utils.h"
     28 #include "chrome/common/chrome_paths.h"
     29 #include "chrome/test/base/in_process_browser_test.h"
     30 #include "chrome/test/base/testing_browser_process.h"
     31 #include "chromeos/chromeos_switches.h"
     32 #include "chromeos/login/user_names.h"
     33 #include "components/user_manager/user.h"
     34 #include "components/user_manager/user_manager.h"
     35 #include "content/public/test/test_utils.h"
     36 #include "ui/aura/env.h"
     37 #include "ui/gfx/image/image_skia.h"
     38 #include "ui/gfx/point.h"
     39 #include "ui/gfx/rect.h"
     40 
     41 using namespace ash;
     42 
     43 namespace chromeos {
     44 
     45 namespace {
     46 
     47 int kLargeWallpaperWidth = 256;
     48 int kLargeWallpaperHeight = chromeos::kLargeWallpaperMaxHeight;
     49 int kSmallWallpaperWidth = 256;
     50 int kSmallWallpaperHeight = chromeos::kSmallWallpaperMaxHeight;
     51 
     52 const char kTestUser1[] = "test1 (at) domain.com";
     53 const char kTestUser1Hash[] = "test1 (at) domain.com-hash";
     54 const char kTestUser2[] = "test2 (at) domain.com";
     55 const char kTestUser2Hash[] = "test2 (at) domain.com-hash";
     56 
     57 }  // namespace
     58 
     59 class WallpaperManagerBrowserTest : public InProcessBrowserTest {
     60  public:
     61   WallpaperManagerBrowserTest () : controller_(NULL),
     62                                    local_state_(NULL) {
     63   }
     64 
     65   virtual ~WallpaperManagerBrowserTest () {}
     66 
     67   virtual void SetUpOnMainThread() OVERRIDE {
     68     controller_ = ash::Shell::GetInstance()->desktop_background_controller();
     69     local_state_ = g_browser_process->local_state();
     70     DesktopBackgroundController::TestAPI(controller_)
     71         .set_wallpaper_reload_delay_for_test(0);
     72     UpdateDisplay("800x600");
     73   }
     74 
     75   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
     76     command_line->AppendSwitch(switches::kLoginManager);
     77     command_line->AppendSwitchASCII(switches::kLoginProfile, "user");
     78   }
     79 
     80   virtual void TearDownOnMainThread() OVERRIDE {
     81     controller_ = NULL;
     82   }
     83 
     84   // Update the display configuration as given in |display_specs|.  See
     85   // ash::test::DisplayManagerTestApi::UpdateDisplay for more details.
     86   void UpdateDisplay(const std::string& display_specs) {
     87     ash::test::DisplayManagerTestApi display_manager_test_api(
     88         ash::Shell::GetInstance()->display_manager());
     89     display_manager_test_api.UpdateDisplay(display_specs);
     90   }
     91 
     92   void WaitAsyncWallpaperLoadStarted() {
     93     base::RunLoop().RunUntilIdle();
     94   }
     95 
     96  protected:
     97 
     98   // Return custom wallpaper path. Create directory if not exist.
     99   base::FilePath GetCustomWallpaperPath(const char* sub_dir,
    100                                         const std::string& username_hash,
    101                                         const std::string& id) {
    102     base::FilePath wallpaper_path =
    103         WallpaperManager::Get()->GetCustomWallpaperPath(sub_dir,
    104                                                         username_hash,
    105                                                         id);
    106     if (!base::DirectoryExists(wallpaper_path.DirName()))
    107       base::CreateDirectory(wallpaper_path.DirName());
    108 
    109     return wallpaper_path;
    110   }
    111 
    112   // Logs in |username|.
    113   void LogIn(const std::string& username, const std::string& username_hash) {
    114     user_manager::UserManager::Get()->UserLoggedIn(
    115         username, username_hash, false);
    116     WaitAsyncWallpaperLoadStarted();
    117   }
    118 
    119   int LoadedWallpapers() {
    120     return WallpaperManager::Get()->loaded_wallpapers();
    121   }
    122 
    123   void ClearDisposableWallpaperCache() {
    124     WallpaperManager::Get()->ClearDisposableWallpaperCache();
    125   }
    126 
    127   // Initializes default wallpaper paths "*default_*file" and writes JPEG
    128   // wallpaper images to them.
    129   // Only needs to be called (once) by tests that want to test loading of
    130   // default wallpapers.
    131   void CreateCmdlineWallpapers() {
    132     wallpaper_dir_.reset(new base::ScopedTempDir);
    133     ASSERT_TRUE(wallpaper_dir_->CreateUniqueTempDir());
    134     wallpaper_manager_test_utils::CreateCmdlineWallpapers(
    135         *wallpaper_dir_, &wallpaper_manager_command_line_);
    136   }
    137 
    138   DesktopBackgroundController* controller_;
    139   PrefService* local_state_;
    140   scoped_ptr<base::CommandLine> wallpaper_manager_command_line_;
    141 
    142   // Directory created by CreateCmdlineWallpapers () to store default
    143   // wallpaper images.
    144   scoped_ptr<base::ScopedTempDir> wallpaper_dir_;
    145 
    146  private:
    147   DISALLOW_COPY_AND_ASSIGN(WallpaperManagerBrowserTest);
    148 };
    149 
    150 // Tests that the appropriate custom wallpaper (large vs. small) is loaded
    151 // depending on the desktop resolution.
    152 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTest,
    153                        LoadCustomLargeWallpaperForLargeExternalScreen) {
    154   WallpaperManager* wallpaper_manager = WallpaperManager::Get();
    155   LogIn(kTestUser1, kTestUser1Hash);
    156   std::string id = base::Int64ToString(base::Time::Now().ToInternalValue());
    157   base::FilePath small_wallpaper_path = GetCustomWallpaperPath(
    158       kSmallWallpaperSubDir,
    159       kTestUser1Hash,
    160       id);
    161   base::FilePath large_wallpaper_path = GetCustomWallpaperPath(
    162       kLargeWallpaperSubDir,
    163       kTestUser1Hash,
    164       id);
    165 
    166   // Saves the small/large resolution wallpapers to small/large custom
    167   // wallpaper paths.
    168   ASSERT_TRUE(wallpaper_manager_test_utils::WriteJPEGFile(
    169       small_wallpaper_path,
    170       kSmallWallpaperWidth,
    171       kSmallWallpaperHeight,
    172       wallpaper_manager_test_utils::kSmallDefaultWallpaperColor));
    173   ASSERT_TRUE(wallpaper_manager_test_utils::WriteJPEGFile(
    174       large_wallpaper_path,
    175       kLargeWallpaperWidth,
    176       kLargeWallpaperHeight,
    177       wallpaper_manager_test_utils::kLargeDefaultWallpaperColor));
    178 
    179   std::string relative_path = base::FilePath(kTestUser1Hash).Append(id).value();
    180   // Saves wallpaper info to local state for user |kTestUser1|.
    181   WallpaperInfo info = {relative_path, WALLPAPER_LAYOUT_CENTER_CROPPED,
    182                         user_manager::User::CUSTOMIZED,
    183                         base::Time::Now().LocalMidnight()};
    184   wallpaper_manager->SetUserWallpaperInfo(kTestUser1, info, true);
    185 
    186   // Set the wallpaper for |kTestUser1|.
    187   wallpaper_manager->SetUserWallpaperNow(kTestUser1);
    188   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    189   gfx::ImageSkia wallpaper = controller_->GetWallpaper();
    190 
    191   // Display is initialized to 800x600. The small resolution custom wallpaper is
    192   // expected.
    193   EXPECT_EQ(kSmallWallpaperWidth, wallpaper.width());
    194   EXPECT_EQ(kSmallWallpaperHeight, wallpaper.height());
    195 
    196   // Hook up another 800x600 display. This shouldn't trigger a reload.
    197   UpdateDisplay("800x600,800x600");
    198   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    199   // The small resolution custom wallpaper is expected.
    200   EXPECT_EQ(kSmallWallpaperWidth, wallpaper.width());
    201   EXPECT_EQ(kSmallWallpaperHeight, wallpaper.height());
    202 
    203   // Detach the secondary display.
    204   UpdateDisplay("800x600");
    205   // Hook up a 2000x2000 display. The large resolution custom wallpaper should
    206   // be loaded.
    207   UpdateDisplay("800x600,2000x2000");
    208   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    209   wallpaper = controller_->GetWallpaper();
    210 
    211   // The large resolution custom wallpaper is expected.
    212   EXPECT_EQ(kLargeWallpaperWidth, wallpaper.width());
    213   EXPECT_EQ(kLargeWallpaperHeight, wallpaper.height());
    214 
    215   // Detach the secondary display.
    216   UpdateDisplay("800x600");
    217   // Hook up the 2000x2000 display again. The large resolution default wallpaper
    218   // should persist. Test for crbug/165788.
    219   UpdateDisplay("800x600,2000x2000");
    220   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    221   wallpaper = controller_->GetWallpaper();
    222 
    223   // The large resolution custom wallpaper is expected.
    224   EXPECT_EQ(kLargeWallpaperWidth, wallpaper.width());
    225   EXPECT_EQ(kLargeWallpaperHeight, wallpaper.height());
    226 }
    227 
    228 // If chrome tries to reload the same wallpaper twice, the latter request should
    229 // be prevented. Otherwise, there are some strange animation issues as
    230 // described in crbug.com/158383.
    231 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTest,
    232                        PreventReloadingSameWallpaper) {
    233   WallpaperManager* wallpaper_manager = WallpaperManager::Get();
    234   // New user log in, a default wallpaper is loaded.
    235   LogIn(kTestUser1, kTestUser1Hash);
    236   EXPECT_EQ(1, LoadedWallpapers());
    237   // Loads the same wallpaper before the initial one finished. It should be
    238   // prevented.
    239   wallpaper_manager->SetUserWallpaperNow(kTestUser1);
    240   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    241   EXPECT_EQ(1, LoadedWallpapers());
    242   // Loads the same wallpaper after the initial one finished. It should be
    243   // prevented.
    244   wallpaper_manager->SetUserWallpaperNow(kTestUser1);
    245   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    246   EXPECT_EQ(1, LoadedWallpapers());
    247   ClearDisposableWallpaperCache();
    248 
    249   // Change wallpaper to a custom wallpaper.
    250   std::string id = base::Int64ToString(base::Time::Now().ToInternalValue());
    251   base::FilePath small_wallpaper_path = GetCustomWallpaperPath(
    252       kSmallWallpaperSubDir,
    253       kTestUser1Hash,
    254       id);
    255   ASSERT_TRUE(wallpaper_manager_test_utils::WriteJPEGFile(
    256       small_wallpaper_path,
    257       kSmallWallpaperWidth,
    258       kSmallWallpaperHeight,
    259       wallpaper_manager_test_utils::kSmallDefaultWallpaperColor));
    260 
    261   std::string relative_path = base::FilePath(kTestUser1Hash).Append(id).value();
    262   // Saves wallpaper info to local state for user |kTestUser1|.
    263   WallpaperInfo info = {relative_path, WALLPAPER_LAYOUT_CENTER_CROPPED,
    264                         user_manager::User::CUSTOMIZED,
    265                         base::Time::Now().LocalMidnight()};
    266   wallpaper_manager->SetUserWallpaperInfo(kTestUser1, info, true);
    267 
    268   wallpaper_manager->SetUserWallpaperNow(kTestUser1);
    269   WaitAsyncWallpaperLoadStarted();
    270   EXPECT_EQ(2, LoadedWallpapers());
    271   // Loads the same wallpaper before the initial one finished. It should be
    272   // prevented.
    273   wallpaper_manager->SetUserWallpaperNow(kTestUser1);
    274   WaitAsyncWallpaperLoadStarted();
    275   EXPECT_EQ(2, LoadedWallpapers());
    276   wallpaper_manager->SetUserWallpaperNow(kTestUser1);
    277   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    278   EXPECT_EQ(2, LoadedWallpapers());
    279 }
    280 
    281 // Some users have old user profiles which may have legacy wallpapers. And these
    282 // lagacy wallpapers should migrate to new wallpaper picker version seamlessly.
    283 // This tests make sure we compatible with migrated old wallpapers.
    284 // crosbug.com/38429
    285 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTest,
    286                        PRE_UseMigratedWallpaperInfo) {
    287   // New user log in, a default wallpaper is loaded.
    288   LogIn(kTestUser1, kTestUser1Hash);
    289   // Old wallpaper migration code doesn't exist in codebase anymore. Modify user
    290   // wallpaper info directly to simulate the wallpaper migration. See
    291   // crosbug.com/38429 for details about why we modify wallpaper info this way.
    292   WallpaperInfo info = {"123", WALLPAPER_LAYOUT_CENTER_CROPPED,
    293                         user_manager::User::DEFAULT,
    294                         base::Time::Now().LocalMidnight()};
    295   base::FilePath user_data_dir;
    296   ASSERT_TRUE(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir));
    297   ASSERT_TRUE(wallpaper_manager_test_utils::WriteJPEGFile(
    298       user_data_dir.Append("123"),
    299       wallpaper_manager_test_utils::kWallpaperSize,
    300       wallpaper_manager_test_utils::kWallpaperSize,
    301       wallpaper_manager_test_utils::kLargeDefaultWallpaperColor));
    302   WallpaperManager::Get()->SetUserWallpaperInfo(kTestUser1, info, true);
    303 }
    304 
    305 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTest,
    306                        UseMigratedWallpaperInfo) {
    307   LogIn(kTestUser1, kTestUser1Hash);
    308   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    309   // This test should finish normally. If timeout, it is probably because
    310   // migrated wallpaper is somehow not loaded. Bad things can happen if
    311   // wallpaper is not loaded at login screen. One example is: crosbug.com/38429.
    312 }
    313 
    314 // Some users have old user profiles which may never get a chance to migrate.
    315 // This tests make sure we compatible with these profiles.
    316 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTest,
    317                        PRE_UsePreMigrationWallpaperInfo) {
    318   // New user log in, a default wallpaper is loaded.
    319   LogIn(kTestUser1, kTestUser1Hash);
    320   // Old wallpaper migration code doesn't exist in codebase anymore. So if
    321   // user's profile is not migrated, it is the same as no wallpaper info. To
    322   // simulate this, we remove user's wallpaper info here.
    323   WallpaperManager::Get()->RemoveUserWallpaperInfo(kTestUser1);
    324 }
    325 
    326 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTest,
    327                        UsePreMigrationWallpaperInfo) {
    328   LogIn(kTestUser1, kTestUser1Hash);
    329   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    330   // This test should finish normally. If timeout, it is probably because chrome
    331   // can not handle pre migrated user profile (M21 profile or older).
    332 }
    333 
    334 // Test for http://crbug.com/265689. When hooked up a large external monitor,
    335 // the default large resolution wallpaper should load.
    336 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTest,
    337                        HotPlugInScreenAtGAIALoginScreen) {
    338   UpdateDisplay("800x600");
    339   // Set initial wallpaper to the default wallpaper.
    340   WallpaperManager::Get()->SetDefaultWallpaperNow(chromeos::login::kStubUser);
    341   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    342 
    343   // Hook up a 2000x2000 display. The large resolution custom wallpaper should
    344   // be loaded.
    345   UpdateDisplay("800x600,2000x2000");
    346   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    347 }
    348 
    349 class WallpaperManagerBrowserTestNoAnimation
    350     : public WallpaperManagerBrowserTest {
    351  public:
    352   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
    353     command_line->AppendSwitch(switches::kLoginManager);
    354     command_line->AppendSwitchASCII(switches::kLoginProfile, "user");
    355     command_line->AppendSwitch(chromeos::switches::kDisableLoginAnimations);
    356     command_line->AppendSwitch(chromeos::switches::kDisableBootAnimation);
    357   }
    358 };
    359 
    360 // Same test as WallpaperManagerBrowserTest.UseMigratedWallpaperInfo. But
    361 // disabled boot and login animation.
    362 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTestNoAnimation,
    363                        PRE_UseMigratedWallpaperInfo) {
    364   // New user log in, a default wallpaper is loaded.
    365   LogIn(kTestUser1, kTestUser1Hash);
    366   // Old wallpaper migration code doesn't exist in codebase anymore. Modify user
    367   // wallpaper info directly to simulate the wallpaper migration. See
    368   // crosbug.com/38429 for details about why we modify wallpaper info this way.
    369   WallpaperInfo info = {"123", WALLPAPER_LAYOUT_CENTER_CROPPED,
    370                         user_manager::User::DEFAULT,
    371                         base::Time::Now().LocalMidnight()};
    372   base::FilePath user_data_dir;
    373   ASSERT_TRUE(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir));
    374   ASSERT_TRUE(wallpaper_manager_test_utils::WriteJPEGFile(
    375       user_data_dir.Append("123"),
    376       wallpaper_manager_test_utils::kWallpaperSize,
    377       wallpaper_manager_test_utils::kWallpaperSize,
    378       wallpaper_manager_test_utils::kLargeDefaultWallpaperColor));
    379   WallpaperManager::Get()->SetUserWallpaperInfo(kTestUser1, info, true);
    380 }
    381 
    382 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTestNoAnimation,
    383                        UseMigratedWallpaperInfo) {
    384   LogIn(kTestUser1, kTestUser1Hash);
    385   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    386   // This test should finish normally. If timeout, it is probably because
    387   // migrated wallpaper is somehow not loaded. Bad things can happen if
    388   // wallpaper is not loaded at login screen. One example is: crosbug.com/38429.
    389 }
    390 
    391 // Same test as WallpaperManagerBrowserTest.UsePreMigrationWallpaperInfo. But
    392 // disabled boot and login animation.
    393 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTestNoAnimation,
    394                        PRE_UsePreMigrationWallpaperInfo) {
    395   // New user log in, a default wallpaper is loaded.
    396   LogIn(kTestUser1, kTestUser1Hash);
    397   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    398   // Old wallpaper migration code doesn't exist in codebase anymore. So if
    399   // user's profile is not migrated, it is the same as no wallpaper info. To
    400   // simulate this, we remove user's wallpaper info here.
    401   WallpaperManager::Get()->RemoveUserWallpaperInfo(kTestUser1);
    402 }
    403 
    404 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTestNoAnimation,
    405                        UsePreMigrationWallpaperInfo) {
    406   LogIn(kTestUser1, kTestUser1Hash);
    407   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    408   // This test should finish normally. If timeout, it is probably because chrome
    409   // can not handle pre migrated user profile (M21 profile or older).
    410 }
    411 
    412 class WallpaperManagerBrowserTestCrashRestore
    413     : public WallpaperManagerBrowserTest {
    414  public:
    415   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
    416     command_line->AppendSwitch(chromeos::switches::kDisableLoginAnimations);
    417     command_line->AppendSwitch(chromeos::switches::kDisableBootAnimation);
    418     command_line->AppendSwitchASCII(switches::kLoginUser, kTestUser1);
    419     command_line->AppendSwitchASCII(switches::kLoginProfile, "user");
    420   }
    421 };
    422 
    423 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTestCrashRestore,
    424                        PRE_RestoreWallpaper) {
    425   LogIn(kTestUser1, kTestUser1Hash);
    426   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    427 }
    428 
    429 // Test for crbug.com/270278. It simulates a browser crash and verifies if user
    430 // wallpaper is loaded.
    431 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTestCrashRestore,
    432                        RestoreWallpaper) {
    433   EXPECT_EQ(1, LoadedWallpapers());
    434 }
    435 
    436 class WallpaperManagerBrowserTestCacheUpdate
    437     : public WallpaperManagerBrowserTest {
    438  public:
    439   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
    440     command_line->AppendSwitchASCII(switches::kLoginUser, kTestUser1);
    441     command_line->AppendSwitchASCII(switches::kLoginProfile, "user");
    442   }
    443  protected:
    444   // Creates a test image of size 1x1.
    445   gfx::ImageSkia CreateTestImage(SkColor color) {
    446     return wallpaper_manager_test_utils::CreateTestImage(1, 1, color);
    447   }
    448 };
    449 
    450 // Sets kTestUser1's wallpaper to a custom wallpaper.
    451 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTestCacheUpdate,
    452                        PRE_VerifyWallpaperCache) {
    453   // Add kTestUser1 to user list. kTestUser1 is the default login profile.
    454   LogIn(kTestUser1, kTestUser1Hash);
    455 
    456   std::string id = base::Int64ToString(base::Time::Now().ToInternalValue());
    457   WallpaperManager* wallpaper_manager = WallpaperManager::Get();
    458   base::FilePath small_wallpaper_path = GetCustomWallpaperPath(
    459       kSmallWallpaperSubDir,
    460       kTestUser1Hash,
    461       id);
    462   base::FilePath large_wallpaper_path = GetCustomWallpaperPath(
    463       kLargeWallpaperSubDir,
    464       kTestUser1Hash,
    465       id);
    466 
    467   // Saves the small/large resolution wallpapers to small/large custom
    468   // wallpaper paths.
    469   ASSERT_TRUE(wallpaper_manager_test_utils::WriteJPEGFile(
    470       small_wallpaper_path,
    471       kSmallWallpaperWidth,
    472       kSmallWallpaperHeight,
    473       wallpaper_manager_test_utils::kSmallDefaultWallpaperColor));
    474   ASSERT_TRUE(wallpaper_manager_test_utils::WriteJPEGFile(
    475       large_wallpaper_path,
    476       kLargeWallpaperWidth,
    477       kLargeWallpaperHeight,
    478       wallpaper_manager_test_utils::kLargeDefaultWallpaperColor));
    479 
    480   std::string relative_path = base::FilePath(kTestUser1Hash).Append(id).value();
    481   // Saves wallpaper info to local state for user |kTestUser1|.
    482   WallpaperInfo info = {relative_path, WALLPAPER_LAYOUT_CENTER_CROPPED,
    483                         user_manager::User::CUSTOMIZED,
    484                         base::Time::Now().LocalMidnight()};
    485   wallpaper_manager->SetUserWallpaperInfo(kTestUser1, info, true);
    486   wallpaper_manager->SetUserWallpaperNow(kTestUser1);
    487   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    488   scoped_ptr<WallpaperManager::TestApi> test_api;
    489   test_api.reset(new WallpaperManager::TestApi(wallpaper_manager));
    490   // Verify SetUserWallpaperNow updates wallpaper cache.
    491   gfx::ImageSkia cached_wallpaper;
    492   EXPECT_TRUE(test_api->GetWallpaperFromCache(kTestUser1, &cached_wallpaper));
    493 }
    494 
    495 // Tests for crbug.com/339576. Wallpaper cache should be updated in
    496 // multi-profile mode when user:
    497 // 1. chooses an online wallpaper from wallpaper
    498 //    picker (calls SetWallpaperFromImageSkia);
    499 // 2. chooses a custom wallpaper from wallpaper
    500 //    picker (calls SetCustomWallpaper);
    501 // 3. reverts to a default wallpaper.
    502 // Also, when user login at multi-profile mode, previous logged in users'
    503 // wallpaper cache should not be deleted.
    504 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTestCacheUpdate,
    505                        VerifyWallpaperCache) {
    506   WallpaperManager* wallpaper_manager = WallpaperManager::Get();
    507 
    508   // Force load initial wallpaper
    509   // (simulate DesktopBackgroundController::UpdateDisplay()).
    510   wallpaper_manager->UpdateWallpaper(true);
    511   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    512   scoped_ptr<WallpaperManager::TestApi> test_api;
    513   test_api.reset(new WallpaperManager::TestApi(wallpaper_manager));
    514   gfx::ImageSkia cached_wallpaper;
    515   // Previous custom wallpaper should be cached after user login.
    516   EXPECT_TRUE(test_api->GetWallpaperFromCache(kTestUser1, &cached_wallpaper));
    517 
    518   LogIn(kTestUser2, kTestUser2Hash);
    519   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    520   // Login another user should not delete logged in user's wallpaper cache.
    521   // Note active user is still kTestUser1.
    522   EXPECT_TRUE(test_api->GetWallpaperFromCache(kTestUser1, &cached_wallpaper));
    523 
    524   gfx::ImageSkia red_wallpaper = CreateTestImage(SK_ColorRED);
    525   wallpaper_manager->SetWallpaperFromImageSkia(kTestUser1,
    526                                                red_wallpaper,
    527                                                WALLPAPER_LAYOUT_CENTER,
    528                                                true);
    529   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    530   // SetWallpaperFromImageSkia should update wallpaper cache when multi-profile
    531   // is turned on.
    532   EXPECT_TRUE(test_api->GetWallpaperFromCache(kTestUser1, &cached_wallpaper));
    533   EXPECT_TRUE(cached_wallpaper.BackedBySameObjectAs(red_wallpaper));
    534 
    535   gfx::ImageSkia green_wallpaper = CreateTestImage(SK_ColorGREEN);
    536   wallpaper_manager->SetCustomWallpaper(kTestUser1,
    537                                         kTestUser1Hash,
    538                                         "dummy",  // dummy file name
    539                                         WALLPAPER_LAYOUT_CENTER,
    540                                         user_manager::User::CUSTOMIZED,
    541                                         green_wallpaper,
    542                                         true);
    543   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    544   // SetCustomWallpaper should also update wallpaper cache when multi-profile is
    545   // turned on.
    546   EXPECT_TRUE(test_api->GetWallpaperFromCache(kTestUser1, &cached_wallpaper));
    547   EXPECT_TRUE(cached_wallpaper.BackedBySameObjectAs(green_wallpaper));
    548 
    549   wallpaper_manager->SetDefaultWallpaperNow(kTestUser1);
    550   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    551   // SetDefaultWallpaper should invalidate the user's wallpaper cache.
    552   EXPECT_FALSE(test_api->GetWallpaperFromCache(kTestUser1, &cached_wallpaper));
    553 }
    554 
    555 // ----------------------------------------------------------------------
    556 // Test default wallpapers.
    557 
    558 class TestObserver : public WallpaperManager::Observer {
    559  public:
    560   explicit TestObserver(WallpaperManager* wallpaper_manager)
    561       : update_wallpaper_count_(0), wallpaper_manager_(wallpaper_manager) {
    562     DCHECK(wallpaper_manager_);
    563     wallpaper_manager_->AddObserver(this);
    564   }
    565 
    566   virtual ~TestObserver() {
    567     wallpaper_manager_->RemoveObserver(this);
    568   }
    569 
    570   virtual void OnWallpaperAnimationFinished(const std::string&) OVERRIDE {
    571   }
    572 
    573   virtual void OnUpdateWallpaperForTesting() OVERRIDE {
    574     ++update_wallpaper_count_;
    575   }
    576 
    577   int GetUpdateWallpaperCountAndReset() {
    578     const size_t old = update_wallpaper_count_;
    579     update_wallpaper_count_ = 0;
    580     return old;
    581   }
    582 
    583  private:
    584   int update_wallpaper_count_;
    585   WallpaperManager* wallpaper_manager_;
    586 
    587   DISALLOW_COPY_AND_ASSIGN(TestObserver);
    588 };
    589 
    590 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTest, DisplayChange) {
    591   // TODO(derat|oshima|bshe): Host windows can't be resized on Win8.
    592   if (!ash::test::AshTestHelper::SupportsHostWindowResize())
    593     return;
    594 
    595   TestObserver observer(WallpaperManager::Get());
    596 
    597   // Set the wallpaper to ensure that UpdateWallpaper() will be called when the
    598   // display configuration changes.
    599   gfx::ImageSkia image = wallpaper_manager_test_utils::CreateTestImage(
    600       640, 480, wallpaper_manager_test_utils::kCustomWallpaperColor);
    601   controller_->SetWallpaperImage(image, WALLPAPER_LAYOUT_STRETCH);
    602 
    603   // Small wallpaper images should be used for configurations less than or
    604   // equal to kSmallWallpaperMaxWidth by kSmallWallpaperMaxHeight, even if
    605   // multiple displays are connected.
    606   UpdateDisplay("800x600");
    607   // Wait for asynchronous DisplayBackgroundController::UpdateDisplay() call.
    608   base::RunLoop().RunUntilIdle();
    609   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    610   EXPECT_EQ(WallpaperManager::WALLPAPER_RESOLUTION_SMALL,
    611             WallpaperManager::Get()->GetAppropriateResolution());
    612   EXPECT_EQ(0, observer.GetUpdateWallpaperCountAndReset());
    613 
    614   UpdateDisplay("800x600,800x600");
    615   // Wait for asynchronous DisplayBackgroundController::UpdateDisplay() call.
    616   base::RunLoop().RunUntilIdle();
    617   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    618   EXPECT_EQ(WallpaperManager::WALLPAPER_RESOLUTION_SMALL,
    619             WallpaperManager::Get()->GetAppropriateResolution());
    620   EXPECT_EQ(0, observer.GetUpdateWallpaperCountAndReset());
    621 
    622   UpdateDisplay("1366x800");
    623   // Wait for asynchronous DisplayBackgroundController::UpdateDisplay() call.
    624   base::RunLoop().RunUntilIdle();
    625   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    626   EXPECT_EQ(WallpaperManager::WALLPAPER_RESOLUTION_SMALL,
    627             WallpaperManager::Get()->GetAppropriateResolution());
    628   EXPECT_EQ(1, observer.GetUpdateWallpaperCountAndReset());
    629 
    630   // At larger sizes, large wallpapers should be used.
    631   UpdateDisplay("1367x800");
    632   // Wait for asynchronous DisplayBackgroundController::UpdateDisplay() call.
    633   base::RunLoop().RunUntilIdle();
    634   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    635   EXPECT_EQ(WallpaperManager::WALLPAPER_RESOLUTION_LARGE,
    636             WallpaperManager::Get()->GetAppropriateResolution());
    637   EXPECT_EQ(1, observer.GetUpdateWallpaperCountAndReset());
    638 
    639   UpdateDisplay("1367x801");
    640   // Wait for asynchronous DisplayBackgroundController::UpdateDisplay() call.
    641   base::RunLoop().RunUntilIdle();
    642   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    643   EXPECT_EQ(WallpaperManager::WALLPAPER_RESOLUTION_LARGE,
    644             WallpaperManager::Get()->GetAppropriateResolution());
    645   EXPECT_EQ(1, observer.GetUpdateWallpaperCountAndReset());
    646 
    647   UpdateDisplay("2560x1700");
    648   // Wait for asynchronous DisplayBackgroundController::UpdateDisplay() call.
    649   base::RunLoop().RunUntilIdle();
    650   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    651   EXPECT_EQ(WallpaperManager::WALLPAPER_RESOLUTION_LARGE,
    652             WallpaperManager::Get()->GetAppropriateResolution());
    653   EXPECT_EQ(1, observer.GetUpdateWallpaperCountAndReset());
    654 
    655   // Rotated smaller screen may use larger image.
    656   UpdateDisplay("800x600/r");
    657   // Wait for asynchronous DisplayBackgroundController::UpdateDisplay() call.
    658   base::RunLoop().RunUntilIdle();
    659   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    660   EXPECT_EQ(WallpaperManager::WALLPAPER_RESOLUTION_SMALL,
    661             WallpaperManager::Get()->GetAppropriateResolution());
    662   EXPECT_EQ(1, observer.GetUpdateWallpaperCountAndReset());
    663 
    664   UpdateDisplay("800x600/r,800x600");
    665   // Wait for asynchronous DisplayBackgroundController::UpdateDisplay() call.
    666   base::RunLoop().RunUntilIdle();
    667   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    668   EXPECT_EQ(WallpaperManager::WALLPAPER_RESOLUTION_SMALL,
    669             WallpaperManager::Get()->GetAppropriateResolution());
    670   EXPECT_EQ(1, observer.GetUpdateWallpaperCountAndReset());
    671   UpdateDisplay("1366x800/r");
    672   // Wait for asynchronous DisplayBackgroundController::UpdateDisplay() call.
    673   base::RunLoop().RunUntilIdle();
    674   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    675   EXPECT_EQ(WallpaperManager::WALLPAPER_RESOLUTION_LARGE,
    676             WallpaperManager::Get()->GetAppropriateResolution());
    677   EXPECT_EQ(1, observer.GetUpdateWallpaperCountAndReset());
    678 
    679   // Max display size didn't chagne.
    680   UpdateDisplay("900x800/r,400x1366");
    681   // Wait for asynchronous DisplayBackgroundController::UpdateDisplay() call.
    682   base::RunLoop().RunUntilIdle();
    683   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    684   EXPECT_EQ(0, observer.GetUpdateWallpaperCountAndReset());
    685 }
    686 
    687 // Test that WallpaperManager loads the appropriate wallpaper
    688 // images as specified via command-line flags in various situations.
    689 // Splitting these into separate tests avoids needing to run animations.
    690 // TODO(derat): Combine these into a single test
    691 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTest, SmallDefaultWallpaper) {
    692   if (!ash::test::AshTestHelper::SupportsMultipleDisplays())
    693     return;
    694 
    695   CreateCmdlineWallpapers();
    696 
    697   // At 800x600, the small wallpaper should be loaded.
    698   UpdateDisplay("800x600");
    699   WallpaperManager::Get()->SetDefaultWallpaperNow(std::string());
    700   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    701   EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor(
    702       controller_->GetWallpaper(),
    703       wallpaper_manager_test_utils::kSmallDefaultWallpaperColor));
    704 }
    705 
    706 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTest, LargeDefaultWallpaper) {
    707   if (!ash::test::AshTestHelper::SupportsMultipleDisplays())
    708     return;
    709 
    710   CreateCmdlineWallpapers();
    711   UpdateDisplay("1600x1200");
    712   WallpaperManager::Get()->SetDefaultWallpaperNow(std::string());
    713   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    714   EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor(
    715       controller_->GetWallpaper(),
    716       wallpaper_manager_test_utils::kLargeDefaultWallpaperColor));
    717 }
    718 
    719 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTest,
    720                        LargeDefaultWallpaperWhenRotated) {
    721   if (!ash::test::AshTestHelper::SupportsMultipleDisplays())
    722     return;
    723   CreateCmdlineWallpapers();
    724 
    725   UpdateDisplay("1200x800/r");
    726   WallpaperManager::Get()->SetDefaultWallpaperNow(std::string());
    727   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    728   EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor(
    729       controller_->GetWallpaper(),
    730       wallpaper_manager_test_utils::kLargeDefaultWallpaperColor));
    731 }
    732 
    733 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTest, SmallGuestWallpaper) {
    734   if (!ash::test::AshTestHelper::SupportsMultipleDisplays())
    735     return;
    736   CreateCmdlineWallpapers();
    737   user_manager::UserManager::Get()->UserLoggedIn(
    738       chromeos::login::kGuestUserName, chromeos::login::kGuestUserName, false);
    739   UpdateDisplay("800x600");
    740   WallpaperManager::Get()->SetDefaultWallpaperNow(std::string());
    741   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    742   EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor(
    743       controller_->GetWallpaper(),
    744       wallpaper_manager_test_utils::kSmallGuestWallpaperColor));
    745 }
    746 
    747 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTest, LargeGuestWallpaper) {
    748   if (!ash::test::AshTestHelper::SupportsMultipleDisplays())
    749     return;
    750 
    751   CreateCmdlineWallpapers();
    752   user_manager::UserManager::Get()->UserLoggedIn(
    753       chromeos::login::kGuestUserName, chromeos::login::kGuestUserName, false);
    754   UpdateDisplay("1600x1200");
    755   WallpaperManager::Get()->SetDefaultWallpaperNow(std::string());
    756   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    757   EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor(
    758       controller_->GetWallpaper(),
    759       wallpaper_manager_test_utils::kLargeGuestWallpaperColor));
    760 }
    761 
    762 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTest,
    763                        SwitchBetweenDefaultAndCustom) {
    764   // Start loading the default wallpaper.
    765   UpdateDisplay("640x480");
    766   CreateCmdlineWallpapers();
    767   user_manager::UserManager::Get()->UserLoggedIn(
    768       chromeos::login::kStubUser, "test_hash", false);
    769 
    770   WallpaperManager::Get()->SetDefaultWallpaperNow(std::string());
    771 
    772   // Custom wallpaper should be applied immediately, canceling the default
    773   // wallpaper load task.
    774   gfx::ImageSkia image = wallpaper_manager_test_utils::CreateTestImage(
    775       640, 480, wallpaper_manager_test_utils::kCustomWallpaperColor);
    776   WallpaperManager::Get()->SetCustomWallpaper(chromeos::login::kStubUser,
    777                                               "test_hash",
    778                                               "test-nofile.jpeg",
    779                                               WALLPAPER_LAYOUT_STRETCH,
    780                                               user_manager::User::CUSTOMIZED,
    781                                               image,
    782                                               true);
    783   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    784 
    785   EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor(
    786       controller_->GetWallpaper(),
    787       wallpaper_manager_test_utils::kCustomWallpaperColor));
    788 
    789   WallpaperManager::Get()->SetDefaultWallpaperNow(std::string());
    790   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
    791 
    792   EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor(
    793       controller_->GetWallpaper(),
    794       wallpaper_manager_test_utils::kSmallDefaultWallpaperColor));
    795 }
    796 
    797 }  // namespace chromeos
    798