user_image_manager_browsertest.cc revision 46d4c2bc3267f3f028f39e7e311b0f89aba2e4fd
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 73namespace chromeos { 74 75namespace { 76 77const char kTestUser1[] = "test-user@example.com"; 78const char kTestUser2[] = "test-user2@example.com"; 79 80policy::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 97class 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 "token", 234 base::Time::Now() + base::TimeDelta::FromDays(1)); 235 236 net::TestURLFetcher* fetcher = 237 url_fetcher_factory->GetFetcherByID( 238 gaia::GaiaOAuthClient::kUrlFetcherId); 239 ASSERT_TRUE(fetcher); 240 fetcher->SetResponseString( 241 "{ \"image\": {\"url\": \"http://localhost/avatar.jpg\"} }"); 242 fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 243 net::OK)); 244 fetcher->set_response_code(200); 245 fetcher->delegate()->OnURLFetchComplete(fetcher); 246 base::RunLoop().RunUntilIdle(); 247 } 248 249 // Completes the download of the currently logged-in user's profile image. 250 // This method must only be called after a profile data download including 251 // the profile image has been started, the download of all non-image data has 252 // been completed by calling CompleteProfileMetadataDownload() and the 253 // net::TestURLFetcher created by the ProfileDownloader to download the 254 // profile image has been captured by |url_fetcher_factory|. 255 void CompleteProfileImageDownload( 256 net::TestURLFetcherFactory* url_fetcher_factory) { 257 std::string profile_image_data; 258 base::FilePath test_data_dir; 259 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir)); 260 EXPECT_TRUE(ReadFileToString( 261 test_data_dir.Append("chromeos").Append("avatar1.jpg"), 262 &profile_image_data)); 263 264 base::RunLoop run_loop; 265 PrefChangeRegistrar pref_change_registrar; 266 pref_change_registrar.Init(local_state_); 267 pref_change_registrar.Add("UserDisplayName", run_loop.QuitClosure()); 268 net::TestURLFetcher* fetcher = url_fetcher_factory->GetFetcherByID(0); 269 ASSERT_TRUE(fetcher); 270 fetcher->SetResponseString(profile_image_data); 271 fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 272 net::OK)); 273 fetcher->set_response_code(200); 274 fetcher->delegate()->OnURLFetchComplete(fetcher); 275 run_loop.Run(); 276 277 const User* user = UserManager::Get()->GetLoggedInUser(); 278 ASSERT_TRUE(user); 279 UserImageManagerImpl* uim = reinterpret_cast<UserImageManagerImpl*>( 280 UserManager::Get()->GetUserImageManager(user->email())); 281 if (uim->job_.get()) { 282 run_loop_.reset(new base::RunLoop); 283 run_loop_->Run(); 284 } 285 } 286 287 base::FilePath test_data_dir_; 288 base::FilePath user_data_dir_; 289 290 PrefService* local_state_; 291 292 scoped_ptr<gfx::ImageSkia> decoded_image_; 293 294 scoped_ptr<base::RunLoop> run_loop_; 295 296 private: 297 DISALLOW_COPY_AND_ASSIGN(UserImageManagerTest); 298}; 299 300IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_DefaultUserImagePreserved) { 301 // Setup an old default (stock) user image. 302 ScopedUserManagerEnabler(new MockUserManager); 303 SetOldUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath()); 304} 305 306IN_PROC_BROWSER_TEST_F(UserImageManagerTest, DefaultUserImagePreserved) { 307 UserManager::Get()->GetUsers(); // Load users. 308 // Old info preserved. 309 ExpectOldUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath()); 310 LogIn(kTestUser1); 311 // Image info is migrated now. 312 ExpectNewUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath()); 313} 314 315IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_OtherUsersUnaffected) { 316 // Setup two users with stock images. 317 ScopedUserManagerEnabler(new MockUserManager); 318 SetOldUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath()); 319 SetOldUserImageInfo(kTestUser2, kFirstDefaultImageIndex + 1, 320 base::FilePath()); 321} 322 323IN_PROC_BROWSER_TEST_F(UserImageManagerTest, OtherUsersUnaffected) { 324 UserManager::Get()->GetUsers(); // Load users. 325 // Old info preserved. 326 ExpectOldUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath()); 327 ExpectOldUserImageInfo(kTestUser2, kFirstDefaultImageIndex + 1, 328 base::FilePath()); 329 LogIn(kTestUser1); 330 // Image info is migrated for the first user and unaffected for the rest. 331 ExpectNewUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath()); 332 ExpectOldUserImageInfo(kTestUser2, kFirstDefaultImageIndex + 1, 333 base::FilePath()); 334} 335 336IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_PRE_NonJPEGImageFromFile) { 337 // Setup a user with non-JPEG image. 338 ScopedUserManagerEnabler(new MockUserManager); 339 SaveUserImagePNG( 340 kTestUser1, kDefaultImageResourceIDs[kFirstDefaultImageIndex]); 341} 342 343IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_NonJPEGImageFromFile) { 344 UserManager::Get()->GetUsers(); // Load users. 345 // Old info preserved. 346 ExpectOldUserImageInfo(kTestUser1, User::kExternalImageIndex, 347 GetUserImagePath(kTestUser1, "png")); 348 const User* user = UserManager::Get()->FindUser(kTestUser1); 349 EXPECT_TRUE(user->image_is_stub()); 350 351 base::RunLoop run_loop; 352 PrefChangeRegistrar pref_change_registrar_; 353 pref_change_registrar_.Init(local_state_); 354 pref_change_registrar_.Add("UserImages", run_loop.QuitClosure()); 355 LogIn(kTestUser1); 356 357 // Wait for migration. 358 run_loop.Run(); 359 360 // Image info is migrated and the image is converted to JPG. 361 ExpectNewUserImageInfo(kTestUser1, User::kExternalImageIndex, 362 GetUserImagePath(kTestUser1, "jpg")); 363 user = UserManager::Get()->GetLoggedInUser(); 364 ASSERT_TRUE(user); 365 EXPECT_FALSE(user->image_is_safe_format()); 366 // Check image dimensions. 367 const gfx::ImageSkia& saved_image = GetDefaultImage(kFirstDefaultImageIndex); 368 EXPECT_EQ(saved_image.width(), user->GetImage().width()); 369 EXPECT_EQ(saved_image.height(), user->GetImage().height()); 370} 371 372IN_PROC_BROWSER_TEST_F(UserImageManagerTest, NonJPEGImageFromFile) { 373 UserManager::Get()->GetUsers(); // Load users. 374 const User* user = UserManager::Get()->FindUser(kTestUser1); 375 ASSERT_TRUE(user); 376 // Wait for image load. 377 if (user->image_index() == User::kInvalidImageIndex) { 378 content::WindowedNotificationObserver( 379 chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED, 380 content::NotificationService::AllSources()).Wait(); 381 } 382 // Now the migrated image is used. 383 EXPECT_TRUE(user->image_is_safe_format()); 384 // Check image dimensions. Images can't be compared since JPEG is lossy. 385 const gfx::ImageSkia& saved_image = GetDefaultImage(kFirstDefaultImageIndex); 386 EXPECT_EQ(saved_image.width(), user->GetImage().width()); 387 EXPECT_EQ(saved_image.height(), user->GetImage().height()); 388} 389 390IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_SaveUserDefaultImageIndex) { 391 RegisterUser(kTestUser1); 392} 393 394// Verifies that SaveUserDefaultImageIndex() correctly sets and persists the 395// chosen user image. 396IN_PROC_BROWSER_TEST_F(UserImageManagerTest, SaveUserDefaultImageIndex) { 397 const User* user = UserManager::Get()->FindUser(kTestUser1); 398 ASSERT_TRUE(user); 399 400 const gfx::ImageSkia& default_image = 401 GetDefaultImage(kFirstDefaultImageIndex); 402 403 UserImageManager* user_image_manager = 404 UserManager::Get()->GetUserImageManager(kTestUser1); 405 user_image_manager->SaveUserDefaultImageIndex(kFirstDefaultImageIndex); 406 407 EXPECT_TRUE(user->HasDefaultImage()); 408 EXPECT_EQ(kFirstDefaultImageIndex, user->image_index()); 409 EXPECT_TRUE(test::AreImagesEqual(default_image, user->GetImage())); 410 ExpectNewUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath()); 411} 412 413IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_SaveUserImage) { 414 RegisterUser(kTestUser1); 415} 416 417// Verifies that SaveUserImage() correctly sets and persists the chosen user 418// image. 419IN_PROC_BROWSER_TEST_F(UserImageManagerTest, SaveUserImage) { 420 const User* user = UserManager::Get()->FindUser(kTestUser1); 421 ASSERT_TRUE(user); 422 423 SkBitmap custom_image_bitmap; 424 custom_image_bitmap.setConfig(SkBitmap::kARGB_8888_Config, 10, 10); 425 custom_image_bitmap.allocPixels(); 426 custom_image_bitmap.setImmutable(); 427 const gfx::ImageSkia custom_image = 428 gfx::ImageSkia::CreateFrom1xBitmap(custom_image_bitmap); 429 430 run_loop_.reset(new base::RunLoop); 431 UserImageManager* user_image_manager = 432 UserManager::Get()->GetUserImageManager(kTestUser1); 433 user_image_manager->SaveUserImage(UserImage::CreateAndEncode(custom_image)); 434 run_loop_->Run(); 435 436 EXPECT_FALSE(user->HasDefaultImage()); 437 EXPECT_EQ(User::kExternalImageIndex, user->image_index()); 438 EXPECT_TRUE(test::AreImagesEqual(custom_image, user->GetImage())); 439 ExpectNewUserImageInfo(kTestUser1, 440 User::kExternalImageIndex, 441 GetUserImagePath(kTestUser1, "jpg")); 442 443 const scoped_ptr<gfx::ImageSkia> saved_image = 444 test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load(); 445 ASSERT_TRUE(saved_image); 446 447 // Check image dimensions. Images can't be compared since JPEG is lossy. 448 EXPECT_EQ(custom_image.width(), saved_image->width()); 449 EXPECT_EQ(custom_image.height(), saved_image->height()); 450} 451 452IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_SaveUserImageFromFile) { 453 RegisterUser(kTestUser1); 454} 455 456// Verifies that SaveUserImageFromFile() correctly sets and persists the chosen 457// user image. 458IN_PROC_BROWSER_TEST_F(UserImageManagerTest, SaveUserImageFromFile) { 459 const User* user = UserManager::Get()->FindUser(kTestUser1); 460 ASSERT_TRUE(user); 461 462 const base::FilePath custom_image_path = 463 test_data_dir_.Append(test::kUserAvatarImage1RelativePath); 464 const scoped_ptr<gfx::ImageSkia> custom_image = 465 test::ImageLoader(custom_image_path).Load(); 466 ASSERT_TRUE(custom_image); 467 468 run_loop_.reset(new base::RunLoop); 469 UserImageManager* user_image_manager = 470 UserManager::Get()->GetUserImageManager(kTestUser1); 471 user_image_manager->SaveUserImageFromFile(custom_image_path); 472 run_loop_->Run(); 473 474 EXPECT_FALSE(user->HasDefaultImage()); 475 EXPECT_EQ(User::kExternalImageIndex, user->image_index()); 476 EXPECT_TRUE(test::AreImagesEqual(*custom_image, user->GetImage())); 477 ExpectNewUserImageInfo(kTestUser1, 478 User::kExternalImageIndex, 479 GetUserImagePath(kTestUser1, "jpg")); 480 481 const scoped_ptr<gfx::ImageSkia> saved_image = 482 test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load(); 483 ASSERT_TRUE(saved_image); 484 485 // Check image dimensions. Images can't be compared since JPEG is lossy. 486 EXPECT_EQ(custom_image->width(), saved_image->width()); 487 EXPECT_EQ(custom_image->height(), saved_image->height()); 488} 489 490IN_PROC_BROWSER_TEST_F(UserImageManagerTest, 491 PRE_SaveUserImageFromProfileImage) { 492 RegisterUser(kTestUser1); 493 chromeos::StartupUtils::MarkOobeCompleted(); 494} 495 496// Verifies that SaveUserImageFromProfileImage() correctly downloads, sets and 497// persists the chosen user image. 498IN_PROC_BROWSER_TEST_F(UserImageManagerTest, SaveUserImageFromProfileImage) { 499 const User* user = UserManager::Get()->FindUser(kTestUser1); 500 ASSERT_TRUE(user); 501 502 UserImageManagerImpl::IgnoreProfileDataDownloadDelayForTesting(); 503 LoginUser(kTestUser1); 504 505 run_loop_.reset(new base::RunLoop); 506 UserImageManager* user_image_manager = 507 UserManager::Get()->GetUserImageManager(kTestUser1); 508 user_image_manager->SaveUserImageFromProfileImage(); 509 run_loop_->Run(); 510 511 net::TestURLFetcherFactory url_fetcher_factory; 512 CompleteProfileMetadataDownload(kTestUser1, &url_fetcher_factory); 513 CompleteProfileImageDownload(&url_fetcher_factory); 514 515 const gfx::ImageSkia& profile_image = 516 user_image_manager->DownloadedProfileImage(); 517 518 EXPECT_FALSE(user->HasDefaultImage()); 519 EXPECT_EQ(User::kProfileImageIndex, user->image_index()); 520 EXPECT_TRUE(test::AreImagesEqual(profile_image, user->GetImage())); 521 ExpectNewUserImageInfo(kTestUser1, 522 User::kProfileImageIndex, 523 GetUserImagePath(kTestUser1, "jpg")); 524 525 const scoped_ptr<gfx::ImageSkia> saved_image = 526 test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load(); 527 ASSERT_TRUE(saved_image); 528 529 // Check image dimensions. Images can't be compared since JPEG is lossy. 530 EXPECT_EQ(profile_image.width(), saved_image->width()); 531 EXPECT_EQ(profile_image.height(), saved_image->height()); 532} 533 534IN_PROC_BROWSER_TEST_F(UserImageManagerTest, 535 PRE_ProfileImageDownloadDoesNotClobber) { 536 RegisterUser(kTestUser1); 537 chromeos::StartupUtils::MarkOobeCompleted(); 538} 539 540// Sets the user image to the profile image, then sets it to one of the default 541// images while the profile image download is still in progress. Verifies that 542// when the download completes, the profile image is ignored and does not 543// clobber the default image chosen in the meantime. 544IN_PROC_BROWSER_TEST_F(UserImageManagerTest, 545 ProfileImageDownloadDoesNotClobber) { 546 const User* user = UserManager::Get()->FindUser(kTestUser1); 547 ASSERT_TRUE(user); 548 549 const gfx::ImageSkia& default_image = 550 GetDefaultImage(kFirstDefaultImageIndex); 551 552 UserImageManagerImpl::IgnoreProfileDataDownloadDelayForTesting(); 553 LoginUser(kTestUser1); 554 555 run_loop_.reset(new base::RunLoop); 556 UserImageManager* user_image_manager = 557 UserManager::Get()->GetUserImageManager(kTestUser1); 558 user_image_manager->SaveUserImageFromProfileImage(); 559 run_loop_->Run(); 560 561 net::TestURLFetcherFactory url_fetcher_factory; 562 CompleteProfileMetadataDownload(kTestUser1, &url_fetcher_factory); 563 564 user_image_manager->SaveUserDefaultImageIndex(kFirstDefaultImageIndex); 565 566 CompleteProfileImageDownload(&url_fetcher_factory); 567 568 EXPECT_TRUE(user->HasDefaultImage()); 569 EXPECT_EQ(kFirstDefaultImageIndex, user->image_index()); 570 EXPECT_TRUE(test::AreImagesEqual(default_image, user->GetImage())); 571 ExpectNewUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath()); 572} 573 574class UserImageManagerPolicyTest : public UserImageManagerTest, 575 public policy::CloudPolicyStore::Observer { 576 protected: 577 UserImageManagerPolicyTest() 578 : fake_dbus_thread_manager_(new chromeos::FakeDBusThreadManager), 579 fake_session_manager_client_(new chromeos::FakeSessionManagerClient) { 580 fake_dbus_thread_manager_->SetFakeClients(); 581 fake_dbus_thread_manager_->SetSessionManagerClient( 582 scoped_ptr<SessionManagerClient>(fake_session_manager_client_)); 583 } 584 585 // UserImageManagerTest overrides: 586 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { 587 DBusThreadManager::SetInstanceForTesting(fake_dbus_thread_manager_); 588 UserImageManagerTest::SetUpInProcessBrowserTestFixture(); 589 } 590 591 virtual void SetUpOnMainThread() OVERRIDE { 592 UserImageManagerTest::SetUpOnMainThread(); 593 594 base::FilePath user_keys_dir; 595 ASSERT_TRUE(PathService::Get(chromeos::DIR_USER_POLICY_KEYS, 596 &user_keys_dir)); 597 const std::string sanitized_username = 598 chromeos::CryptohomeClient::GetStubSanitizedUsername(kTestUser1); 599 const base::FilePath user_key_file = 600 user_keys_dir.AppendASCII(sanitized_username) 601 .AppendASCII("policy.pub"); 602 std::vector<uint8> user_key_bits; 603 ASSERT_TRUE(user_policy_.GetSigningKey()->ExportPublicKey(&user_key_bits)); 604 ASSERT_TRUE(base::CreateDirectory(user_key_file.DirName())); 605 ASSERT_EQ(base::WriteFile( 606 user_key_file, 607 reinterpret_cast<const char*>(user_key_bits.data()), 608 user_key_bits.size()), 609 static_cast<int>(user_key_bits.size())); 610 user_policy_.policy_data().set_username(kTestUser1); 611 612 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 613 614 policy_image_ = test::ImageLoader(test_data_dir_.Append( 615 test::kUserAvatarImage2RelativePath)).Load(); 616 ASSERT_TRUE(policy_image_); 617 } 618 619 // policy::CloudPolicyStore::Observer overrides: 620 virtual void OnStoreLoaded(policy::CloudPolicyStore* store) OVERRIDE { 621 if (run_loop_) 622 run_loop_->Quit(); 623 } 624 625 virtual void OnStoreError(policy::CloudPolicyStore* store) OVERRIDE { 626 if (run_loop_) 627 run_loop_->Quit(); 628 } 629 630 std::string ConstructPolicy(const std::string& relative_path) { 631 std::string image_data; 632 if (!base::ReadFileToString(test_data_dir_.Append(relative_path), 633 &image_data)) { 634 ADD_FAILURE(); 635 } 636 std::string policy; 637 base::JSONWriter::Write(policy::test::ConstructExternalDataReference( 638 embedded_test_server()->GetURL(std::string("/") + relative_path).spec(), 639 image_data).get(), 640 &policy); 641 return policy; 642 } 643 644 policy::UserPolicyBuilder user_policy_; 645 FakeDBusThreadManager* fake_dbus_thread_manager_; 646 FakeSessionManagerClient* fake_session_manager_client_; 647 648 scoped_ptr<gfx::ImageSkia> policy_image_; 649 650 private: 651 DISALLOW_COPY_AND_ASSIGN(UserImageManagerPolicyTest); 652}; 653 654IN_PROC_BROWSER_TEST_F(UserImageManagerPolicyTest, PRE_SetAndClear) { 655 RegisterUser(kTestUser1); 656 chromeos::StartupUtils::MarkOobeCompleted(); 657} 658 659// Verifies that the user image can be set through policy. Also verifies that 660// after the policy has been cleared, the user is able to choose a different 661// image. 662IN_PROC_BROWSER_TEST_F(UserImageManagerPolicyTest, SetAndClear) { 663 const User* user = UserManager::Get()->FindUser(kTestUser1); 664 ASSERT_TRUE(user); 665 666 LoginUser(kTestUser1); 667 base::RunLoop().RunUntilIdle(); 668 669 policy::CloudPolicyStore* store = GetStoreForUser(user); 670 ASSERT_TRUE(store); 671 672 // Set policy. Verify that the policy-provided user image is downloaded, set 673 // and persisted. 674 user_policy_.payload().mutable_useravatarimage()->set_value( 675 ConstructPolicy(test::kUserAvatarImage2RelativePath)); 676 user_policy_.Build(); 677 fake_session_manager_client_->set_user_policy(kTestUser1, 678 user_policy_.GetBlob()); 679 run_loop_.reset(new base::RunLoop); 680 store->Load(); 681 run_loop_->Run(); 682 683 EXPECT_FALSE(user->HasDefaultImage()); 684 EXPECT_EQ(User::kExternalImageIndex, user->image_index()); 685 EXPECT_TRUE(test::AreImagesEqual(*policy_image_, user->GetImage())); 686 ExpectNewUserImageInfo(kTestUser1, 687 User::kExternalImageIndex, 688 GetUserImagePath(kTestUser1, "jpg")); 689 690 scoped_ptr<gfx::ImageSkia> saved_image = 691 test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load(); 692 ASSERT_TRUE(saved_image); 693 694 // Check image dimensions. Images can't be compared since JPEG is lossy. 695 EXPECT_EQ(policy_image_->width(), saved_image->width()); 696 EXPECT_EQ(policy_image_->height(), saved_image->height()); 697 698 // Clear policy. Verify that the user image switches to a random default 699 // image. 700 user_policy_.payload().Clear(); 701 user_policy_.Build(); 702 fake_session_manager_client_->set_user_policy(kTestUser1, 703 user_policy_.GetBlob()); 704 run_loop_.reset(new base::RunLoop); 705 store->AddObserver(this); 706 store->Load(); 707 run_loop_->Run(); 708 store->RemoveObserver(this); 709 base::RunLoop().RunUntilIdle(); 710 711 const int default_image_index = user->image_index(); 712 EXPECT_TRUE(user->HasDefaultImage()); 713 ASSERT_LE(kFirstDefaultImageIndex, default_image_index); 714 ASSERT_GT(kFirstDefaultImageIndex + kDefaultImagesCount, default_image_index); 715 const gfx::ImageSkia& default_image = GetDefaultImage(default_image_index); 716 EXPECT_TRUE(test::AreImagesEqual(default_image, user->GetImage())); 717 ExpectNewUserImageInfo(kTestUser1, default_image_index, base::FilePath()); 718 719 // Choose a different user image. Verify that the chosen user image is set and 720 // persisted. 721 const int user_image_index = kFirstDefaultImageIndex + 722 (default_image_index - kFirstDefaultImageIndex + 1) % kDefaultImagesCount; 723 const gfx::ImageSkia& user_image = GetDefaultImage(user_image_index); 724 725 UserImageManager* user_image_manager = 726 UserManager::Get()->GetUserImageManager(kTestUser1); 727 user_image_manager->SaveUserDefaultImageIndex(user_image_index); 728 729 EXPECT_TRUE(user->HasDefaultImage()); 730 EXPECT_EQ(user_image_index, user->image_index()); 731 EXPECT_TRUE(test::AreImagesEqual(user_image, user->GetImage())); 732 ExpectNewUserImageInfo(kTestUser1, user_image_index, base::FilePath()); 733} 734 735IN_PROC_BROWSER_TEST_F(UserImageManagerPolicyTest, PRE_PolicyOverridesUser) { 736 RegisterUser(kTestUser1); 737 chromeos::StartupUtils::MarkOobeCompleted(); 738} 739 740// Verifies that when the user chooses a user image and a different image is 741// then set through policy, the policy takes precedence, overriding the 742// previously chosen image. 743IN_PROC_BROWSER_TEST_F(UserImageManagerPolicyTest, PolicyOverridesUser) { 744 const User* user = UserManager::Get()->FindUser(kTestUser1); 745 ASSERT_TRUE(user); 746 747 LoginUser(kTestUser1); 748 base::RunLoop().RunUntilIdle(); 749 750 policy::CloudPolicyStore* store = GetStoreForUser(user); 751 ASSERT_TRUE(store); 752 753 // Choose a user image. Verify that the chosen user image is set and 754 // persisted. 755 const gfx::ImageSkia& default_image = 756 GetDefaultImage(kFirstDefaultImageIndex); 757 758 UserImageManager* user_image_manager = 759 UserManager::Get()->GetUserImageManager(kTestUser1); 760 user_image_manager->SaveUserDefaultImageIndex(kFirstDefaultImageIndex); 761 762 EXPECT_TRUE(user->HasDefaultImage()); 763 EXPECT_EQ(kFirstDefaultImageIndex, user->image_index()); 764 EXPECT_TRUE(test::AreImagesEqual(default_image, user->GetImage())); 765 ExpectNewUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath()); 766 767 // Set policy. Verify that the policy-provided user image is downloaded, set 768 // and persisted, overriding the previously set image. 769 user_policy_.payload().mutable_useravatarimage()->set_value( 770 ConstructPolicy(test::kUserAvatarImage2RelativePath)); 771 user_policy_.Build(); 772 fake_session_manager_client_->set_user_policy(kTestUser1, 773 user_policy_.GetBlob()); 774 run_loop_.reset(new base::RunLoop); 775 store->Load(); 776 run_loop_->Run(); 777 778 EXPECT_FALSE(user->HasDefaultImage()); 779 EXPECT_EQ(User::kExternalImageIndex, user->image_index()); 780 EXPECT_TRUE(test::AreImagesEqual(*policy_image_, user->GetImage())); 781 ExpectNewUserImageInfo(kTestUser1, 782 User::kExternalImageIndex, 783 GetUserImagePath(kTestUser1, "jpg")); 784 785 scoped_ptr<gfx::ImageSkia> saved_image = 786 test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load(); 787 ASSERT_TRUE(saved_image); 788 789 // Check image dimensions. Images can't be compared since JPEG is lossy. 790 EXPECT_EQ(policy_image_->width(), saved_image->width()); 791 EXPECT_EQ(policy_image_->height(), saved_image->height()); 792} 793 794IN_PROC_BROWSER_TEST_F(UserImageManagerPolicyTest, 795 PRE_UserDoesNotOverridePolicy) { 796 RegisterUser(kTestUser1); 797 chromeos::StartupUtils::MarkOobeCompleted(); 798} 799 800// Verifies that when the user image has been set through policy and the user 801// chooses a different image, the policy takes precedence, preventing the user 802// from overriding the previously chosen image. 803IN_PROC_BROWSER_TEST_F(UserImageManagerPolicyTest, UserDoesNotOverridePolicy) { 804 const User* user = UserManager::Get()->FindUser(kTestUser1); 805 ASSERT_TRUE(user); 806 807 LoginUser(kTestUser1); 808 base::RunLoop().RunUntilIdle(); 809 810 policy::CloudPolicyStore* store = GetStoreForUser(user); 811 ASSERT_TRUE(store); 812 813 // Set policy. Verify that the policy-provided user image is downloaded, set 814 // and persisted. 815 user_policy_.payload().mutable_useravatarimage()->set_value( 816 ConstructPolicy(test::kUserAvatarImage2RelativePath)); 817 user_policy_.Build(); 818 fake_session_manager_client_->set_user_policy(kTestUser1, 819 user_policy_.GetBlob()); 820 run_loop_.reset(new base::RunLoop); 821 store->Load(); 822 run_loop_->Run(); 823 824 EXPECT_FALSE(user->HasDefaultImage()); 825 EXPECT_EQ(User::kExternalImageIndex, user->image_index()); 826 EXPECT_TRUE(test::AreImagesEqual(*policy_image_, user->GetImage())); 827 ExpectNewUserImageInfo(kTestUser1, 828 User::kExternalImageIndex, 829 GetUserImagePath(kTestUser1, "jpg")); 830 831 scoped_ptr<gfx::ImageSkia> saved_image = 832 test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load(); 833 ASSERT_TRUE(saved_image); 834 835 // Check image dimensions. Images can't be compared since JPEG is lossy. 836 EXPECT_EQ(policy_image_->width(), saved_image->width()); 837 EXPECT_EQ(policy_image_->height(), saved_image->height()); 838 839 // Choose a different user image. Verify that the user image does not change 840 // as policy takes precedence. 841 UserImageManager* user_image_manager = 842 UserManager::Get()->GetUserImageManager(kTestUser1); 843 user_image_manager->SaveUserDefaultImageIndex(kFirstDefaultImageIndex); 844 845 EXPECT_FALSE(user->HasDefaultImage()); 846 EXPECT_EQ(User::kExternalImageIndex, user->image_index()); 847 EXPECT_TRUE(test::AreImagesEqual(*policy_image_, user->GetImage())); 848 ExpectNewUserImageInfo(kTestUser1, 849 User::kExternalImageIndex, 850 GetUserImagePath(kTestUser1, "jpg")); 851 852 saved_image = test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load(); 853 ASSERT_TRUE(saved_image); 854 855 // Check image dimensions. Images can't be compared since JPEG is lossy. 856 EXPECT_EQ(policy_image_->width(), saved_image->width()); 857 EXPECT_EQ(policy_image_->height(), saved_image->height()); 858} 859 860} // namespace chromeos 861