1 // Copyright 2018 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ash/policy/policy_recommendation_restorer.h"
7 #include "ash/constants/ash_pref_names.h"
8 #include "ash/public/cpp/ash_prefs.h"
9 #include "ash/session/session_controller_impl.h"
10 #include "ash/session/test_session_controller_client.h"
11 #include "ash/shell.h"
12 #include "ash/test/ash_test_base.h"
13 #include "base/memory/ptr_util.h"
14 #include "base/memory/raw_ptr.h"
15 #include "components/prefs/pref_notifier_impl.h"
16 #include "components/prefs/testing_pref_store.h"
17 #include "components/sync_preferences/testing_pref_service_syncable.h"
18 #include "ui/base/user_activity/user_activity_detector.h"
22 class PolicyRecommendationRestorerTest : public NoSessionAshTestBase {
24 PolicyRecommendationRestorerTest(const PolicyRecommendationRestorerTest&) =
26 PolicyRecommendationRestorerTest& operator=(
27 const PolicyRecommendationRestorerTest&) = delete;
30 PolicyRecommendationRestorerTest()
31 : recommended_prefs_(new TestingPrefStore),
32 prefs_(new sync_preferences::TestingPrefServiceSyncable(
33 /*managed_prefs=*/new TestingPrefStore,
34 /*supervised_user_prefs=*/new TestingPrefStore,
35 /*extension_prefs=*/new TestingPrefStore,
36 /*standalone_browser_prefs=*/new TestingPrefStore,
37 /*user_prefs=*/new TestingPrefStore,
39 new user_prefs::PrefRegistrySyncable,
40 new PrefNotifierImpl)) {}
41 ~PolicyRecommendationRestorerTest() override = default;
43 // NoSessionAshTestBase override:
44 void SetUp() override {
45 TestSessionControllerClient::DisableAutomaticallyProvideSigninPref();
46 NoSessionAshTestBase::SetUp();
48 // Register sigin prefs but not connected to pref service yet. This allows
49 // us set pref values before ash connects to pref service for testing.
50 RegisterSigninProfilePrefs(prefs_->registry(), /*country=*/"",
53 restorer_ = Shell::Get()->policy_recommendation_restorer();
56 void ConnectToSigninPrefService() {
57 GetSessionControllerClient()->SetSigninScreenPrefService(
58 base::WrapUnique(prefs_.get()));
59 ASSERT_EQ(Shell::Get()->session_controller()->GetSigninScreenPrefService(),
61 // Manually trigger a user activity, so that the delay is not skipped due to
62 // no user input since a pref is started observing recommended value. See
63 // PolicyRecommendationRestorer::Restore() for the information.
64 ui::UserActivityDetector::Get()->HandleExternalUserActivity();
67 void SetRecommendedValues() {
68 recommended_prefs_->SetBoolean(prefs::kAccessibilityLargeCursorEnabled,
70 recommended_prefs_->SetBoolean(prefs::kAccessibilitySpokenFeedbackEnabled,
72 recommended_prefs_->SetBoolean(prefs::kAccessibilityHighContrastEnabled,
74 recommended_prefs_->SetBoolean(prefs::kAccessibilityScreenMagnifierEnabled,
76 recommended_prefs_->SetBoolean(prefs::kAccessibilityVirtualKeyboardEnabled,
80 void SetUserSettings() {
81 prefs_->SetBoolean(prefs::kAccessibilityLargeCursorEnabled, true);
82 prefs_->SetBoolean(prefs::kAccessibilitySpokenFeedbackEnabled, true);
83 prefs_->SetBoolean(prefs::kAccessibilityHighContrastEnabled, true);
84 prefs_->SetBoolean(prefs::kAccessibilityScreenMagnifierEnabled, true);
85 prefs_->SetBoolean(prefs::kAccessibilityVirtualKeyboardEnabled, true);
88 void VerifyPrefFollowsUser(const std::string& pref_name,
89 const base::Value& expected_value) const {
90 const sync_preferences::PrefServiceSyncable::Preference* pref =
91 prefs_->FindPreference(pref_name);
93 EXPECT_TRUE(pref->HasUserSetting());
94 const base::Value* value = pref->GetValue();
96 EXPECT_EQ(expected_value, *value);
99 void VerifyPrefsFollowUser() const {
100 VerifyPrefFollowsUser(prefs::kAccessibilityLargeCursorEnabled,
102 VerifyPrefFollowsUser(prefs::kAccessibilitySpokenFeedbackEnabled,
104 VerifyPrefFollowsUser(prefs::kAccessibilityHighContrastEnabled,
106 VerifyPrefFollowsUser(prefs::kAccessibilityScreenMagnifierEnabled,
108 VerifyPrefFollowsUser(prefs::kAccessibilityVirtualKeyboardEnabled,
112 void VerifyPrefFollowsRecommendation(
113 const std::string& pref_name,
114 const base::Value& expected_value) const {
115 const sync_preferences::PrefServiceSyncable::Preference* pref =
116 prefs_->FindPreference(pref_name);
118 EXPECT_TRUE(pref->IsRecommended());
119 EXPECT_FALSE(pref->HasUserSetting());
120 const base::Value* value = pref->GetValue();
122 EXPECT_EQ(expected_value, *value);
125 void VerifyPrefsFollowRecommendation() const {
126 VerifyPrefFollowsRecommendation(prefs::kAccessibilityLargeCursorEnabled,
128 VerifyPrefFollowsRecommendation(prefs::kAccessibilitySpokenFeedbackEnabled,
130 VerifyPrefFollowsRecommendation(prefs::kAccessibilityHighContrastEnabled,
132 VerifyPrefFollowsRecommendation(prefs::kAccessibilityScreenMagnifierEnabled,
134 VerifyPrefFollowsRecommendation(prefs::kAccessibilityVirtualKeyboardEnabled,
138 bool RestoreTimerIsRunning() {
139 return restorer_->restore_timer_for_test()->IsRunning();
142 // If restore timer is running, stops it, runs its task and returns true.
143 // Otherwise, returns false.
144 [[nodiscard]] bool TriggerRestoreTimer() {
145 if (!restorer_->restore_timer_for_test()->IsRunning())
148 restorer_->restore_timer_for_test()->FireNow();
152 raw_ptr<PolicyRecommendationRestorer, DanglingUntriaged | ExperimentalAsh>
155 // Ownerships are passed to SessionController.
156 raw_ptr<TestingPrefStore, DanglingUntriaged | ExperimentalAsh>
158 raw_ptr<sync_preferences::TestingPrefServiceSyncable,
159 DanglingUntriaged | ExperimentalAsh>
163 // Verifies that when no recommended values have been set, |restorer_| does not
164 // clear user settings on initialization and does not start a timer that will
165 // clear user settings eventually.
166 TEST_F(PolicyRecommendationRestorerTest, NoRecommendations) {
169 ConnectToSigninPrefService();
170 VerifyPrefsFollowUser();
171 EXPECT_FALSE(RestoreTimerIsRunning());
174 // Verifies that when recommended values have been set, |restorer_| clears user
175 // settings on signing pref initialization.
176 TEST_F(PolicyRecommendationRestorerTest, RestoreOnSigninPrefInitialized) {
177 SetRecommendedValues();
180 ConnectToSigninPrefService();
181 VerifyPrefsFollowRecommendation();
182 EXPECT_FALSE(RestoreTimerIsRunning());
185 // Verifies that if recommended values change while the signin screen is being
186 // shown, a timer is started that will clear user settings eventually.
187 TEST_F(PolicyRecommendationRestorerTest,
188 RestoreOnRecommendationChangeOnSigninScreen) {
189 // No recommended values in observed prefs.
190 ConnectToSigninPrefService();
191 EXPECT_FALSE(RestoreTimerIsRunning());
193 prefs_->SetBoolean(prefs::kAccessibilityLargeCursorEnabled, true);
194 VerifyPrefFollowsUser(prefs::kAccessibilityLargeCursorEnabled,
196 EXPECT_FALSE(RestoreTimerIsRunning());
197 recommended_prefs_->SetBoolean(prefs::kAccessibilityLargeCursorEnabled,
199 EXPECT_TRUE(TriggerRestoreTimer());
200 VerifyPrefFollowsRecommendation(prefs::kAccessibilityLargeCursorEnabled,
203 prefs_->SetBoolean(prefs::kAccessibilitySpokenFeedbackEnabled, true);
204 VerifyPrefFollowsUser(prefs::kAccessibilitySpokenFeedbackEnabled,
206 recommended_prefs_->SetBoolean(prefs::kAccessibilitySpokenFeedbackEnabled,
208 EXPECT_TRUE(TriggerRestoreTimer());
209 VerifyPrefFollowsRecommendation(prefs::kAccessibilitySpokenFeedbackEnabled,
212 prefs_->SetBoolean(prefs::kAccessibilityHighContrastEnabled, true);
213 VerifyPrefFollowsUser(prefs::kAccessibilityHighContrastEnabled,
215 recommended_prefs_->SetBoolean(prefs::kAccessibilityHighContrastEnabled,
217 EXPECT_TRUE(TriggerRestoreTimer());
218 VerifyPrefFollowsRecommendation(prefs::kAccessibilityHighContrastEnabled,
221 prefs_->SetBoolean(prefs::kAccessibilityScreenMagnifierEnabled, true);
222 VerifyPrefFollowsUser(prefs::kAccessibilityScreenMagnifierEnabled,
224 recommended_prefs_->SetBoolean(prefs::kAccessibilityScreenMagnifierEnabled,
226 EXPECT_TRUE(TriggerRestoreTimer());
227 VerifyPrefFollowsRecommendation(prefs::kAccessibilityScreenMagnifierEnabled,
230 prefs_->SetBoolean(prefs::kAccessibilityVirtualKeyboardEnabled, true);
231 VerifyPrefFollowsUser(prefs::kAccessibilityVirtualKeyboardEnabled,
233 recommended_prefs_->SetBoolean(prefs::kAccessibilityVirtualKeyboardEnabled,
235 EXPECT_TRUE(TriggerRestoreTimer());
236 VerifyPrefFollowsRecommendation(prefs::kAccessibilityVirtualKeyboardEnabled,
240 // Verifies that if recommended values change while a user session is in
241 // progress, user settings are cleared immediately.
242 TEST_F(PolicyRecommendationRestorerTest,
243 RestoreOnRecommendationChangeOnUserSession) {
246 ConnectToSigninPrefService();
247 SimulateUserLogin("user@test.com");
249 VerifyPrefFollowsUser(prefs::kAccessibilityLargeCursorEnabled,
251 recommended_prefs_->SetBoolean(prefs::kAccessibilityLargeCursorEnabled,
253 EXPECT_FALSE(RestoreTimerIsRunning());
254 VerifyPrefFollowsRecommendation(prefs::kAccessibilityLargeCursorEnabled,
257 VerifyPrefFollowsUser(prefs::kAccessibilitySpokenFeedbackEnabled,
259 recommended_prefs_->SetBoolean(prefs::kAccessibilitySpokenFeedbackEnabled,
261 EXPECT_FALSE(RestoreTimerIsRunning());
262 VerifyPrefFollowsRecommendation(prefs::kAccessibilitySpokenFeedbackEnabled,
265 VerifyPrefFollowsUser(prefs::kAccessibilityHighContrastEnabled,
267 recommended_prefs_->SetBoolean(prefs::kAccessibilityHighContrastEnabled,
269 EXPECT_FALSE(RestoreTimerIsRunning());
270 VerifyPrefFollowsRecommendation(prefs::kAccessibilityHighContrastEnabled,
273 VerifyPrefFollowsUser(prefs::kAccessibilityScreenMagnifierEnabled,
275 recommended_prefs_->SetBoolean(prefs::kAccessibilityScreenMagnifierEnabled,
277 EXPECT_FALSE(RestoreTimerIsRunning());
278 VerifyPrefFollowsRecommendation(prefs::kAccessibilityScreenMagnifierEnabled,
281 VerifyPrefFollowsUser(prefs::kAccessibilityVirtualKeyboardEnabled,
283 recommended_prefs_->SetBoolean(prefs::kAccessibilityVirtualKeyboardEnabled,
285 EXPECT_FALSE(RestoreTimerIsRunning());
286 VerifyPrefFollowsRecommendation(prefs::kAccessibilityVirtualKeyboardEnabled,
290 // Verifies that if no recommended values have been set and user settings
291 // change, the user settings are not cleared immediately and no timer is started
292 // that will clear the user settings eventually.
293 TEST_F(PolicyRecommendationRestorerTest, DoNothingOnUserChange) {
294 ConnectToSigninPrefService();
296 // a11y mono audio is not observing recommended values in production.
297 prefs_->SetBoolean(prefs::kAccessibilityMonoAudioEnabled, true);
298 VerifyPrefFollowsUser(prefs::kAccessibilityMonoAudioEnabled,
300 EXPECT_FALSE(RestoreTimerIsRunning());
303 TEST_F(PolicyRecommendationRestorerTest, RestoreOnUserChange) {
304 SetRecommendedValues();
305 ConnectToSigninPrefService();
307 EXPECT_FALSE(RestoreTimerIsRunning());
308 prefs_->SetBoolean(prefs::kAccessibilityLargeCursorEnabled, true);
309 VerifyPrefFollowsUser(prefs::kAccessibilityLargeCursorEnabled,
311 EXPECT_TRUE(TriggerRestoreTimer());
312 VerifyPrefFollowsRecommendation(prefs::kAccessibilityLargeCursorEnabled,
315 EXPECT_FALSE(RestoreTimerIsRunning());
316 prefs_->SetBoolean(prefs::kAccessibilitySpokenFeedbackEnabled, true);
317 VerifyPrefFollowsUser(prefs::kAccessibilitySpokenFeedbackEnabled,
319 EXPECT_TRUE(TriggerRestoreTimer());
320 VerifyPrefFollowsRecommendation(prefs::kAccessibilitySpokenFeedbackEnabled,
323 EXPECT_FALSE(RestoreTimerIsRunning());
324 prefs_->SetBoolean(prefs::kAccessibilityHighContrastEnabled, true);
325 VerifyPrefFollowsUser(prefs::kAccessibilityHighContrastEnabled,
327 EXPECT_TRUE(TriggerRestoreTimer());
328 VerifyPrefFollowsRecommendation(prefs::kAccessibilityHighContrastEnabled,
331 EXPECT_FALSE(RestoreTimerIsRunning());
332 prefs_->SetBoolean(prefs::kAccessibilityScreenMagnifierEnabled, true);
333 VerifyPrefFollowsUser(prefs::kAccessibilityScreenMagnifierEnabled,
335 EXPECT_TRUE(TriggerRestoreTimer());
336 VerifyPrefFollowsRecommendation(prefs::kAccessibilityScreenMagnifierEnabled,
339 EXPECT_FALSE(RestoreTimerIsRunning());
340 prefs_->SetBoolean(prefs::kAccessibilityVirtualKeyboardEnabled, true);
341 VerifyPrefFollowsUser(prefs::kAccessibilityVirtualKeyboardEnabled,
343 EXPECT_TRUE(TriggerRestoreTimer());
344 VerifyPrefFollowsRecommendation(prefs::kAccessibilityVirtualKeyboardEnabled,
347 EXPECT_FALSE(RestoreTimerIsRunning());
350 // Verifies that if recommended values have not been set, user settings have
351 // changed and a session is then started, the user settings are not cleared
353 TEST_F(PolicyRecommendationRestorerTest, DoNothingOnSessionStart) {
354 ConnectToSigninPrefService();
357 SimulateUserLogin("user@test.com");
358 VerifyPrefsFollowUser();
359 EXPECT_FALSE(RestoreTimerIsRunning());
362 // Verifies that user activity resets the timer which clears user settings.
363 TEST_F(PolicyRecommendationRestorerTest, UserActivityResetsTimer) {
364 recommended_prefs_->SetBoolean(prefs::kAccessibilityLargeCursorEnabled,
366 ConnectToSigninPrefService();
368 prefs_->SetBoolean(prefs::kAccessibilityLargeCursorEnabled, true);
369 EXPECT_TRUE(RestoreTimerIsRunning());
371 // Notify that there is user activity.
372 restorer_->OnUserActivity(nullptr);
373 VerifyPrefFollowsUser(prefs::kAccessibilityLargeCursorEnabled,
376 // Trigger reset timer to timeout.
377 EXPECT_TRUE(TriggerRestoreTimer());
378 VerifyPrefFollowsRecommendation(prefs::kAccessibilityLargeCursorEnabled,
380 EXPECT_FALSE(RestoreTimerIsRunning());