Home | History | Annotate | Download | only in policy
      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