1 // Copyright 2013 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 "chrome/browser/chromeos/policy/recommendation_restorer.h" 6 7 #include "ash/magnifier/magnifier_constants.h" 8 #include "base/memory/scoped_ptr.h" 9 #include "base/prefs/pref_notifier_impl.h" 10 #include "base/prefs/testing_pref_store.h" 11 #include "base/strings/utf_string_conversions.h" 12 #include "base/test/test_simple_task_runner.h" 13 #include "base/thread_task_runner_handle.h" 14 #include "base/time/time.h" 15 #include "base/values.h" 16 #include "chrome/browser/chrome_notification_types.h" 17 #include "chrome/browser/chromeos/policy/recommendation_restorer_factory.h" 18 #include "chrome/browser/prefs/browser_prefs.h" 19 #include "chrome/browser/prefs/pref_service_syncable.h" 20 #include "chrome/common/chrome_constants.h" 21 #include "chrome/common/pref_names.h" 22 #include "chrome/test/base/testing_browser_process.h" 23 #include "chrome/test/base/testing_pref_service_syncable.h" 24 #include "chrome/test/base/testing_profile.h" 25 #include "chrome/test/base/testing_profile_manager.h" 26 #include "components/user_prefs/pref_registry_syncable.h" 27 #include "content/public/browser/notification_details.h" 28 #include "content/public/browser/notification_service.h" 29 #include "content/public/browser/notification_source.h" 30 #include "testing/gtest/include/gtest/gtest.h" 31 32 namespace policy { 33 34 namespace { 35 // The amount of idle time after which recommended values are restored. 36 const int kRestoreDelayInMs = 60 * 1000; // 1 minute. 37 } // namespace 38 39 class RecommendationRestorerTest : public testing::Test { 40 protected: 41 RecommendationRestorerTest(); 42 43 // testing::Test: 44 virtual void SetUp() OVERRIDE; 45 46 void RegisterUserProfilePrefs(); 47 void RegisterLoginProfilePrefs(); 48 49 void SetRecommendedValues(); 50 void SetUserSettings(); 51 52 void CreateLoginProfile(); 53 void CreateUserProfile(); 54 55 void NotifyOfSessionStart(); 56 void NotifyOfUserActivity(); 57 58 void VerifyPrefFollowsUser(const char* pref_name, 59 const base::Value& expected_value) const; 60 void VerifyPrefsFollowUser() const; 61 void VerifyPrefFollowsRecommendation(const char* pref_name, 62 const base::Value& expected_value) const; 63 void VerifyPrefsFollowRecommendations() const; 64 65 void VerifyNotListeningForNotifications() const; 66 void VerifyTimerIsStopped() const; 67 void VerifyTimerIsRunning() const; 68 69 TestingPrefStore* recommended_prefs_; // Not owned. 70 TestingPrefServiceSyncable* prefs_; // Not owned. 71 RecommendationRestorer* restorer_; // Not owned. 72 73 scoped_refptr<base::TestSimpleTaskRunner> runner_; 74 base::ThreadTaskRunnerHandle runner_handler_; 75 76 private: 77 scoped_ptr<PrefServiceSyncable> prefs_owner_; 78 79 TestingProfileManager profile_manager_; 80 81 DISALLOW_COPY_AND_ASSIGN(RecommendationRestorerTest); 82 }; 83 84 RecommendationRestorerTest::RecommendationRestorerTest() 85 : recommended_prefs_(new TestingPrefStore), 86 prefs_(new TestingPrefServiceSyncable( 87 new TestingPrefStore, 88 new TestingPrefStore, 89 recommended_prefs_, 90 new user_prefs::PrefRegistrySyncable, 91 new PrefNotifierImpl)), 92 restorer_(NULL), 93 runner_(new base::TestSimpleTaskRunner), 94 runner_handler_(runner_), 95 prefs_owner_(prefs_), 96 profile_manager_(TestingBrowserProcess::GetGlobal()) { 97 } 98 99 void RecommendationRestorerTest::SetUp() { 100 testing::Test::SetUp(); 101 ASSERT_TRUE(profile_manager_.SetUp()); 102 } 103 104 void RecommendationRestorerTest::RegisterUserProfilePrefs() { 105 chrome::RegisterUserProfilePrefs(prefs_->registry()); 106 } 107 108 void RecommendationRestorerTest::RegisterLoginProfilePrefs() { 109 chrome::RegisterLoginProfilePrefs(prefs_->registry()); 110 } 111 112 void RecommendationRestorerTest::SetRecommendedValues() { 113 recommended_prefs_->SetBoolean(prefs::kLargeCursorEnabled, false); 114 recommended_prefs_->SetBoolean(prefs::kSpokenFeedbackEnabled, false); 115 recommended_prefs_->SetBoolean(prefs::kHighContrastEnabled, false); 116 recommended_prefs_->SetBoolean(prefs::kScreenMagnifierEnabled, false); 117 recommended_prefs_->SetInteger(prefs::kScreenMagnifierType, 0); 118 } 119 120 void RecommendationRestorerTest::SetUserSettings() { 121 prefs_->SetBoolean(prefs::kLargeCursorEnabled, true); 122 prefs_->SetBoolean(prefs::kSpokenFeedbackEnabled, true); 123 prefs_->SetBoolean(prefs::kHighContrastEnabled, true); 124 prefs_->SetBoolean(prefs::kScreenMagnifierEnabled, true); 125 prefs_->SetInteger(prefs::kScreenMagnifierType, ash::MAGNIFIER_FULL); 126 } 127 128 void RecommendationRestorerTest::CreateLoginProfile() { 129 ASSERT_FALSE(restorer_); 130 TestingProfile* profile = profile_manager_.CreateTestingProfile( 131 chrome::kInitialProfile, prefs_owner_.Pass(), 132 UTF8ToUTF16(chrome::kInitialProfile), 0, std::string()); 133 restorer_ = RecommendationRestorerFactory::GetForProfile(profile); 134 EXPECT_TRUE(restorer_); 135 } 136 137 void RecommendationRestorerTest::CreateUserProfile() { 138 ASSERT_FALSE(restorer_); 139 TestingProfile* profile = profile_manager_.CreateTestingProfile( 140 "user", prefs_owner_.Pass(), UTF8ToUTF16("user"), 0, std::string()); 141 restorer_ = RecommendationRestorerFactory::GetForProfile(profile); 142 EXPECT_TRUE(restorer_); 143 } 144 145 void RecommendationRestorerTest::NotifyOfSessionStart() { 146 ASSERT_TRUE(restorer_); 147 restorer_->Observe(chrome::NOTIFICATION_LOGIN_USER_CHANGED, 148 content::Source<RecommendationRestorerTest>(this), 149 content::NotificationService::NoDetails()); 150 } 151 152 void RecommendationRestorerTest::NotifyOfUserActivity() { 153 ASSERT_TRUE(restorer_); 154 restorer_->OnUserActivity(NULL); 155 } 156 157 void RecommendationRestorerTest::VerifyPrefFollowsUser( 158 const char* pref_name, 159 const base::Value& expected_value) const { 160 const PrefServiceSyncable::Preference* pref = 161 prefs_->FindPreference(pref_name); 162 ASSERT_TRUE(pref); 163 EXPECT_TRUE(pref->HasUserSetting()); 164 const base::Value* value = pref->GetValue(); 165 ASSERT_TRUE(value); 166 EXPECT_TRUE(expected_value.Equals(value)); 167 } 168 169 void RecommendationRestorerTest::VerifyPrefsFollowUser() const { 170 VerifyPrefFollowsUser(prefs::kLargeCursorEnabled, 171 base::FundamentalValue(true)); 172 VerifyPrefFollowsUser(prefs::kSpokenFeedbackEnabled, 173 base::FundamentalValue(true)); 174 VerifyPrefFollowsUser(prefs::kHighContrastEnabled, 175 base::FundamentalValue(true)); 176 VerifyPrefFollowsUser(prefs::kScreenMagnifierEnabled, 177 base::FundamentalValue(true)); 178 VerifyPrefFollowsUser(prefs::kScreenMagnifierType, 179 base::FundamentalValue(ash::MAGNIFIER_FULL)); 180 } 181 182 void RecommendationRestorerTest::VerifyPrefFollowsRecommendation( 183 const char* pref_name, 184 const base::Value& expected_value) const { 185 const PrefServiceSyncable::Preference* pref = 186 prefs_->FindPreference(pref_name); 187 ASSERT_TRUE(pref); 188 EXPECT_TRUE(pref->IsRecommended()); 189 EXPECT_FALSE(pref->HasUserSetting()); 190 const base::Value* value = pref->GetValue(); 191 ASSERT_TRUE(value); 192 EXPECT_TRUE(expected_value.Equals(value)); 193 } 194 195 void RecommendationRestorerTest::VerifyPrefsFollowRecommendations() const { 196 VerifyPrefFollowsRecommendation(prefs::kLargeCursorEnabled, 197 base::FundamentalValue(false)); 198 VerifyPrefFollowsRecommendation(prefs::kSpokenFeedbackEnabled, 199 base::FundamentalValue(false)); 200 VerifyPrefFollowsRecommendation(prefs::kHighContrastEnabled, 201 base::FundamentalValue(false)); 202 VerifyPrefFollowsRecommendation(prefs::kScreenMagnifierEnabled, 203 base::FundamentalValue(false)); 204 VerifyPrefFollowsRecommendation(prefs::kScreenMagnifierType, 205 base::FundamentalValue(0)); 206 } 207 208 void RecommendationRestorerTest::VerifyNotListeningForNotifications() const { 209 ASSERT_TRUE(restorer_); 210 EXPECT_TRUE(restorer_->pref_change_registrar_.IsEmpty()); 211 EXPECT_TRUE(restorer_->notification_registrar_.IsEmpty()); 212 } 213 214 void RecommendationRestorerTest::VerifyTimerIsStopped() const { 215 ASSERT_TRUE(restorer_); 216 EXPECT_FALSE(restorer_->restore_timer_.IsRunning()); 217 } 218 219 void RecommendationRestorerTest::VerifyTimerIsRunning() const { 220 ASSERT_TRUE(restorer_); 221 EXPECT_TRUE(restorer_->restore_timer_.IsRunning()); 222 EXPECT_EQ(base::TimeDelta::FromMilliseconds(kRestoreDelayInMs), 223 restorer_->restore_timer_.GetCurrentDelay()); 224 } 225 226 TEST_F(RecommendationRestorerTest, CreateForUserProfile) { 227 // Verifies that when a RecommendationRestorer is created for a user profile, 228 // it does not start listening for any notifications, does not clear user 229 // settings on initialization and does not start a timer that will clear user 230 // settings eventually. 231 RegisterUserProfilePrefs(); 232 SetRecommendedValues(); 233 SetUserSettings(); 234 235 CreateUserProfile(); 236 VerifyNotListeningForNotifications(); 237 VerifyPrefsFollowUser(); 238 VerifyTimerIsStopped(); 239 } 240 241 TEST_F(RecommendationRestorerTest, NoRecommendations) { 242 // Verifies that when no recommended values have been set and a 243 // RecommendationRestorer is created for the login profile, it does not clear 244 // user settings on initialization and does not start a timer that will clear 245 // user settings eventually. 246 RegisterLoginProfilePrefs(); 247 SetUserSettings(); 248 249 CreateLoginProfile(); 250 VerifyPrefsFollowUser(); 251 VerifyTimerIsStopped(); 252 } 253 254 TEST_F(RecommendationRestorerTest, RestoreOnStartup) { 255 // Verifies that when recommended values have been set and a 256 // RecommendationRestorer is created for the login profile, it clears user 257 // settings on initialization. 258 RegisterLoginProfilePrefs(); 259 SetRecommendedValues(); 260 SetUserSettings(); 261 262 CreateLoginProfile(); 263 VerifyPrefsFollowRecommendations(); 264 VerifyTimerIsStopped(); 265 } 266 267 TEST_F(RecommendationRestorerTest, RestoreOnRecommendationChangeOnLoginScreen) { 268 // Verifies that if recommended values change while the login screen is being 269 // shown, a timer is started that will clear user settings eventually. 270 RegisterLoginProfilePrefs(); 271 SetUserSettings(); 272 273 CreateLoginProfile(); 274 275 VerifyTimerIsStopped(); 276 recommended_prefs_->SetBoolean(prefs::kLargeCursorEnabled, false); 277 VerifyPrefFollowsUser(prefs::kLargeCursorEnabled, 278 base::FundamentalValue(true)); 279 VerifyTimerIsRunning(); 280 runner_->RunUntilIdle(); 281 VerifyPrefFollowsRecommendation(prefs::kLargeCursorEnabled, 282 base::FundamentalValue(false)); 283 284 VerifyTimerIsStopped(); 285 recommended_prefs_->SetBoolean(prefs::kSpokenFeedbackEnabled, false); 286 VerifyPrefFollowsUser(prefs::kSpokenFeedbackEnabled, 287 base::FundamentalValue(true)); 288 VerifyTimerIsRunning(); 289 runner_->RunUntilIdle(); 290 VerifyPrefFollowsRecommendation(prefs::kSpokenFeedbackEnabled, 291 base::FundamentalValue(false)); 292 293 VerifyTimerIsStopped(); 294 recommended_prefs_->SetBoolean(prefs::kHighContrastEnabled, false); 295 VerifyPrefFollowsUser(prefs::kHighContrastEnabled, 296 base::FundamentalValue(true)); 297 VerifyTimerIsRunning(); 298 runner_->RunUntilIdle(); 299 VerifyPrefFollowsRecommendation(prefs::kHighContrastEnabled, 300 base::FundamentalValue(false)); 301 302 VerifyTimerIsStopped(); 303 recommended_prefs_->SetBoolean(prefs::kScreenMagnifierEnabled, false); 304 recommended_prefs_->SetInteger(prefs::kScreenMagnifierType, 0); 305 VerifyPrefFollowsUser(prefs::kScreenMagnifierEnabled, 306 base::FundamentalValue(true)); 307 VerifyPrefFollowsUser(prefs::kScreenMagnifierType, 308 base::FundamentalValue(ash::MAGNIFIER_FULL)); 309 VerifyTimerIsRunning(); 310 runner_->RunUntilIdle(); 311 VerifyPrefFollowsRecommendation(prefs::kScreenMagnifierEnabled, 312 base::FundamentalValue(false)); 313 VerifyPrefFollowsRecommendation(prefs::kScreenMagnifierType, 314 base::FundamentalValue(0)); 315 316 VerifyTimerIsStopped(); 317 } 318 319 TEST_F(RecommendationRestorerTest, RestoreOnRecommendationChangeInUserSession) { 320 // Verifies that if recommended values change while a user session is in 321 // progress, user settings are cleared immediately. 322 RegisterLoginProfilePrefs(); 323 SetUserSettings(); 324 325 CreateLoginProfile(); 326 NotifyOfSessionStart(); 327 328 VerifyPrefFollowsUser(prefs::kLargeCursorEnabled, 329 base::FundamentalValue(true)); 330 recommended_prefs_->SetBoolean(prefs::kLargeCursorEnabled, false); 331 VerifyTimerIsStopped(); 332 VerifyPrefFollowsRecommendation(prefs::kLargeCursorEnabled, 333 base::FundamentalValue(false)); 334 335 VerifyPrefFollowsUser(prefs::kSpokenFeedbackEnabled, 336 base::FundamentalValue(true)); 337 recommended_prefs_->SetBoolean(prefs::kSpokenFeedbackEnabled, false); 338 VerifyTimerIsStopped(); 339 VerifyPrefFollowsRecommendation(prefs::kSpokenFeedbackEnabled, 340 base::FundamentalValue(false)); 341 342 VerifyPrefFollowsUser(prefs::kHighContrastEnabled, 343 base::FundamentalValue(true)); 344 recommended_prefs_->SetBoolean(prefs::kHighContrastEnabled, false); 345 VerifyTimerIsStopped(); 346 VerifyPrefFollowsRecommendation(prefs::kHighContrastEnabled, 347 base::FundamentalValue(false)); 348 349 VerifyPrefFollowsUser(prefs::kScreenMagnifierEnabled, 350 base::FundamentalValue(true)); 351 VerifyPrefFollowsUser(prefs::kScreenMagnifierType, 352 base::FundamentalValue(ash::MAGNIFIER_FULL)); 353 recommended_prefs_->SetBoolean(prefs::kScreenMagnifierEnabled, false); 354 recommended_prefs_->SetInteger(prefs::kScreenMagnifierType, 0); 355 VerifyTimerIsStopped(); 356 VerifyPrefFollowsRecommendation(prefs::kScreenMagnifierEnabled, 357 base::FundamentalValue(false)); 358 VerifyPrefFollowsRecommendation(prefs::kScreenMagnifierType, 359 base::FundamentalValue(0)); 360 } 361 362 TEST_F(RecommendationRestorerTest, DoNothingOnUserChange) { 363 // Verifies that if no recommended values have been set and user settings 364 // change, the user settings are not cleared immediately and no timer is 365 // started that will clear the user settings eventually. 366 RegisterLoginProfilePrefs(); 367 CreateLoginProfile(); 368 369 prefs_->SetBoolean(prefs::kLargeCursorEnabled, true); 370 VerifyPrefFollowsUser(prefs::kLargeCursorEnabled, 371 base::FundamentalValue(true)); 372 VerifyTimerIsStopped(); 373 374 prefs_->SetBoolean(prefs::kSpokenFeedbackEnabled, true); 375 VerifyPrefFollowsUser(prefs::kSpokenFeedbackEnabled, 376 base::FundamentalValue(true)); 377 VerifyTimerIsStopped(); 378 379 prefs_->SetBoolean(prefs::kHighContrastEnabled, true); 380 VerifyPrefFollowsUser(prefs::kHighContrastEnabled, 381 base::FundamentalValue(true)); 382 VerifyTimerIsStopped(); 383 384 prefs_->SetBoolean(prefs::kScreenMagnifierEnabled, true); 385 VerifyPrefFollowsUser(prefs::kScreenMagnifierEnabled, 386 base::FundamentalValue(true)); 387 VerifyTimerIsStopped(); 388 389 prefs_->SetBoolean(prefs::kScreenMagnifierEnabled, true); 390 prefs_->SetInteger(prefs::kScreenMagnifierType, ash::MAGNIFIER_FULL); 391 VerifyPrefFollowsUser(prefs::kScreenMagnifierEnabled, 392 base::FundamentalValue(true)); 393 VerifyPrefFollowsUser(prefs::kScreenMagnifierType, 394 base::FundamentalValue(ash::MAGNIFIER_FULL)); 395 VerifyTimerIsStopped(); 396 } 397 398 TEST_F(RecommendationRestorerTest, RestoreOnUserChange) { 399 // Verifies that if recommended values have been set and user settings change 400 // while the login screen is being shown, a timer is started that will clear 401 // the user settings eventually. 402 RegisterLoginProfilePrefs(); 403 SetRecommendedValues(); 404 405 CreateLoginProfile(); 406 407 VerifyTimerIsStopped(); 408 prefs_->SetBoolean(prefs::kLargeCursorEnabled, true); 409 VerifyPrefFollowsUser(prefs::kLargeCursorEnabled, 410 base::FundamentalValue(true)); 411 VerifyTimerIsRunning(); 412 runner_->RunUntilIdle(); 413 VerifyPrefFollowsRecommendation(prefs::kLargeCursorEnabled, 414 base::FundamentalValue(false)); 415 416 VerifyTimerIsStopped(); 417 prefs_->SetBoolean(prefs::kSpokenFeedbackEnabled, true); 418 VerifyPrefFollowsUser(prefs::kSpokenFeedbackEnabled, 419 base::FundamentalValue(true)); 420 VerifyTimerIsRunning(); 421 runner_->RunUntilIdle(); 422 VerifyPrefFollowsRecommendation(prefs::kSpokenFeedbackEnabled, 423 base::FundamentalValue(false)); 424 425 VerifyTimerIsStopped(); 426 prefs_->SetBoolean(prefs::kHighContrastEnabled, true); 427 VerifyPrefFollowsUser(prefs::kHighContrastEnabled, 428 base::FundamentalValue(true)); 429 VerifyTimerIsRunning(); 430 runner_->RunUntilIdle(); 431 VerifyPrefFollowsRecommendation(prefs::kHighContrastEnabled, 432 base::FundamentalValue(false)); 433 434 VerifyTimerIsStopped(); 435 prefs_->SetBoolean(prefs::kScreenMagnifierEnabled, true); 436 prefs_->SetInteger(prefs::kScreenMagnifierType, ash::MAGNIFIER_FULL); 437 VerifyPrefFollowsUser(prefs::kScreenMagnifierEnabled, 438 base::FundamentalValue(true)); 439 VerifyPrefFollowsUser(prefs::kScreenMagnifierType, 440 base::FundamentalValue(ash::MAGNIFIER_FULL)); 441 VerifyTimerIsRunning(); 442 runner_->RunUntilIdle(); 443 VerifyPrefFollowsRecommendation(prefs::kScreenMagnifierEnabled, 444 base::FundamentalValue(false)); 445 VerifyPrefFollowsRecommendation(prefs::kScreenMagnifierType, 446 base::FundamentalValue(0)); 447 448 VerifyTimerIsStopped(); 449 } 450 451 TEST_F(RecommendationRestorerTest, RestoreOnSessionStart) { 452 // Verifies that if recommended values have been set, user settings have 453 // changed and a session is then started, the user settings are cleared 454 // immediately and the timer that would have cleared them eventually on the 455 // login screen is stopped. 456 RegisterLoginProfilePrefs(); 457 SetRecommendedValues(); 458 459 CreateLoginProfile(); 460 SetUserSettings(); 461 462 NotifyOfSessionStart(); 463 VerifyPrefsFollowRecommendations(); 464 VerifyTimerIsStopped(); 465 } 466 467 TEST_F(RecommendationRestorerTest, DoNothingOnSessionStart) { 468 // Verifies that if recommended values have not been set, user settings have 469 // changed and a session is then started, the user settings are not cleared 470 // immediately. 471 RegisterLoginProfilePrefs(); 472 CreateLoginProfile(); 473 SetUserSettings(); 474 475 NotifyOfSessionStart(); 476 VerifyPrefsFollowUser(); 477 VerifyTimerIsStopped(); 478 } 479 480 TEST_F(RecommendationRestorerTest, UserActivityResetsTimer) { 481 // Verifies that user activity resets the timer which clears user settings. 482 RegisterLoginProfilePrefs(); 483 484 recommended_prefs_->SetBoolean(prefs::kLargeCursorEnabled, false); 485 486 CreateLoginProfile(); 487 488 prefs_->SetBoolean(prefs::kLargeCursorEnabled, true); 489 VerifyTimerIsRunning(); 490 491 // Notify that there is user activity, then fast forward until the originally 492 // set timer fires. 493 NotifyOfUserActivity(); 494 runner_->RunPendingTasks(); 495 VerifyPrefFollowsUser(prefs::kLargeCursorEnabled, 496 base::FundamentalValue(true)); 497 498 // Fast forward until the reset timer fires. 499 VerifyTimerIsRunning(); 500 runner_->RunUntilIdle(); 501 VerifyPrefFollowsRecommendation(prefs::kLargeCursorEnabled, 502 base::FundamentalValue(false)); 503 VerifyTimerIsStopped(); 504 } 505 506 } // namespace policy 507