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