1 // Copyright (c) 2012 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.
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/default_user_images.h"
29 #include "chrome/browser/chromeos/login/login_manager_test.h"
30 #include "chrome/browser/chromeos/login/mock_user_manager.h"
31 #include "chrome/browser/chromeos/login/startup_utils.h"
32 #include "chrome/browser/chromeos/login/user.h"
33 #include "chrome/browser/chromeos/login/user_image.h"
34 #include "chrome/browser/chromeos/login/user_image_manager.h"
35 #include "chrome/browser/chromeos/login/user_image_manager_impl.h"
36 #include "chrome/browser/chromeos/login/user_image_manager_test_util.h"
37 #include "chrome/browser/chromeos/login/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/oauth2_token_service.h"
60 #include "net/test/embedded_test_server/embedded_test_server.h"
61 #include "net/url_request/test_url_fetcher_factory.h"
62 #include "net/url_request/url_fetcher_delegate.h"
63 #include "net/url_request/url_request_status.h"
64 #include "policy/proto/cloud_policy.pb.h"
65 #include "testing/gtest/include/gtest/gtest.h"
66 #include "third_party/skia/include/core/SkBitmap.h"
67 #include "ui/base/layout.h"
68 #include "ui/base/resource/resource_bundle.h"
69 #include "ui/gfx/image/image_skia.h"
76 const char kTestUser1[] = "test-user@example.com";
77 const char kTestUser2[] = "test-user2@example.com";
79 policy::CloudPolicyStore* GetStoreForUser(const User* user) {
80 Profile* profile = UserManager::Get()->GetProfileByUser(user);
85 policy::UserCloudPolicyManagerChromeOS* policy_manager =
86 policy::UserCloudPolicyManagerFactoryChromeOS::GetForProfile(profile);
87 if (!policy_manager) {
91 return policy_manager->core()->store();
96 class UserImageManagerTest : public LoginManagerTest,
97 public UserManager::Observer {
99 UserImageManagerTest() : LoginManagerTest(true) {
102 // LoginManagerTest overrides:
103 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
104 LoginManagerTest::SetUpInProcessBrowserTestFixture();
106 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_));
107 ASSERT_TRUE(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir_));
110 virtual void SetUpOnMainThread() OVERRIDE {
111 LoginManagerTest::SetUpOnMainThread();
112 local_state_ = g_browser_process->local_state();
113 UserManager::Get()->AddObserver(this);
116 virtual void TearDownOnMainThread() OVERRIDE {
117 UserManager::Get()->RemoveObserver(this);
118 LoginManagerTest::TearDownOnMainThread();
121 // UserManager::Observer overrides:
122 virtual void LocalStateChanged(UserManager* user_manager) OVERRIDE {
127 // Logs in |username|.
128 void LogIn(const std::string& username) {
129 UserManager::Get()->UserLoggedIn(username, username, false);
132 // Stores old (pre-migration) user image info.
133 void SetOldUserImageInfo(const std::string& username,
135 const base::FilePath& image_path) {
136 RegisterUser(username);
137 DictionaryPrefUpdate images_pref(local_state_, "UserImages");
138 base::DictionaryValue* image_properties = new base::DictionaryValue();
139 image_properties->Set(
140 "index", base::Value::CreateIntegerValue(image_index));
141 image_properties->Set(
142 "path" , new base::StringValue(image_path.value()));
143 images_pref->SetWithoutPathExpansion(username, image_properties);
146 // Verifies user image info in |images_pref| dictionary.
147 void ExpectUserImageInfo(const base::DictionaryValue* images_pref,
148 const std::string& username,
150 const base::FilePath& image_path) {
151 ASSERT_TRUE(images_pref);
152 const base::DictionaryValue* image_properties = NULL;
153 images_pref->GetDictionaryWithoutPathExpansion(username, &image_properties);
154 ASSERT_TRUE(image_properties);
155 int actual_image_index;
156 std::string actual_image_path;
157 ASSERT_TRUE(image_properties->GetInteger("index", &actual_image_index) &&
158 image_properties->GetString("path", &actual_image_path));
159 EXPECT_EQ(image_index, actual_image_index);
160 EXPECT_EQ(image_path.value(), actual_image_path);
163 // Verifies that there is no image info for |username| in dictionary
165 void ExpectNoUserImageInfo(const base::DictionaryValue* images_pref,
166 const std::string& username) {
167 ASSERT_TRUE(images_pref);
168 const base::DictionaryValue* image_properties = NULL;
169 images_pref->GetDictionaryWithoutPathExpansion(username, &image_properties);
170 ASSERT_FALSE(image_properties);
173 // Verifies that old user image info matches |image_index| and |image_path|
174 // and that new user image info does not exist.
175 void ExpectOldUserImageInfo(const std::string& username,
177 const base::FilePath& image_path) {
178 ExpectUserImageInfo(local_state_->GetDictionary("UserImages"),
179 username, image_index, image_path);
180 ExpectNoUserImageInfo(local_state_->GetDictionary("user_image_info"),
184 // Verifies that new user image info matches |image_index| and |image_path|
185 // and that old user image info does not exist.
186 void ExpectNewUserImageInfo(const std::string& username,
188 const base::FilePath& image_path) {
189 ExpectUserImageInfo(local_state_->GetDictionary("user_image_info"),
190 username, image_index, image_path);
191 ExpectNoUserImageInfo(local_state_->GetDictionary("UserImages"),
195 // Sets bitmap |resource_id| as image for |username| and saves it to disk.
196 void SaveUserImagePNG(const std::string& username,
198 base::FilePath image_path = GetUserImagePath(username, "png");
199 scoped_refptr<base::RefCountedStaticMemory> image_data(
200 ResourceBundle::GetSharedInstance().LoadDataResourceBytesForScale(
201 resource_id, ui::SCALE_FACTOR_100P));
202 int written = base::WriteFile(
204 reinterpret_cast<const char*>(image_data->front()),
206 EXPECT_EQ(static_cast<int>(image_data->size()), written);
207 SetOldUserImageInfo(username, User::kExternalImageIndex, image_path);
210 // Returns the image path for user |username| with specified |extension|.
211 base::FilePath GetUserImagePath(const std::string& username,
212 const std::string& extension) {
213 return user_data_dir_.Append(username).AddExtension(extension);
216 // Completes the download of all non-image profile data for the user
217 // |username|. This method must only be called after a profile data
218 // download has been started. |url_fetcher_factory| will capture
219 // the net::TestURLFetcher created by the ProfileDownloader to
220 // download the profile image.
221 void CompleteProfileMetadataDownload(
222 const std::string& username,
223 net::TestURLFetcherFactory* url_fetcher_factory) {
224 ProfileDownloader* profile_downloader =
225 reinterpret_cast<UserImageManagerImpl*>(
226 UserManager::Get()->GetUserImageManager(username))->
227 profile_downloader_.get();
228 ASSERT_TRUE(profile_downloader);
230 static_cast<OAuth2TokenService::Consumer*>(profile_downloader)->
231 OnGetTokenSuccess(NULL,
233 base::Time::Now() + base::TimeDelta::FromDays(1));
235 net::TestURLFetcher* fetcher = url_fetcher_factory->GetFetcherByID(0);
236 ASSERT_TRUE(fetcher);
237 fetcher->SetResponseString(
238 "{ \"picture\": \"http://localhost/avatar.jpg\" }");
239 fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
241 fetcher->set_response_code(200);
242 fetcher->delegate()->OnURLFetchComplete(fetcher);
243 base::RunLoop().RunUntilIdle();
246 // Completes the download of the currently logged-in user's profile image.
247 // This method must only be called after a profile data download including
248 // the profile image has been started, the download of all non-image data has
249 // been completed by calling CompleteProfileMetadataDownload() and the
250 // net::TestURLFetcher created by the ProfileDownloader to download the
251 // profile image has been captured by |url_fetcher_factory|.
252 void CompleteProfileImageDownload(
253 net::TestURLFetcherFactory* url_fetcher_factory) {
254 std::string profile_image_data;
255 base::FilePath test_data_dir;
256 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir));
257 EXPECT_TRUE(ReadFileToString(
258 test_data_dir.Append("chromeos").Append("avatar1.jpg"),
259 &profile_image_data));
261 base::RunLoop run_loop;
262 PrefChangeRegistrar pref_change_registrar;
263 pref_change_registrar.Init(local_state_);
264 pref_change_registrar.Add("UserDisplayName", run_loop.QuitClosure());
265 net::TestURLFetcher* fetcher = url_fetcher_factory->GetFetcherByID(0);
266 ASSERT_TRUE(fetcher);
267 fetcher->SetResponseString(profile_image_data);
268 fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
270 fetcher->set_response_code(200);
271 fetcher->delegate()->OnURLFetchComplete(fetcher);
274 const User* user = UserManager::Get()->GetLoggedInUser();
276 UserImageManagerImpl* uim = reinterpret_cast<UserImageManagerImpl*>(
277 UserManager::Get()->GetUserImageManager(user->email()));
278 if (uim->job_.get()) {
279 run_loop_.reset(new base::RunLoop);
284 base::FilePath test_data_dir_;
285 base::FilePath user_data_dir_;
287 PrefService* local_state_;
289 scoped_ptr<gfx::ImageSkia> decoded_image_;
291 scoped_ptr<base::RunLoop> run_loop_;
294 DISALLOW_COPY_AND_ASSIGN(UserImageManagerTest);
297 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_DefaultUserImagePreserved) {
298 // Setup an old default (stock) user image.
299 ScopedUserManagerEnabler(new MockUserManager);
300 SetOldUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath());
303 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, DefaultUserImagePreserved) {
304 UserManager::Get()->GetUsers(); // Load users.
305 // Old info preserved.
306 ExpectOldUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath());
308 // Image info is migrated now.
309 ExpectNewUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath());
312 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_OtherUsersUnaffected) {
313 // Setup two users with stock images.
314 ScopedUserManagerEnabler(new MockUserManager);
315 SetOldUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath());
316 SetOldUserImageInfo(kTestUser2, kFirstDefaultImageIndex + 1,
320 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, OtherUsersUnaffected) {
321 UserManager::Get()->GetUsers(); // Load users.
322 // Old info preserved.
323 ExpectOldUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath());
324 ExpectOldUserImageInfo(kTestUser2, kFirstDefaultImageIndex + 1,
327 // Image info is migrated for the first user and unaffected for the rest.
328 ExpectNewUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath());
329 ExpectOldUserImageInfo(kTestUser2, kFirstDefaultImageIndex + 1,
333 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_PRE_NonJPEGImageFromFile) {
334 // Setup a user with non-JPEG image.
335 ScopedUserManagerEnabler(new MockUserManager);
337 kTestUser1, kDefaultImageResourceIDs[kFirstDefaultImageIndex]);
340 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_NonJPEGImageFromFile) {
341 UserManager::Get()->GetUsers(); // Load users.
342 // Old info preserved.
343 ExpectOldUserImageInfo(kTestUser1, User::kExternalImageIndex,
344 GetUserImagePath(kTestUser1, "png"));
345 const User* user = UserManager::Get()->FindUser(kTestUser1);
346 EXPECT_TRUE(user->image_is_stub());
348 base::RunLoop run_loop;
349 PrefChangeRegistrar pref_change_registrar_;
350 pref_change_registrar_.Init(local_state_);
351 pref_change_registrar_.Add("UserImages", run_loop.QuitClosure());
354 // Wait for migration.
357 // Image info is migrated and the image is converted to JPG.
358 ExpectNewUserImageInfo(kTestUser1, User::kExternalImageIndex,
359 GetUserImagePath(kTestUser1, "jpg"));
360 user = UserManager::Get()->GetLoggedInUser();
362 EXPECT_FALSE(user->image_is_safe_format());
363 // Check image dimensions.
364 const gfx::ImageSkia& saved_image = GetDefaultImage(kFirstDefaultImageIndex);
365 EXPECT_EQ(saved_image.width(), user->image().width());
366 EXPECT_EQ(saved_image.height(), user->image().height());
369 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, NonJPEGImageFromFile) {
370 UserManager::Get()->GetUsers(); // Load users.
371 const User* user = UserManager::Get()->FindUser(kTestUser1);
373 // Wait for image load.
374 if (user->image_index() == User::kInvalidImageIndex) {
375 content::WindowedNotificationObserver(
376 chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED,
377 content::NotificationService::AllSources()).Wait();
379 // Now the migrated image is used.
380 EXPECT_TRUE(user->image_is_safe_format());
381 // Check image dimensions. Images can't be compared since JPEG is lossy.
382 const gfx::ImageSkia& saved_image = GetDefaultImage(kFirstDefaultImageIndex);
383 EXPECT_EQ(saved_image.width(), user->image().width());
384 EXPECT_EQ(saved_image.height(), user->image().height());
387 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_SaveUserDefaultImageIndex) {
388 RegisterUser(kTestUser1);
391 // Verifies that SaveUserDefaultImageIndex() correctly sets and persists the
392 // chosen user image.
393 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, SaveUserDefaultImageIndex) {
394 const User* user = UserManager::Get()->FindUser(kTestUser1);
397 const gfx::ImageSkia& default_image =
398 GetDefaultImage(kFirstDefaultImageIndex);
400 UserImageManager* user_image_manager =
401 UserManager::Get()->GetUserImageManager(kTestUser1);
402 user_image_manager->SaveUserDefaultImageIndex(kFirstDefaultImageIndex);
404 EXPECT_TRUE(user->HasDefaultImage());
405 EXPECT_EQ(kFirstDefaultImageIndex, user->image_index());
406 EXPECT_TRUE(test::AreImagesEqual(default_image, user->image()));
407 ExpectNewUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath());
410 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_SaveUserImage) {
411 RegisterUser(kTestUser1);
414 // Verifies that SaveUserImage() correctly sets and persists the chosen user
416 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, SaveUserImage) {
417 const User* user = UserManager::Get()->FindUser(kTestUser1);
420 SkBitmap custom_image_bitmap;
421 custom_image_bitmap.setConfig(SkBitmap::kARGB_8888_Config, 10, 10);
422 custom_image_bitmap.allocPixels();
423 custom_image_bitmap.setImmutable();
424 const gfx::ImageSkia custom_image =
425 gfx::ImageSkia::CreateFrom1xBitmap(custom_image_bitmap);
427 run_loop_.reset(new base::RunLoop);
428 UserImageManager* user_image_manager =
429 UserManager::Get()->GetUserImageManager(kTestUser1);
430 user_image_manager->SaveUserImage(UserImage::CreateAndEncode(custom_image));
433 EXPECT_FALSE(user->HasDefaultImage());
434 EXPECT_EQ(User::kExternalImageIndex, user->image_index());
435 EXPECT_TRUE(test::AreImagesEqual(custom_image, user->image()));
436 ExpectNewUserImageInfo(kTestUser1,
437 User::kExternalImageIndex,
438 GetUserImagePath(kTestUser1, "jpg"));
440 const scoped_ptr<gfx::ImageSkia> saved_image =
441 test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load();
442 ASSERT_TRUE(saved_image);
444 // Check image dimensions. Images can't be compared since JPEG is lossy.
445 EXPECT_EQ(custom_image.width(), saved_image->width());
446 EXPECT_EQ(custom_image.height(), saved_image->height());
449 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_SaveUserImageFromFile) {
450 RegisterUser(kTestUser1);
453 // Verifies that SaveUserImageFromFile() correctly sets and persists the chosen
455 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, SaveUserImageFromFile) {
456 const User* user = UserManager::Get()->FindUser(kTestUser1);
459 const base::FilePath custom_image_path =
460 test_data_dir_.Append(test::kUserAvatarImage1RelativePath);
461 const scoped_ptr<gfx::ImageSkia> custom_image =
462 test::ImageLoader(custom_image_path).Load();
463 ASSERT_TRUE(custom_image);
465 run_loop_.reset(new base::RunLoop);
466 UserImageManager* user_image_manager =
467 UserManager::Get()->GetUserImageManager(kTestUser1);
468 user_image_manager->SaveUserImageFromFile(custom_image_path);
471 EXPECT_FALSE(user->HasDefaultImage());
472 EXPECT_EQ(User::kExternalImageIndex, user->image_index());
473 EXPECT_TRUE(test::AreImagesEqual(*custom_image, user->image()));
474 ExpectNewUserImageInfo(kTestUser1,
475 User::kExternalImageIndex,
476 GetUserImagePath(kTestUser1, "jpg"));
478 const scoped_ptr<gfx::ImageSkia> saved_image =
479 test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load();
480 ASSERT_TRUE(saved_image);
482 // Check image dimensions. Images can't be compared since JPEG is lossy.
483 EXPECT_EQ(custom_image->width(), saved_image->width());
484 EXPECT_EQ(custom_image->height(), saved_image->height());
487 IN_PROC_BROWSER_TEST_F(UserImageManagerTest,
488 PRE_SaveUserImageFromProfileImage) {
489 RegisterUser(kTestUser1);
490 chromeos::StartupUtils::MarkOobeCompleted();
493 // Verifies that SaveUserImageFromProfileImage() correctly downloads, sets and
494 // persists the chosen user image.
495 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, SaveUserImageFromProfileImage) {
496 const User* user = UserManager::Get()->FindUser(kTestUser1);
499 UserImageManagerImpl::IgnoreProfileDataDownloadDelayForTesting();
500 LoginUser(kTestUser1);
502 run_loop_.reset(new base::RunLoop);
503 UserImageManager* user_image_manager =
504 UserManager::Get()->GetUserImageManager(kTestUser1);
505 user_image_manager->SaveUserImageFromProfileImage();
508 net::TestURLFetcherFactory url_fetcher_factory;
509 CompleteProfileMetadataDownload(kTestUser1, &url_fetcher_factory);
510 CompleteProfileImageDownload(&url_fetcher_factory);
512 const gfx::ImageSkia& profile_image =
513 user_image_manager->DownloadedProfileImage();
515 EXPECT_FALSE(user->HasDefaultImage());
516 EXPECT_EQ(User::kProfileImageIndex, user->image_index());
517 EXPECT_TRUE(test::AreImagesEqual(profile_image, user->image()));
518 ExpectNewUserImageInfo(kTestUser1,
519 User::kProfileImageIndex,
520 GetUserImagePath(kTestUser1, "jpg"));
522 const scoped_ptr<gfx::ImageSkia> saved_image =
523 test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load();
524 ASSERT_TRUE(saved_image);
526 // Check image dimensions. Images can't be compared since JPEG is lossy.
527 EXPECT_EQ(profile_image.width(), saved_image->width());
528 EXPECT_EQ(profile_image.height(), saved_image->height());
531 IN_PROC_BROWSER_TEST_F(UserImageManagerTest,
532 PRE_ProfileImageDownloadDoesNotClobber) {
533 RegisterUser(kTestUser1);
534 chromeos::StartupUtils::MarkOobeCompleted();
537 // Sets the user image to the profile image, then sets it to one of the default
538 // images while the profile image download is still in progress. Verifies that
539 // when the download completes, the profile image is ignored and does not
540 // clobber the default image chosen in the meantime.
541 IN_PROC_BROWSER_TEST_F(UserImageManagerTest,
542 ProfileImageDownloadDoesNotClobber) {
543 const User* user = UserManager::Get()->FindUser(kTestUser1);
546 const gfx::ImageSkia& default_image =
547 GetDefaultImage(kFirstDefaultImageIndex);
549 UserImageManagerImpl::IgnoreProfileDataDownloadDelayForTesting();
550 LoginUser(kTestUser1);
552 run_loop_.reset(new base::RunLoop);
553 UserImageManager* user_image_manager =
554 UserManager::Get()->GetUserImageManager(kTestUser1);
555 user_image_manager->SaveUserImageFromProfileImage();
558 net::TestURLFetcherFactory url_fetcher_factory;
559 CompleteProfileMetadataDownload(kTestUser1, &url_fetcher_factory);
561 user_image_manager->SaveUserDefaultImageIndex(kFirstDefaultImageIndex);
563 CompleteProfileImageDownload(&url_fetcher_factory);
565 EXPECT_TRUE(user->HasDefaultImage());
566 EXPECT_EQ(kFirstDefaultImageIndex, user->image_index());
567 EXPECT_TRUE(test::AreImagesEqual(default_image, user->image()));
568 ExpectNewUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath());
571 class UserImageManagerPolicyTest : public UserImageManagerTest,
572 public policy::CloudPolicyStore::Observer {
574 UserImageManagerPolicyTest()
575 : fake_dbus_thread_manager_(new chromeos::FakeDBusThreadManager),
576 fake_session_manager_client_(new chromeos::FakeSessionManagerClient) {
577 fake_dbus_thread_manager_->SetFakeClients();
578 fake_dbus_thread_manager_->SetSessionManagerClient(
579 scoped_ptr<SessionManagerClient>(fake_session_manager_client_));
582 // UserImageManagerTest overrides:
583 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
584 DBusThreadManager::SetInstanceForTesting(fake_dbus_thread_manager_);
585 UserImageManagerTest::SetUpInProcessBrowserTestFixture();
588 virtual void SetUpOnMainThread() OVERRIDE {
589 UserImageManagerTest::SetUpOnMainThread();
591 base::FilePath user_keys_dir;
592 ASSERT_TRUE(PathService::Get(chromeos::DIR_USER_POLICY_KEYS,
594 const std::string sanitized_username =
595 chromeos::CryptohomeClient::GetStubSanitizedUsername(kTestUser1);
596 const base::FilePath user_key_file =
597 user_keys_dir.AppendASCII(sanitized_username)
598 .AppendASCII("policy.pub");
599 std::vector<uint8> user_key_bits;
600 ASSERT_TRUE(user_policy_.GetSigningKey()->ExportPublicKey(&user_key_bits));
601 ASSERT_TRUE(base::CreateDirectory(user_key_file.DirName()));
602 ASSERT_EQ(base::WriteFile(
604 reinterpret_cast<const char*>(user_key_bits.data()),
605 user_key_bits.size()),
606 static_cast<int>(user_key_bits.size()));
607 user_policy_.policy_data().set_username(kTestUser1);
609 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
611 policy_image_ = test::ImageLoader(test_data_dir_.Append(
612 test::kUserAvatarImage2RelativePath)).Load();
613 ASSERT_TRUE(policy_image_);
616 // policy::CloudPolicyStore::Observer overrides:
617 virtual void OnStoreLoaded(policy::CloudPolicyStore* store) OVERRIDE {
622 virtual void OnStoreError(policy::CloudPolicyStore* store) OVERRIDE {
627 std::string ConstructPolicy(const std::string& relative_path) {
628 std::string image_data;
629 if (!base::ReadFileToString(test_data_dir_.Append(relative_path),
634 base::JSONWriter::Write(policy::test::ConstructExternalDataReference(
635 embedded_test_server()->GetURL(std::string("/") + relative_path).spec(),
641 policy::UserPolicyBuilder user_policy_;
642 FakeDBusThreadManager* fake_dbus_thread_manager_;
643 FakeSessionManagerClient* fake_session_manager_client_;
645 scoped_ptr<gfx::ImageSkia> policy_image_;
648 DISALLOW_COPY_AND_ASSIGN(UserImageManagerPolicyTest);
651 IN_PROC_BROWSER_TEST_F(UserImageManagerPolicyTest, PRE_SetAndClear) {
652 RegisterUser(kTestUser1);
653 chromeos::StartupUtils::MarkOobeCompleted();
656 // Verifies that the user image can be set through policy. Also verifies that
657 // after the policy has been cleared, the user is able to choose a different
659 IN_PROC_BROWSER_TEST_F(UserImageManagerPolicyTest, SetAndClear) {
660 const User* user = UserManager::Get()->FindUser(kTestUser1);
663 LoginUser(kTestUser1);
664 base::RunLoop().RunUntilIdle();
666 policy::CloudPolicyStore* store = GetStoreForUser(user);
669 // Set policy. Verify that the policy-provided user image is downloaded, set
671 user_policy_.payload().mutable_useravatarimage()->set_value(
672 ConstructPolicy(test::kUserAvatarImage2RelativePath));
673 user_policy_.Build();
674 fake_session_manager_client_->set_user_policy(kTestUser1,
675 user_policy_.GetBlob());
676 run_loop_.reset(new base::RunLoop);
680 EXPECT_FALSE(user->HasDefaultImage());
681 EXPECT_EQ(User::kExternalImageIndex, user->image_index());
682 EXPECT_TRUE(test::AreImagesEqual(*policy_image_, user->image()));
683 ExpectNewUserImageInfo(kTestUser1,
684 User::kExternalImageIndex,
685 GetUserImagePath(kTestUser1, "jpg"));
687 scoped_ptr<gfx::ImageSkia> saved_image =
688 test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load();
689 ASSERT_TRUE(saved_image);
691 // Check image dimensions. Images can't be compared since JPEG is lossy.
692 EXPECT_EQ(policy_image_->width(), saved_image->width());
693 EXPECT_EQ(policy_image_->height(), saved_image->height());
695 // Clear policy. Verify that the policy-provided user image remains set as no
696 // different user image has been chosen yet.
697 user_policy_.payload().Clear();
698 user_policy_.Build();
699 fake_session_manager_client_->set_user_policy(kTestUser1,
700 user_policy_.GetBlob());
701 run_loop_.reset(new base::RunLoop);
702 store->AddObserver(this);
705 store->RemoveObserver(this);
706 base::RunLoop().RunUntilIdle();
708 EXPECT_FALSE(user->HasDefaultImage());
709 EXPECT_EQ(User::kExternalImageIndex, user->image_index());
710 EXPECT_TRUE(test::AreImagesEqual(*policy_image_, user->image()));
711 ExpectNewUserImageInfo(kTestUser1,
712 User::kExternalImageIndex,
713 GetUserImagePath(kTestUser1, "jpg"));
715 saved_image = test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load();
716 ASSERT_TRUE(saved_image);
718 // Check image dimensions. Images can't be compared since JPEG is lossy.
719 EXPECT_EQ(policy_image_->width(), saved_image->width());
720 EXPECT_EQ(policy_image_->height(), saved_image->height());
722 // Choose a different user image. Verify that the chosen user image is set and
724 const gfx::ImageSkia& default_image =
725 GetDefaultImage(kFirstDefaultImageIndex);
727 UserImageManager* user_image_manager =
728 UserManager::Get()->GetUserImageManager(kTestUser1);
729 user_image_manager->SaveUserDefaultImageIndex(kFirstDefaultImageIndex);
731 EXPECT_TRUE(user->HasDefaultImage());
732 EXPECT_EQ(kFirstDefaultImageIndex, user->image_index());
733 EXPECT_TRUE(test::AreImagesEqual(default_image, user->image()));
734 ExpectNewUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath());
737 IN_PROC_BROWSER_TEST_F(UserImageManagerPolicyTest, PRE_PolicyOverridesUser) {
738 RegisterUser(kTestUser1);
739 chromeos::StartupUtils::MarkOobeCompleted();
742 // Verifies that when the user chooses a user image and a different image is
743 // then set through policy, the policy takes precedence, overriding the
744 // previously chosen image.
745 IN_PROC_BROWSER_TEST_F(UserImageManagerPolicyTest, PolicyOverridesUser) {
746 const User* user = UserManager::Get()->FindUser(kTestUser1);
749 LoginUser(kTestUser1);
750 base::RunLoop().RunUntilIdle();
752 policy::CloudPolicyStore* store = GetStoreForUser(user);
755 // Choose a user image. Verify that the chosen user image is set and
757 const gfx::ImageSkia& default_image =
758 GetDefaultImage(kFirstDefaultImageIndex);
760 UserImageManager* user_image_manager =
761 UserManager::Get()->GetUserImageManager(kTestUser1);
762 user_image_manager->SaveUserDefaultImageIndex(kFirstDefaultImageIndex);
764 EXPECT_TRUE(user->HasDefaultImage());
765 EXPECT_EQ(kFirstDefaultImageIndex, user->image_index());
766 EXPECT_TRUE(test::AreImagesEqual(default_image, user->image()));
767 ExpectNewUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath());
769 // Set policy. Verify that the policy-provided user image is downloaded, set
770 // and persisted, overriding the previously set image.
771 user_policy_.payload().mutable_useravatarimage()->set_value(
772 ConstructPolicy(test::kUserAvatarImage2RelativePath));
773 user_policy_.Build();
774 fake_session_manager_client_->set_user_policy(kTestUser1,
775 user_policy_.GetBlob());
776 run_loop_.reset(new base::RunLoop);
780 EXPECT_FALSE(user->HasDefaultImage());
781 EXPECT_EQ(User::kExternalImageIndex, user->image_index());
782 EXPECT_TRUE(test::AreImagesEqual(*policy_image_, user->image()));
783 ExpectNewUserImageInfo(kTestUser1,
784 User::kExternalImageIndex,
785 GetUserImagePath(kTestUser1, "jpg"));
787 scoped_ptr<gfx::ImageSkia> saved_image =
788 test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load();
789 ASSERT_TRUE(saved_image);
791 // Check image dimensions. Images can't be compared since JPEG is lossy.
792 EXPECT_EQ(policy_image_->width(), saved_image->width());
793 EXPECT_EQ(policy_image_->height(), saved_image->height());
796 IN_PROC_BROWSER_TEST_F(UserImageManagerPolicyTest,
797 PRE_UserDoesNotOverridePolicy) {
798 RegisterUser(kTestUser1);
799 chromeos::StartupUtils::MarkOobeCompleted();
802 // Verifies that when the user image has been set through policy and the user
803 // chooses a different image, the policy takes precedence, preventing the user
804 // from overriding the previously chosen image.
805 IN_PROC_BROWSER_TEST_F(UserImageManagerPolicyTest, UserDoesNotOverridePolicy) {
806 const User* user = UserManager::Get()->FindUser(kTestUser1);
809 LoginUser(kTestUser1);
810 base::RunLoop().RunUntilIdle();
812 policy::CloudPolicyStore* store = GetStoreForUser(user);
815 // Set policy. Verify that the policy-provided user image is downloaded, set
817 user_policy_.payload().mutable_useravatarimage()->set_value(
818 ConstructPolicy(test::kUserAvatarImage2RelativePath));
819 user_policy_.Build();
820 fake_session_manager_client_->set_user_policy(kTestUser1,
821 user_policy_.GetBlob());
822 run_loop_.reset(new base::RunLoop);
826 EXPECT_FALSE(user->HasDefaultImage());
827 EXPECT_EQ(User::kExternalImageIndex, user->image_index());
828 EXPECT_TRUE(test::AreImagesEqual(*policy_image_, user->image()));
829 ExpectNewUserImageInfo(kTestUser1,
830 User::kExternalImageIndex,
831 GetUserImagePath(kTestUser1, "jpg"));
833 scoped_ptr<gfx::ImageSkia> saved_image =
834 test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load();
835 ASSERT_TRUE(saved_image);
837 // Check image dimensions. Images can't be compared since JPEG is lossy.
838 EXPECT_EQ(policy_image_->width(), saved_image->width());
839 EXPECT_EQ(policy_image_->height(), saved_image->height());
841 // Choose a different user image. Verify that the user image does not change
842 // as policy takes precedence.
843 UserImageManager* user_image_manager =
844 UserManager::Get()->GetUserImageManager(kTestUser1);
845 user_image_manager->SaveUserDefaultImageIndex(kFirstDefaultImageIndex);
847 EXPECT_FALSE(user->HasDefaultImage());
848 EXPECT_EQ(User::kExternalImageIndex, user->image_index());
849 EXPECT_TRUE(test::AreImagesEqual(*policy_image_, user->image()));
850 ExpectNewUserImageInfo(kTestUser1,
851 User::kExternalImageIndex,
852 GetUserImagePath(kTestUser1, "jpg"));
854 saved_image = test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load();
855 ASSERT_TRUE(saved_image);
857 // Check image dimensions. Images can't be compared since JPEG is lossy.
858 EXPECT_EQ(policy_image_->width(), saved_image->width());
859 EXPECT_EQ(policy_image_->height(), saved_image->height());
862 } // namespace chromeos