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