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