03d30641ba2846ea54f31f3ebb46cc51e06c9918
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / login / user_image_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 <map>
6 #include <string>
7 #include <vector>
8
9 #include "base/basictypes.h"
10 #include "base/compiler_specific.h"
11 #include "base/file_util.h"
12 #include "base/files/file_path.h"
13 #include "base/json/json_writer.h"
14 #include "base/memory/linked_ptr.h"
15 #include "base/memory/ref_counted.h"
16 #include "base/memory/ref_counted_memory.h"
17 #include "base/memory/scoped_ptr.h"
18 #include "base/message_loop/message_loop_proxy.h"
19 #include "base/path_service.h"
20 #include "base/prefs/pref_change_registrar.h"
21 #include "base/prefs/pref_service.h"
22 #include "base/prefs/scoped_user_pref_update.h"
23 #include "base/run_loop.h"
24 #include "base/time/time.h"
25 #include "base/values.h"
26 #include "chrome/browser/browser_process.h"
27 #include "chrome/browser/chrome_notification_types.h"
28 #include "chrome/browser/chromeos/login/default_user_images.h"
29 #include "chrome/browser/chromeos/login/login_manager_test.h"
30 #include "chrome/browser/chromeos/login/mock_user_manager.h"
31 #include "chrome/browser/chromeos/login/startup_utils.h"
32 #include "chrome/browser/chromeos/login/user.h"
33 #include "chrome/browser/chromeos/login/user_image.h"
34 #include "chrome/browser/chromeos/login/user_image_manager.h"
35 #include "chrome/browser/chromeos/login/user_image_manager_impl.h"
36 #include "chrome/browser/chromeos/login/user_image_manager_test_util.h"
37 #include "chrome/browser/chromeos/login/user_manager.h"
38 #include "chrome/browser/chromeos/policy/cloud_external_data_manager_base_test_util.h"
39 #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h"
40 #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_factory_chromeos.h"
41 #include "chrome/browser/profiles/profile.h"
42 #include "chrome/browser/profiles/profile_downloader.h"
43 #include "chrome/common/chrome_paths.h"
44 #include "chrome/test/base/in_process_browser_test.h"
45 #include "chrome/test/base/testing_browser_process.h"
46 #include "chromeos/chromeos_paths.h"
47 #include "chromeos/dbus/cryptohome_client.h"
48 #include "chromeos/dbus/dbus_thread_manager.h"
49 #include "chromeos/dbus/fake_dbus_thread_manager.h"
50 #include "chromeos/dbus/fake_session_manager_client.h"
51 #include "chromeos/dbus/session_manager_client.h"
52 #include "components/policy/core/common/cloud/cloud_policy_core.h"
53 #include "components/policy/core/common/cloud/cloud_policy_store.h"
54 #include "components/policy/core/common/cloud/policy_builder.h"
55 #include "content/public/browser/notification_service.h"
56 #include "content/public/browser/notification_source.h"
57 #include "content/public/test/test_utils.h"
58 #include "crypto/rsa_private_key.h"
59 #include "google_apis/gaia/oauth2_token_service.h"
60 #include "net/test/embedded_test_server/embedded_test_server.h"
61 #include "net/url_request/test_url_fetcher_factory.h"
62 #include "net/url_request/url_fetcher_delegate.h"
63 #include "net/url_request/url_request_status.h"
64 #include "policy/proto/cloud_policy.pb.h"
65 #include "testing/gtest/include/gtest/gtest.h"
66 #include "third_party/skia/include/core/SkBitmap.h"
67 #include "ui/base/layout.h"
68 #include "ui/base/resource/resource_bundle.h"
69 #include "ui/gfx/image/image_skia.h"
70 #include "url/gurl.h"
71
72 namespace chromeos {
73
74 namespace {
75
76 const char kTestUser1[] = "test-user@example.com";
77 const char kTestUser2[] = "test-user2@example.com";
78
79 policy::CloudPolicyStore* GetStoreForUser(const User* user) {
80   Profile* profile = UserManager::Get()->GetProfileByUser(user);
81   if (!profile) {
82     ADD_FAILURE();
83     return NULL;
84   }
85   policy::UserCloudPolicyManagerChromeOS* policy_manager =
86       policy::UserCloudPolicyManagerFactoryChromeOS::GetForProfile(profile);
87   if (!policy_manager) {
88     ADD_FAILURE();
89     return NULL;
90   }
91   return policy_manager->core()->store();
92 }
93
94 }  // namespace
95
96 class UserImageManagerTest : public LoginManagerTest,
97                              public UserManager::Observer {
98  protected:
99   UserImageManagerTest() : LoginManagerTest(true) {
100   }
101
102   // LoginManagerTest overrides:
103   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
104     LoginManagerTest::SetUpInProcessBrowserTestFixture();
105
106     ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_));
107     ASSERT_TRUE(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir_));
108   }
109
110   virtual void SetUpOnMainThread() OVERRIDE {
111     LoginManagerTest::SetUpOnMainThread();
112     local_state_ = g_browser_process->local_state();
113     UserManager::Get()->AddObserver(this);
114   }
115
116   virtual void TearDownOnMainThread() OVERRIDE {
117     UserManager::Get()->RemoveObserver(this);
118     LoginManagerTest::TearDownOnMainThread();
119   }
120
121   // UserManager::Observer overrides:
122   virtual void LocalStateChanged(UserManager* user_manager) OVERRIDE {
123     if (run_loop_)
124       run_loop_->Quit();
125   }
126
127   // Logs in |username|.
128   void LogIn(const std::string& username) {
129     UserManager::Get()->UserLoggedIn(username, username, false);
130   }
131
132   // Stores old (pre-migration) user image info.
133   void SetOldUserImageInfo(const std::string& username,
134                            int image_index,
135                            const base::FilePath& image_path) {
136     RegisterUser(username);
137     DictionaryPrefUpdate images_pref(local_state_, "UserImages");
138     base::DictionaryValue* image_properties = new base::DictionaryValue();
139     image_properties->Set(
140         "index", base::Value::CreateIntegerValue(image_index));
141     image_properties->Set(
142         "path" , new base::StringValue(image_path.value()));
143     images_pref->SetWithoutPathExpansion(username, image_properties);
144   }
145
146   // Verifies user image info in |images_pref| dictionary.
147   void ExpectUserImageInfo(const base::DictionaryValue* images_pref,
148                            const std::string& username,
149                            int image_index,
150                            const base::FilePath& image_path) {
151     ASSERT_TRUE(images_pref);
152     const base::DictionaryValue* image_properties = NULL;
153     images_pref->GetDictionaryWithoutPathExpansion(username, &image_properties);
154     ASSERT_TRUE(image_properties);
155     int actual_image_index;
156     std::string actual_image_path;
157     ASSERT_TRUE(image_properties->GetInteger("index", &actual_image_index) &&
158                 image_properties->GetString("path", &actual_image_path));
159     EXPECT_EQ(image_index, actual_image_index);
160     EXPECT_EQ(image_path.value(), actual_image_path);
161   }
162
163   // Verifies that there is no image info for |username| in dictionary
164   // |images_pref|.
165   void ExpectNoUserImageInfo(const base::DictionaryValue* images_pref,
166                              const std::string& username) {
167     ASSERT_TRUE(images_pref);
168     const base::DictionaryValue* image_properties = NULL;
169     images_pref->GetDictionaryWithoutPathExpansion(username, &image_properties);
170     ASSERT_FALSE(image_properties);
171   }
172
173   // Verifies that old user image info matches |image_index| and |image_path|
174   // and that new user image info does not exist.
175   void ExpectOldUserImageInfo(const std::string& username,
176                               int image_index,
177                               const base::FilePath& image_path) {
178     ExpectUserImageInfo(local_state_->GetDictionary("UserImages"),
179                         username, image_index, image_path);
180     ExpectNoUserImageInfo(local_state_->GetDictionary("user_image_info"),
181                           username);
182   }
183
184   // Verifies that new user image info matches |image_index| and |image_path|
185   // and that old user image info does not exist.
186   void ExpectNewUserImageInfo(const std::string& username,
187                               int image_index,
188                               const base::FilePath& image_path) {
189     ExpectUserImageInfo(local_state_->GetDictionary("user_image_info"),
190                         username, image_index, image_path);
191     ExpectNoUserImageInfo(local_state_->GetDictionary("UserImages"),
192                           username);
193   }
194
195   // Sets bitmap |resource_id| as image for |username| and saves it to disk.
196   void SaveUserImagePNG(const std::string& username,
197                         int resource_id) {
198     base::FilePath image_path = GetUserImagePath(username, "png");
199     scoped_refptr<base::RefCountedStaticMemory> image_data(
200         ResourceBundle::GetSharedInstance().LoadDataResourceBytesForScale(
201             resource_id, ui::SCALE_FACTOR_100P));
202     int written = base::WriteFile(
203         image_path,
204         reinterpret_cast<const char*>(image_data->front()),
205         image_data->size());
206     EXPECT_EQ(static_cast<int>(image_data->size()), written);
207     SetOldUserImageInfo(username, User::kExternalImageIndex, image_path);
208   }
209
210   // Returns the image path for user |username| with specified |extension|.
211   base::FilePath GetUserImagePath(const std::string& username,
212                                   const std::string& extension) {
213     return user_data_dir_.Append(username).AddExtension(extension);
214   }
215
216   // Completes the download of all non-image profile data for the user
217   // |username|.  This method must only be called after a profile data
218   // download has been started.  |url_fetcher_factory| will capture
219   // the net::TestURLFetcher created by the ProfileDownloader to
220   // download the profile image.
221   void CompleteProfileMetadataDownload(
222       const std::string& username,
223       net::TestURLFetcherFactory* url_fetcher_factory) {
224     ProfileDownloader* profile_downloader =
225         reinterpret_cast<UserImageManagerImpl*>(
226             UserManager::Get()->GetUserImageManager(username))->
227                 profile_downloader_.get();
228     ASSERT_TRUE(profile_downloader);
229
230     static_cast<OAuth2TokenService::Consumer*>(profile_downloader)->
231         OnGetTokenSuccess(NULL,
232                           std::string(),
233                           base::Time::Now() + base::TimeDelta::FromDays(1));
234
235     net::TestURLFetcher* fetcher = url_fetcher_factory->GetFetcherByID(0);
236     ASSERT_TRUE(fetcher);
237     fetcher->SetResponseString(
238         "{ \"picture\": \"http://localhost/avatar.jpg\" }");
239     fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
240                                               net::OK));
241     fetcher->set_response_code(200);
242     fetcher->delegate()->OnURLFetchComplete(fetcher);
243     base::RunLoop().RunUntilIdle();
244   }
245
246   // Completes the download of the currently logged-in user's profile image.
247   // This method must only be called after a profile data download including
248   // the profile image has been started, the download of all non-image data has
249   // been completed by calling CompleteProfileMetadataDownload() and the
250   // net::TestURLFetcher created by the ProfileDownloader to download the
251   // profile image has been captured by |url_fetcher_factory|.
252   void CompleteProfileImageDownload(
253       net::TestURLFetcherFactory* url_fetcher_factory) {
254     std::string profile_image_data;
255     base::FilePath test_data_dir;
256     ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir));
257     EXPECT_TRUE(ReadFileToString(
258         test_data_dir.Append("chromeos").Append("avatar1.jpg"),
259         &profile_image_data));
260
261     base::RunLoop run_loop;
262     PrefChangeRegistrar pref_change_registrar;
263     pref_change_registrar.Init(local_state_);
264     pref_change_registrar.Add("UserDisplayName", run_loop.QuitClosure());
265     net::TestURLFetcher* fetcher = url_fetcher_factory->GetFetcherByID(0);
266     ASSERT_TRUE(fetcher);
267     fetcher->SetResponseString(profile_image_data);
268     fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
269                                               net::OK));
270     fetcher->set_response_code(200);
271     fetcher->delegate()->OnURLFetchComplete(fetcher);
272     run_loop.Run();
273
274     const User* user = UserManager::Get()->GetLoggedInUser();
275     ASSERT_TRUE(user);
276     UserImageManagerImpl* uim = reinterpret_cast<UserImageManagerImpl*>(
277         UserManager::Get()->GetUserImageManager(user->email()));
278     if (uim->job_.get()) {
279       run_loop_.reset(new base::RunLoop);
280       run_loop_->Run();
281     }
282   }
283
284   base::FilePath test_data_dir_;
285   base::FilePath user_data_dir_;
286
287   PrefService* local_state_;
288
289   scoped_ptr<gfx::ImageSkia> decoded_image_;
290
291   scoped_ptr<base::RunLoop> run_loop_;
292
293  private:
294   DISALLOW_COPY_AND_ASSIGN(UserImageManagerTest);
295 };
296
297 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_DefaultUserImagePreserved) {
298   // Setup an old default (stock) user image.
299   ScopedUserManagerEnabler(new MockUserManager);
300   SetOldUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath());
301 }
302
303 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, DefaultUserImagePreserved) {
304   UserManager::Get()->GetUsers();  // Load users.
305   // Old info preserved.
306   ExpectOldUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath());
307   LogIn(kTestUser1);
308   // Image info is migrated now.
309   ExpectNewUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath());
310 }
311
312 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_OtherUsersUnaffected) {
313   // Setup two users with stock images.
314   ScopedUserManagerEnabler(new MockUserManager);
315   SetOldUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath());
316   SetOldUserImageInfo(kTestUser2, kFirstDefaultImageIndex + 1,
317                       base::FilePath());
318 }
319
320 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, OtherUsersUnaffected) {
321   UserManager::Get()->GetUsers();  // Load users.
322   // Old info preserved.
323   ExpectOldUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath());
324   ExpectOldUserImageInfo(kTestUser2, kFirstDefaultImageIndex + 1,
325                          base::FilePath());
326   LogIn(kTestUser1);
327   // Image info is migrated for the first user and unaffected for the rest.
328   ExpectNewUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath());
329   ExpectOldUserImageInfo(kTestUser2, kFirstDefaultImageIndex + 1,
330                          base::FilePath());
331 }
332
333 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_PRE_NonJPEGImageFromFile) {
334   // Setup a user with non-JPEG image.
335   ScopedUserManagerEnabler(new MockUserManager);
336   SaveUserImagePNG(
337       kTestUser1, kDefaultImageResourceIDs[kFirstDefaultImageIndex]);
338 }
339
340 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_NonJPEGImageFromFile) {
341   UserManager::Get()->GetUsers();  // Load users.
342   // Old info preserved.
343   ExpectOldUserImageInfo(kTestUser1, User::kExternalImageIndex,
344                          GetUserImagePath(kTestUser1, "png"));
345   const User* user = UserManager::Get()->FindUser(kTestUser1);
346   EXPECT_TRUE(user->image_is_stub());
347
348   base::RunLoop run_loop;
349   PrefChangeRegistrar pref_change_registrar_;
350   pref_change_registrar_.Init(local_state_);
351   pref_change_registrar_.Add("UserImages", run_loop.QuitClosure());
352   LogIn(kTestUser1);
353
354   // Wait for migration.
355   run_loop.Run();
356
357   // Image info is migrated and the image is converted to JPG.
358   ExpectNewUserImageInfo(kTestUser1, User::kExternalImageIndex,
359                          GetUserImagePath(kTestUser1, "jpg"));
360   user = UserManager::Get()->GetLoggedInUser();
361   ASSERT_TRUE(user);
362   EXPECT_FALSE(user->image_is_safe_format());
363   // Check image dimensions.
364   const gfx::ImageSkia& saved_image = GetDefaultImage(kFirstDefaultImageIndex);
365   EXPECT_EQ(saved_image.width(), user->image().width());
366   EXPECT_EQ(saved_image.height(), user->image().height());
367 }
368
369 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, NonJPEGImageFromFile) {
370   UserManager::Get()->GetUsers();  // Load users.
371   const User* user = UserManager::Get()->FindUser(kTestUser1);
372   ASSERT_TRUE(user);
373   // Wait for image load.
374   if (user->image_index() == User::kInvalidImageIndex) {
375     content::WindowedNotificationObserver(
376         chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED,
377         content::NotificationService::AllSources()).Wait();
378   }
379   // Now the migrated image is used.
380   EXPECT_TRUE(user->image_is_safe_format());
381   // Check image dimensions. Images can't be compared since JPEG is lossy.
382   const gfx::ImageSkia& saved_image = GetDefaultImage(kFirstDefaultImageIndex);
383   EXPECT_EQ(saved_image.width(), user->image().width());
384   EXPECT_EQ(saved_image.height(), user->image().height());
385 }
386
387 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_SaveUserDefaultImageIndex) {
388   RegisterUser(kTestUser1);
389 }
390
391 // Verifies that SaveUserDefaultImageIndex() correctly sets and persists the
392 // chosen user image.
393 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, SaveUserDefaultImageIndex) {
394   const User* user = UserManager::Get()->FindUser(kTestUser1);
395   ASSERT_TRUE(user);
396
397   const gfx::ImageSkia& default_image =
398       GetDefaultImage(kFirstDefaultImageIndex);
399
400   UserImageManager* user_image_manager =
401       UserManager::Get()->GetUserImageManager(kTestUser1);
402   user_image_manager->SaveUserDefaultImageIndex(kFirstDefaultImageIndex);
403
404   EXPECT_TRUE(user->HasDefaultImage());
405   EXPECT_EQ(kFirstDefaultImageIndex, user->image_index());
406   EXPECT_TRUE(test::AreImagesEqual(default_image, user->image()));
407   ExpectNewUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath());
408 }
409
410 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_SaveUserImage) {
411   RegisterUser(kTestUser1);
412 }
413
414 // Verifies that SaveUserImage() correctly sets and persists the chosen user
415 // image.
416 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, SaveUserImage) {
417   const User* user = UserManager::Get()->FindUser(kTestUser1);
418   ASSERT_TRUE(user);
419
420   SkBitmap custom_image_bitmap;
421   custom_image_bitmap.setConfig(SkBitmap::kARGB_8888_Config, 10, 10);
422   custom_image_bitmap.allocPixels();
423   custom_image_bitmap.setImmutable();
424   const gfx::ImageSkia custom_image =
425       gfx::ImageSkia::CreateFrom1xBitmap(custom_image_bitmap);
426
427   run_loop_.reset(new base::RunLoop);
428   UserImageManager* user_image_manager =
429       UserManager::Get()->GetUserImageManager(kTestUser1);
430   user_image_manager->SaveUserImage(UserImage::CreateAndEncode(custom_image));
431   run_loop_->Run();
432
433   EXPECT_FALSE(user->HasDefaultImage());
434   EXPECT_EQ(User::kExternalImageIndex, user->image_index());
435   EXPECT_TRUE(test::AreImagesEqual(custom_image, user->image()));
436   ExpectNewUserImageInfo(kTestUser1,
437                          User::kExternalImageIndex,
438                          GetUserImagePath(kTestUser1, "jpg"));
439
440   const scoped_ptr<gfx::ImageSkia> saved_image =
441       test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load();
442   ASSERT_TRUE(saved_image);
443
444   // Check image dimensions. Images can't be compared since JPEG is lossy.
445   EXPECT_EQ(custom_image.width(), saved_image->width());
446   EXPECT_EQ(custom_image.height(), saved_image->height());
447 }
448
449 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_SaveUserImageFromFile) {
450   RegisterUser(kTestUser1);
451 }
452
453 // Verifies that SaveUserImageFromFile() correctly sets and persists the chosen
454 // user image.
455 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, SaveUserImageFromFile) {
456   const User* user = UserManager::Get()->FindUser(kTestUser1);
457   ASSERT_TRUE(user);
458
459   const base::FilePath custom_image_path =
460       test_data_dir_.Append(test::kUserAvatarImage1RelativePath);
461   const scoped_ptr<gfx::ImageSkia> custom_image =
462       test::ImageLoader(custom_image_path).Load();
463   ASSERT_TRUE(custom_image);
464
465   run_loop_.reset(new base::RunLoop);
466   UserImageManager* user_image_manager =
467       UserManager::Get()->GetUserImageManager(kTestUser1);
468   user_image_manager->SaveUserImageFromFile(custom_image_path);
469   run_loop_->Run();
470
471   EXPECT_FALSE(user->HasDefaultImage());
472   EXPECT_EQ(User::kExternalImageIndex, user->image_index());
473   EXPECT_TRUE(test::AreImagesEqual(*custom_image, user->image()));
474   ExpectNewUserImageInfo(kTestUser1,
475                          User::kExternalImageIndex,
476                          GetUserImagePath(kTestUser1, "jpg"));
477
478   const scoped_ptr<gfx::ImageSkia> saved_image =
479       test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load();
480   ASSERT_TRUE(saved_image);
481
482   // Check image dimensions. Images can't be compared since JPEG is lossy.
483   EXPECT_EQ(custom_image->width(), saved_image->width());
484   EXPECT_EQ(custom_image->height(), saved_image->height());
485 }
486
487 IN_PROC_BROWSER_TEST_F(UserImageManagerTest,
488                        PRE_SaveUserImageFromProfileImage) {
489   RegisterUser(kTestUser1);
490   chromeos::StartupUtils::MarkOobeCompleted();
491 }
492
493 // Verifies that SaveUserImageFromProfileImage() correctly downloads, sets and
494 // persists the chosen user image.
495 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, SaveUserImageFromProfileImage) {
496   const User* user = UserManager::Get()->FindUser(kTestUser1);
497   ASSERT_TRUE(user);
498
499   UserImageManagerImpl::IgnoreProfileDataDownloadDelayForTesting();
500   LoginUser(kTestUser1);
501
502   run_loop_.reset(new base::RunLoop);
503   UserImageManager* user_image_manager =
504       UserManager::Get()->GetUserImageManager(kTestUser1);
505   user_image_manager->SaveUserImageFromProfileImage();
506   run_loop_->Run();
507
508   net::TestURLFetcherFactory url_fetcher_factory;
509   CompleteProfileMetadataDownload(kTestUser1, &url_fetcher_factory);
510   CompleteProfileImageDownload(&url_fetcher_factory);
511
512   const gfx::ImageSkia& profile_image =
513       user_image_manager->DownloadedProfileImage();
514
515   EXPECT_FALSE(user->HasDefaultImage());
516   EXPECT_EQ(User::kProfileImageIndex, user->image_index());
517   EXPECT_TRUE(test::AreImagesEqual(profile_image, user->image()));
518   ExpectNewUserImageInfo(kTestUser1,
519                          User::kProfileImageIndex,
520                          GetUserImagePath(kTestUser1, "jpg"));
521
522   const scoped_ptr<gfx::ImageSkia> saved_image =
523       test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load();
524   ASSERT_TRUE(saved_image);
525
526   // Check image dimensions. Images can't be compared since JPEG is lossy.
527   EXPECT_EQ(profile_image.width(), saved_image->width());
528   EXPECT_EQ(profile_image.height(), saved_image->height());
529 }
530
531 IN_PROC_BROWSER_TEST_F(UserImageManagerTest,
532                        PRE_ProfileImageDownloadDoesNotClobber) {
533   RegisterUser(kTestUser1);
534   chromeos::StartupUtils::MarkOobeCompleted();
535 }
536
537 // Sets the user image to the profile image, then sets it to one of the default
538 // images while the profile image download is still in progress. Verifies that
539 // when the download completes, the profile image is ignored and does not
540 // clobber the default image chosen in the meantime.
541 IN_PROC_BROWSER_TEST_F(UserImageManagerTest,
542                        ProfileImageDownloadDoesNotClobber) {
543   const User* user = UserManager::Get()->FindUser(kTestUser1);
544   ASSERT_TRUE(user);
545
546   const gfx::ImageSkia& default_image =
547       GetDefaultImage(kFirstDefaultImageIndex);
548
549   UserImageManagerImpl::IgnoreProfileDataDownloadDelayForTesting();
550   LoginUser(kTestUser1);
551
552   run_loop_.reset(new base::RunLoop);
553   UserImageManager* user_image_manager =
554       UserManager::Get()->GetUserImageManager(kTestUser1);
555   user_image_manager->SaveUserImageFromProfileImage();
556   run_loop_->Run();
557
558   net::TestURLFetcherFactory url_fetcher_factory;
559   CompleteProfileMetadataDownload(kTestUser1, &url_fetcher_factory);
560
561   user_image_manager->SaveUserDefaultImageIndex(kFirstDefaultImageIndex);
562
563   CompleteProfileImageDownload(&url_fetcher_factory);
564
565   EXPECT_TRUE(user->HasDefaultImage());
566   EXPECT_EQ(kFirstDefaultImageIndex, user->image_index());
567   EXPECT_TRUE(test::AreImagesEqual(default_image, user->image()));
568   ExpectNewUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath());
569 }
570
571 class UserImageManagerPolicyTest : public UserImageManagerTest,
572                                    public policy::CloudPolicyStore::Observer {
573  protected:
574   UserImageManagerPolicyTest()
575       : fake_dbus_thread_manager_(new chromeos::FakeDBusThreadManager),
576         fake_session_manager_client_(new chromeos::FakeSessionManagerClient) {
577     fake_dbus_thread_manager_->SetFakeClients();
578     fake_dbus_thread_manager_->SetSessionManagerClient(
579         scoped_ptr<SessionManagerClient>(fake_session_manager_client_));
580   }
581
582   // UserImageManagerTest overrides:
583   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
584     DBusThreadManager::SetInstanceForTesting(fake_dbus_thread_manager_);
585     UserImageManagerTest::SetUpInProcessBrowserTestFixture();
586   }
587
588   virtual void SetUpOnMainThread() OVERRIDE {
589     UserImageManagerTest::SetUpOnMainThread();
590
591     base::FilePath user_keys_dir;
592     ASSERT_TRUE(PathService::Get(chromeos::DIR_USER_POLICY_KEYS,
593                                  &user_keys_dir));
594     const std::string sanitized_username =
595         chromeos::CryptohomeClient::GetStubSanitizedUsername(kTestUser1);
596     const base::FilePath user_key_file =
597         user_keys_dir.AppendASCII(sanitized_username)
598                      .AppendASCII("policy.pub");
599     std::vector<uint8> user_key_bits;
600     ASSERT_TRUE(user_policy_.GetSigningKey()->ExportPublicKey(&user_key_bits));
601     ASSERT_TRUE(base::CreateDirectory(user_key_file.DirName()));
602     ASSERT_EQ(base::WriteFile(
603                   user_key_file,
604                   reinterpret_cast<const char*>(user_key_bits.data()),
605                   user_key_bits.size()),
606               static_cast<int>(user_key_bits.size()));
607     user_policy_.policy_data().set_username(kTestUser1);
608
609     ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
610
611     policy_image_ = test::ImageLoader(test_data_dir_.Append(
612         test::kUserAvatarImage2RelativePath)).Load();
613     ASSERT_TRUE(policy_image_);
614   }
615
616   // policy::CloudPolicyStore::Observer overrides:
617   virtual void OnStoreLoaded(policy::CloudPolicyStore* store) OVERRIDE {
618     if (run_loop_)
619       run_loop_->Quit();
620   }
621
622   virtual void OnStoreError(policy::CloudPolicyStore* store) OVERRIDE {
623     if (run_loop_)
624       run_loop_->Quit();
625   }
626
627   std::string ConstructPolicy(const std::string& relative_path) {
628     std::string image_data;
629     if (!base::ReadFileToString(test_data_dir_.Append(relative_path),
630                                 &image_data)) {
631       ADD_FAILURE();
632     }
633     std::string policy;
634     base::JSONWriter::Write(policy::test::ConstructExternalDataReference(
635         embedded_test_server()->GetURL(std::string("/") + relative_path).spec(),
636         image_data).get(),
637         &policy);
638     return policy;
639   }
640
641   policy::UserPolicyBuilder user_policy_;
642   FakeDBusThreadManager* fake_dbus_thread_manager_;
643   FakeSessionManagerClient* fake_session_manager_client_;
644
645   scoped_ptr<gfx::ImageSkia> policy_image_;
646
647  private:
648   DISALLOW_COPY_AND_ASSIGN(UserImageManagerPolicyTest);
649 };
650
651 IN_PROC_BROWSER_TEST_F(UserImageManagerPolicyTest, PRE_SetAndClear) {
652   RegisterUser(kTestUser1);
653   chromeos::StartupUtils::MarkOobeCompleted();
654 }
655
656 // Verifies that the user image can be set through policy. Also verifies that
657 // after the policy has been cleared, the user is able to choose a different
658 // image.
659 IN_PROC_BROWSER_TEST_F(UserImageManagerPolicyTest, SetAndClear) {
660   const User* user = UserManager::Get()->FindUser(kTestUser1);
661   ASSERT_TRUE(user);
662
663   LoginUser(kTestUser1);
664   base::RunLoop().RunUntilIdle();
665
666   policy::CloudPolicyStore* store = GetStoreForUser(user);
667   ASSERT_TRUE(store);
668
669   // Set policy. Verify that the policy-provided user image is downloaded, set
670   // and persisted.
671   user_policy_.payload().mutable_useravatarimage()->set_value(
672       ConstructPolicy(test::kUserAvatarImage2RelativePath));
673   user_policy_.Build();
674   fake_session_manager_client_->set_user_policy(kTestUser1,
675                                                 user_policy_.GetBlob());
676   run_loop_.reset(new base::RunLoop);
677   store->Load();
678   run_loop_->Run();
679
680   EXPECT_FALSE(user->HasDefaultImage());
681   EXPECT_EQ(User::kExternalImageIndex, user->image_index());
682   EXPECT_TRUE(test::AreImagesEqual(*policy_image_, user->image()));
683   ExpectNewUserImageInfo(kTestUser1,
684                          User::kExternalImageIndex,
685                          GetUserImagePath(kTestUser1, "jpg"));
686
687   scoped_ptr<gfx::ImageSkia> saved_image =
688       test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load();
689   ASSERT_TRUE(saved_image);
690
691   // Check image dimensions. Images can't be compared since JPEG is lossy.
692   EXPECT_EQ(policy_image_->width(), saved_image->width());
693   EXPECT_EQ(policy_image_->height(), saved_image->height());
694
695   // Clear policy. Verify that the policy-provided user image remains set as no
696   // different user image has been chosen yet.
697   user_policy_.payload().Clear();
698   user_policy_.Build();
699   fake_session_manager_client_->set_user_policy(kTestUser1,
700                                                 user_policy_.GetBlob());
701   run_loop_.reset(new base::RunLoop);
702   store->AddObserver(this);
703   store->Load();
704   run_loop_->Run();
705   store->RemoveObserver(this);
706   base::RunLoop().RunUntilIdle();
707
708   EXPECT_FALSE(user->HasDefaultImage());
709   EXPECT_EQ(User::kExternalImageIndex, user->image_index());
710   EXPECT_TRUE(test::AreImagesEqual(*policy_image_, user->image()));
711   ExpectNewUserImageInfo(kTestUser1,
712                          User::kExternalImageIndex,
713                          GetUserImagePath(kTestUser1, "jpg"));
714
715   saved_image = test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load();
716   ASSERT_TRUE(saved_image);
717
718   // Check image dimensions. Images can't be compared since JPEG is lossy.
719   EXPECT_EQ(policy_image_->width(), saved_image->width());
720   EXPECT_EQ(policy_image_->height(), saved_image->height());
721
722   // Choose a different user image. Verify that the chosen user image is set and
723   // persisted.
724   const gfx::ImageSkia& default_image =
725       GetDefaultImage(kFirstDefaultImageIndex);
726
727   UserImageManager* user_image_manager =
728       UserManager::Get()->GetUserImageManager(kTestUser1);
729   user_image_manager->SaveUserDefaultImageIndex(kFirstDefaultImageIndex);
730
731   EXPECT_TRUE(user->HasDefaultImage());
732   EXPECT_EQ(kFirstDefaultImageIndex, user->image_index());
733   EXPECT_TRUE(test::AreImagesEqual(default_image, user->image()));
734   ExpectNewUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath());
735 }
736
737 IN_PROC_BROWSER_TEST_F(UserImageManagerPolicyTest, PRE_PolicyOverridesUser) {
738   RegisterUser(kTestUser1);
739   chromeos::StartupUtils::MarkOobeCompleted();
740 }
741
742 // Verifies that when the user chooses a user image and a different image is
743 // then set through policy, the policy takes precedence, overriding the
744 // previously chosen image.
745 IN_PROC_BROWSER_TEST_F(UserImageManagerPolicyTest, PolicyOverridesUser) {
746   const User* user = UserManager::Get()->FindUser(kTestUser1);
747   ASSERT_TRUE(user);
748
749   LoginUser(kTestUser1);
750   base::RunLoop().RunUntilIdle();
751
752   policy::CloudPolicyStore* store = GetStoreForUser(user);
753   ASSERT_TRUE(store);
754
755   // Choose a user image. Verify that the chosen user image is set and
756   // persisted.
757   const gfx::ImageSkia& default_image =
758       GetDefaultImage(kFirstDefaultImageIndex);
759
760   UserImageManager* user_image_manager =
761       UserManager::Get()->GetUserImageManager(kTestUser1);
762   user_image_manager->SaveUserDefaultImageIndex(kFirstDefaultImageIndex);
763
764   EXPECT_TRUE(user->HasDefaultImage());
765   EXPECT_EQ(kFirstDefaultImageIndex, user->image_index());
766   EXPECT_TRUE(test::AreImagesEqual(default_image, user->image()));
767   ExpectNewUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath());
768
769   // Set policy. Verify that the policy-provided user image is downloaded, set
770   // and persisted, overriding the previously set image.
771   user_policy_.payload().mutable_useravatarimage()->set_value(
772       ConstructPolicy(test::kUserAvatarImage2RelativePath));
773   user_policy_.Build();
774   fake_session_manager_client_->set_user_policy(kTestUser1,
775                                                 user_policy_.GetBlob());
776   run_loop_.reset(new base::RunLoop);
777   store->Load();
778   run_loop_->Run();
779
780   EXPECT_FALSE(user->HasDefaultImage());
781   EXPECT_EQ(User::kExternalImageIndex, user->image_index());
782   EXPECT_TRUE(test::AreImagesEqual(*policy_image_, user->image()));
783   ExpectNewUserImageInfo(kTestUser1,
784                          User::kExternalImageIndex,
785                          GetUserImagePath(kTestUser1, "jpg"));
786
787   scoped_ptr<gfx::ImageSkia> saved_image =
788       test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load();
789   ASSERT_TRUE(saved_image);
790
791   // Check image dimensions. Images can't be compared since JPEG is lossy.
792   EXPECT_EQ(policy_image_->width(), saved_image->width());
793   EXPECT_EQ(policy_image_->height(), saved_image->height());
794 }
795
796 IN_PROC_BROWSER_TEST_F(UserImageManagerPolicyTest,
797                        PRE_UserDoesNotOverridePolicy) {
798   RegisterUser(kTestUser1);
799   chromeos::StartupUtils::MarkOobeCompleted();
800 }
801
802 // Verifies that when the user image has been set through policy and the user
803 // chooses a different image, the policy takes precedence, preventing the user
804 // from overriding the previously chosen image.
805 IN_PROC_BROWSER_TEST_F(UserImageManagerPolicyTest, UserDoesNotOverridePolicy) {
806   const User* user = UserManager::Get()->FindUser(kTestUser1);
807   ASSERT_TRUE(user);
808
809   LoginUser(kTestUser1);
810   base::RunLoop().RunUntilIdle();
811
812   policy::CloudPolicyStore* store = GetStoreForUser(user);
813   ASSERT_TRUE(store);
814
815   // Set policy. Verify that the policy-provided user image is downloaded, set
816   // and persisted.
817   user_policy_.payload().mutable_useravatarimage()->set_value(
818       ConstructPolicy(test::kUserAvatarImage2RelativePath));
819   user_policy_.Build();
820   fake_session_manager_client_->set_user_policy(kTestUser1,
821                                                 user_policy_.GetBlob());
822   run_loop_.reset(new base::RunLoop);
823   store->Load();
824   run_loop_->Run();
825
826   EXPECT_FALSE(user->HasDefaultImage());
827   EXPECT_EQ(User::kExternalImageIndex, user->image_index());
828   EXPECT_TRUE(test::AreImagesEqual(*policy_image_, user->image()));
829   ExpectNewUserImageInfo(kTestUser1,
830                          User::kExternalImageIndex,
831                          GetUserImagePath(kTestUser1, "jpg"));
832
833   scoped_ptr<gfx::ImageSkia> saved_image =
834       test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load();
835   ASSERT_TRUE(saved_image);
836
837   // Check image dimensions. Images can't be compared since JPEG is lossy.
838   EXPECT_EQ(policy_image_->width(), saved_image->width());
839   EXPECT_EQ(policy_image_->height(), saved_image->height());
840
841   // Choose a different user image. Verify that the user image does not change
842   // as policy takes precedence.
843   UserImageManager* user_image_manager =
844       UserManager::Get()->GetUserImageManager(kTestUser1);
845   user_image_manager->SaveUserDefaultImageIndex(kFirstDefaultImageIndex);
846
847   EXPECT_FALSE(user->HasDefaultImage());
848   EXPECT_EQ(User::kExternalImageIndex, user->image_index());
849   EXPECT_TRUE(test::AreImagesEqual(*policy_image_, user->image()));
850   ExpectNewUserImageInfo(kTestUser1,
851                          User::kExternalImageIndex,
852                          GetUserImagePath(kTestUser1, "jpg"));
853
854   saved_image = test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load();
855   ASSERT_TRUE(saved_image);
856
857   // Check image dimensions. Images can't be compared since JPEG is lossy.
858   EXPECT_EQ(policy_image_->width(), saved_image->width());
859   EXPECT_EQ(policy_image_->height(), saved_image->height());
860 }
861
862 }  // namespace chromeos