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