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