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