- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / login / wallpaper_manager_browsertest.cc
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 "chrome/browser/chromeos/login/wallpaper_manager.h"
6
7 #include "ash/ash_resources/grit/ash_resources.h"
8 #include "ash/desktop_background/desktop_background_controller.h"
9 #include "ash/desktop_background/desktop_background_controller_observer.h"
10 #include "ash/display/display_manager.h"
11 #include "ash/shell.h"
12 #include "ash/test/display_manager_test_api.h"
13 #include "base/command_line.h"
14 #include "base/file_util.h"
15 #include "base/message_loop/message_loop.h"
16 #include "base/prefs/scoped_user_pref_update.h"
17 #include "base/strings/string_number_conversions.h"
18 #include "base/time/time.h"
19 #include "base/values.h"
20 #include "chrome/browser/chromeos/login/user.h"
21 #include "chrome/browser/chromeos/login/user_manager.h"
22 #include "chrome/common/chrome_switches.h"
23 #include "chrome/test/base/in_process_browser_test.h"
24 #include "chrome/test/base/testing_browser_process.h"
25 #include "chromeos/chromeos_switches.h"
26 #include "chromeos/dbus/cryptohome_client.h"
27 #include "ui/aura/env.h"
28 #include "ui/base/resource/resource_bundle.h"
29
30 using namespace ash;
31
32 namespace chromeos {
33
34 namespace {
35
36 const int kLargeWallpaperResourceId = IDR_AURA_WALLPAPER_DEFAULT_LARGE;
37 const int kSmallWallpaperResourceId = IDR_AURA_WALLPAPER_DEFAULT_SMALL;
38
39 int kLargeWallpaperWidth = 256;
40 int kLargeWallpaperHeight = ash::kLargeWallpaperMaxHeight;
41 int kSmallWallpaperWidth = 256;
42 int kSmallWallpaperHeight = ash::kSmallWallpaperMaxHeight;
43
44 const char kTestUser1[] = "test@domain.com";
45 const char kTestUser1Hash[] = "test@domain.com-hash";
46
47 }  // namespace
48
49 class WallpaperManagerBrowserTest : public InProcessBrowserTest,
50                                     public DesktopBackgroundControllerObserver {
51  public:
52   WallpaperManagerBrowserTest () : controller_(NULL),
53                                    local_state_(NULL) {
54   }
55
56   virtual ~WallpaperManagerBrowserTest () {}
57
58   virtual void SetUpOnMainThread() OVERRIDE {
59     controller_ = ash::Shell::GetInstance()->desktop_background_controller();
60     controller_->AddObserver(this);
61     local_state_ = g_browser_process->local_state();
62     UpdateDisplay("800x600");
63   }
64
65   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
66     command_line->AppendSwitch(switches::kLoginManager);
67     command_line->AppendSwitchASCII(switches::kLoginProfile, "user");
68   }
69
70   virtual void CleanUpOnMainThread() OVERRIDE {
71     controller_->RemoveObserver(this);
72     controller_ = NULL;
73   }
74
75   // Update the display configuration as given in |display_specs|.
76   // See ash::test::DisplayManagerTestApi::UpdateDisplay for more
77   // details.
78   void UpdateDisplay(const std::string& display_specs) {
79     ash::test::DisplayManagerTestApi display_manager_test_api(
80         ash::Shell::GetInstance()->display_manager());
81     display_manager_test_api.UpdateDisplay(display_specs);
82   }
83
84   void WaitAsyncWallpaperLoad() {
85     base::MessageLoop::current()->Run();
86   }
87
88   virtual void OnWallpaperDataChanged() OVERRIDE {
89     base::MessageLoop::current()->Quit();
90   }
91
92  protected:
93   // Return custom wallpaper path. Create directory if not exist.
94   base::FilePath GetCustomWallpaperPath(const char* sub_dir,
95                                         const std::string& username_hash,
96                                         const std::string& id) {
97     base::FilePath wallpaper_path =
98         WallpaperManager::Get()->GetCustomWallpaperPath(sub_dir,
99                                                         username_hash,
100                                                         id);
101     if (!base::DirectoryExists(wallpaper_path.DirName()))
102       file_util::CreateDirectory(wallpaper_path.DirName());
103
104     return wallpaper_path;
105   }
106
107   // Logs in |username|.
108   void LogIn(const std::string& username, const std::string& username_hash) {
109     UserManager::Get()->UserLoggedIn(username, username_hash, false);
110   }
111
112   // Saves bitmap |resource_id| to disk.
113   void SaveUserWallpaperData(const std::string& username,
114                              const base::FilePath& wallpaper_path,
115                              int resource_id) {
116     scoped_refptr<base::RefCountedStaticMemory> image_data(
117         ResourceBundle::GetSharedInstance().LoadDataResourceBytesForScale(
118             resource_id, ui::SCALE_FACTOR_100P));
119     int written = file_util::WriteFile(
120         wallpaper_path,
121         reinterpret_cast<const char*>(image_data->front()),
122         image_data->size());
123     EXPECT_EQ(static_cast<int>(image_data->size()), written);
124   }
125
126   int LoadedWallpapers() {
127     return WallpaperManager::Get()->loaded_wallpapers();
128   }
129
130   DesktopBackgroundController* controller_;
131   PrefService* local_state_;
132
133  private:
134   DISALLOW_COPY_AND_ASSIGN(WallpaperManagerBrowserTest);
135 };
136
137 // Tests that the appropriate custom wallpaper (large vs. small) is loaded
138 // depending on the desktop resolution.
139 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTest,
140                        LoadCustomLargeWallpaperForLargeExternalScreen) {
141   WallpaperManager* wallpaper_manager = WallpaperManager::Get();
142   LogIn(kTestUser1, kTestUser1Hash);
143   // Wait for default wallpaper loaded.
144   WaitAsyncWallpaperLoad();
145   std::string id = base::Int64ToString(base::Time::Now().ToInternalValue());
146   base::FilePath small_wallpaper_path = GetCustomWallpaperPath(
147       kSmallWallpaperSubDir,
148       kTestUser1Hash,
149       id);
150   base::FilePath large_wallpaper_path = GetCustomWallpaperPath(
151       kLargeWallpaperSubDir,
152       kTestUser1Hash,
153       id);
154
155   // Saves the small/large resolution wallpapers to small/large custom
156   // wallpaper paths.
157   SaveUserWallpaperData(kTestUser1,
158                         small_wallpaper_path,
159                         kSmallWallpaperResourceId);
160   SaveUserWallpaperData(kTestUser1,
161                         large_wallpaper_path,
162                         kLargeWallpaperResourceId);
163
164   std::string relative_path = base::FilePath(kTestUser1Hash).Append(id).value();
165   // Saves wallpaper info to local state for user |kTestUser1|.
166   WallpaperInfo info = {
167       relative_path,
168       WALLPAPER_LAYOUT_CENTER_CROPPED,
169       User::CUSTOMIZED,
170       base::Time::Now().LocalMidnight()
171   };
172   wallpaper_manager->SetUserWallpaperInfo(kTestUser1, info, true);
173
174   // Set the wallpaper for |kTestUser1|.
175   wallpaper_manager->SetUserWallpaper(kTestUser1);
176   WaitAsyncWallpaperLoad();
177   gfx::ImageSkia wallpaper = controller_->GetWallpaper();
178
179   // Display is initialized to 800x600. The small resolution custom wallpaper is
180   // expected.
181   EXPECT_EQ(kSmallWallpaperWidth, wallpaper.width());
182   EXPECT_EQ(kSmallWallpaperHeight, wallpaper.height());
183
184   // Hook up another 800x600 display.
185   UpdateDisplay("800x600,800x600");
186   WaitAsyncWallpaperLoad();
187   // The small resolution custom wallpaper is expected.
188   EXPECT_EQ(kSmallWallpaperWidth, wallpaper.width());
189   EXPECT_EQ(kSmallWallpaperHeight, wallpaper.height());
190
191   // Detach the secondary display.
192   UpdateDisplay("800x600");
193   // Hook up a 2000x2000 display. The large resolution custom wallpaper should
194   // be loaded.
195   UpdateDisplay("800x600,2000x2000");
196   WaitAsyncWallpaperLoad();
197   wallpaper = controller_->GetWallpaper();
198
199   // The large resolution custom wallpaper is expected.
200   EXPECT_EQ(kLargeWallpaperWidth, wallpaper.width());
201   EXPECT_EQ(kLargeWallpaperHeight, wallpaper.height());
202
203   // Detach the secondary display.
204   UpdateDisplay("800x600");
205   // Hook up the 2000x2000 display again. The large resolution default wallpaper
206   // should persist. Test for crbug/165788.
207   UpdateDisplay("800x600,2000x2000");
208   WaitAsyncWallpaperLoad();
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
216 // If chrome tries to reload the same wallpaper twice, the latter request should
217 // be prevented. Otherwise, there are some strange animation issues as
218 // described in crbug.com/158383.
219 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTest,
220                        PreventReloadingSameWallpaper) {
221   WallpaperManager* wallpaper_manager = WallpaperManager::Get();
222   // New user log in, a default wallpaper is loaded.
223   LogIn(kTestUser1, kTestUser1Hash);
224   EXPECT_EQ(1, LoadedWallpapers());
225   // Loads the same wallpaper before the initial one finished. It should be
226   // prevented.
227   wallpaper_manager->SetUserWallpaper(kTestUser1);
228   EXPECT_EQ(1, LoadedWallpapers());
229   WaitAsyncWallpaperLoad();
230   // Loads the same wallpaper after the initial one finished. It should be
231   // prevented.
232   wallpaper_manager->SetUserWallpaper(kTestUser1);
233   EXPECT_EQ(1, LoadedWallpapers());
234   wallpaper_manager->ClearWallpaperCache();
235
236   // Change wallpaper to a custom wallpaper.
237   std::string id = base::Int64ToString(base::Time::Now().ToInternalValue());
238   base::FilePath small_wallpaper_path = GetCustomWallpaperPath(
239       kSmallWallpaperSubDir,
240       kTestUser1Hash,
241       id);
242   SaveUserWallpaperData(kTestUser1,
243                         small_wallpaper_path,
244                         kSmallWallpaperResourceId);
245
246   std::string relative_path = base::FilePath(kTestUser1Hash).Append(id).value();
247   // Saves wallpaper info to local state for user |kTestUser1|.
248   WallpaperInfo info = {
249       relative_path,
250       WALLPAPER_LAYOUT_CENTER_CROPPED,
251       User::CUSTOMIZED,
252       base::Time::Now().LocalMidnight()
253   };
254   wallpaper_manager->SetUserWallpaperInfo(kTestUser1, info, true);
255
256   wallpaper_manager->SetUserWallpaper(kTestUser1);
257   EXPECT_EQ(2, LoadedWallpapers());
258   // Loads the same wallpaper before the initial one finished. It should be
259   // prevented.
260   wallpaper_manager->SetUserWallpaper(kTestUser1);
261   EXPECT_EQ(2, LoadedWallpapers());
262   WaitAsyncWallpaperLoad();
263   wallpaper_manager->SetUserWallpaper(kTestUser1);
264   EXPECT_EQ(2, LoadedWallpapers());
265 }
266
267 // Some users have old user profiles which may have legacy wallpapers. And these
268 // lagacy wallpapers should migrate to new wallpaper picker version seamlessly.
269 // This tests make sure we compatible with migrated old wallpapers.
270 // crosbug.com/38429
271 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTest,
272                        PRE_UseMigratedWallpaperInfo) {
273   // New user log in, a default wallpaper is loaded.
274   LogIn(kTestUser1, kTestUser1Hash);
275   WaitAsyncWallpaperLoad();
276   // Old wallpaper migration code doesn't exist in codebase anymore. Modify user
277   // wallpaper info directly to simulate the wallpaper migration. See
278   // crosbug.com/38429 for details about why we modify wallpaper info this way.
279   WallpaperInfo info = {
280       "123",
281       WALLPAPER_LAYOUT_CENTER_CROPPED,
282       User::DEFAULT,
283       base::Time::Now().LocalMidnight()
284   };
285   WallpaperManager::Get()->SetUserWallpaperInfo(kTestUser1, info, true);
286 }
287
288 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTest,
289                        UseMigratedWallpaperInfo) {
290   LogIn(kTestUser1, kTestUser1Hash);
291   WaitAsyncWallpaperLoad();
292   // This test should finish normally. If timeout, it is probably because
293   // migrated wallpaper is somehow not loaded. Bad things can happen if
294   // wallpaper is not loaded at login screen. One example is: crosbug.com/38429.
295 }
296
297 // Some users have old user profiles which may never get a chance to migrate.
298 // This tests make sure we compatible with these profiles.
299 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTest,
300                        PRE_UsePreMigrationWallpaperInfo) {
301   // New user log in, a default wallpaper is loaded.
302   LogIn(kTestUser1, kTestUser1Hash);
303   WaitAsyncWallpaperLoad();
304   // Old wallpaper migration code doesn't exist in codebase anymore. So if
305   // user's profile is not migrated, it is the same as no wallpaper info. To
306   // simulate this, we remove user's wallpaper info here.
307   WallpaperManager::Get()->RemoveUserWallpaperInfo(kTestUser1);
308 }
309
310 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTest,
311                        UsePreMigrationWallpaperInfo) {
312   LogIn(kTestUser1, kTestUser1Hash);
313   WaitAsyncWallpaperLoad();
314   // This test should finish normally. If timeout, it is probably because chrome
315   // can not handle pre migrated user profile (M21 profile or older).
316 }
317
318 // Test for http://crbug.com/265689. When hooked up a large external monitor,
319 // the default large resolution wallpaper should load.
320 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTest,
321                        HotPlugInScreenAtGAIALoginScreen) {
322   UpdateDisplay("800x600");
323   // Set initial wallpaper to the default wallpaper.
324   WallpaperManager::Get()->SetDefaultWallpaper();
325   WaitAsyncWallpaperLoad();
326
327   // Hook up a 2000x2000 display. The large resolution custom wallpaper should
328   // be loaded.
329   UpdateDisplay("800x600,2000x2000");
330   WaitAsyncWallpaperLoad();
331 }
332
333 class WallpaperManagerBrowserTestNoAnimation
334     : public WallpaperManagerBrowserTest {
335  public:
336   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
337     command_line->AppendSwitch(switches::kLoginManager);
338     command_line->AppendSwitchASCII(switches::kLoginProfile, "user");
339     command_line->AppendSwitch(chromeos::switches::kDisableLoginAnimations);
340     command_line->AppendSwitch(chromeos::switches::kDisableBootAnimation);
341   }
342 };
343
344 // Same test as WallpaperManagerBrowserTest.UseMigratedWallpaperInfo. But
345 // disabled boot and login animation.
346 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTestNoAnimation,
347                        PRE_UseMigratedWallpaperInfo) {
348   // New user log in, a default wallpaper is loaded.
349   LogIn(kTestUser1, kTestUser1Hash);
350   WaitAsyncWallpaperLoad();
351   // Old wallpaper migration code doesn't exist in codebase anymore. Modify user
352   // wallpaper info directly to simulate the wallpaper migration. See
353   // crosbug.com/38429 for details about why we modify wallpaper info this way.
354   WallpaperInfo info = {
355       "123",
356       WALLPAPER_LAYOUT_CENTER_CROPPED,
357       User::DEFAULT,
358       base::Time::Now().LocalMidnight()
359   };
360   WallpaperManager::Get()->SetUserWallpaperInfo(kTestUser1, info, true);
361 }
362
363 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTestNoAnimation,
364                        UseMigratedWallpaperInfo) {
365   LogIn(kTestUser1, kTestUser1Hash);
366   WaitAsyncWallpaperLoad();
367   // This test should finish normally. If timeout, it is probably because
368   // migrated wallpaper is somehow not loaded. Bad things can happen if
369   // wallpaper is not loaded at login screen. One example is: crosbug.com/38429.
370 }
371
372 // Same test as WallpaperManagerBrowserTest.UsePreMigrationWallpaperInfo. But
373 // disabled boot and login animation.
374 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTestNoAnimation,
375                        PRE_UsePreMigrationWallpaperInfo) {
376   // New user log in, a default wallpaper is loaded.
377   LogIn(kTestUser1, kTestUser1Hash);
378   WaitAsyncWallpaperLoad();
379   // Old wallpaper migration code doesn't exist in codebase anymore. So if
380   // user's profile is not migrated, it is the same as no wallpaper info. To
381   // simulate this, we remove user's wallpaper info here.
382   WallpaperManager::Get()->RemoveUserWallpaperInfo(kTestUser1);
383 }
384
385 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTestNoAnimation,
386                        UsePreMigrationWallpaperInfo) {
387   LogIn(kTestUser1, kTestUser1Hash);
388   WaitAsyncWallpaperLoad();
389   // This test should finish normally. If timeout, it is probably because chrome
390   // can not handle pre migrated user profile (M21 profile or older).
391 }
392
393 class WallpaperManagerBrowserTestCrashRestore
394     : public WallpaperManagerBrowserTest {
395  public:
396   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
397     command_line->AppendSwitch(chromeos::switches::kDisableLoginAnimations);
398     command_line->AppendSwitch(chromeos::switches::kDisableBootAnimation);
399     command_line->AppendSwitch(::switches::kMultiProfiles);
400     command_line->AppendSwitchASCII(switches::kLoginUser, kTestUser1);
401     command_line->AppendSwitchASCII(switches::kLoginProfile,
402         CryptohomeClient::GetStubSanitizedUsername(kTestUser1));
403   }
404 };
405
406 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTestCrashRestore,
407                        PRE_RestoreWallpaper) {
408   LogIn(kTestUser1, kTestUser1Hash);
409 }
410
411 // Test for crbug.com/270278. It simulates a browser crash and verifies if user
412 // wallpaper is loaded.
413 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTestCrashRestore,
414                        RestoreWallpaper) {
415   EXPECT_EQ(1, LoadedWallpapers());
416 }
417
418 }  // namespace chromeos