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
41using namespace ash;
42
43namespace chromeos {
44
45namespace {
46
47int kLargeWallpaperWidth = 256;
48int kLargeWallpaperHeight = chromeos::kLargeWallpaperMaxHeight;
49int kSmallWallpaperWidth = 256;
50int kSmallWallpaperHeight = chromeos::kSmallWallpaperMaxHeight;
51
52const char kTestUser1[] = "test1@domain.com";
53const char kTestUser1Hash[] = "test1@domain.com-hash";
54const char kTestUser2[] = "test2@domain.com";
55const char kTestUser2Hash[] = "test2@domain.com-hash";
56
57}  // namespace
58
59class 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.
152IN_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.
231IN_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
285IN_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
305IN_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.
316IN_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
326IN_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.
336IN_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
349class 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.
362IN_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
382IN_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.
393IN_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
404IN_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
412class 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
423IN_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.
431IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTestCrashRestore,
432                       RestoreWallpaper) {
433  EXPECT_EQ(1, LoadedWallpapers());
434}
435
436class 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.
451IN_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.
504IN_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
558class 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
590IN_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
691IN_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
706IN_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
719IN_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
733IN_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
747IN_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
762IN_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