OLD | NEW |
| (Empty) |
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/shell.h" | |
8 #include "ash/wm/user_activity_detector.h" | |
9 #include "base/bind.h" | |
10 #include "base/bind_helpers.h" | |
11 #include "base/location.h" | |
12 #include "base/logging.h" | |
13 #include "base/prefs/pref_service.h" | |
14 #include "base/time.h" | |
15 #include "base/values.h" | |
16 #include "chrome/browser/chromeos/profiles/profile_helper.h" | |
17 #include "chrome/browser/profiles/profile.h" | |
18 #include "chrome/common/chrome_notification_types.h" | |
19 #include "chrome/common/pref_names.h" | |
20 #include "content/public/browser/notification_details.h" | |
21 #include "content/public/browser/notification_service.h" | |
22 #include "content/public/browser/notification_source.h" | |
23 | |
24 namespace policy { | |
25 | |
26 namespace { | |
27 // The amount of idle time after which recommended values are restored. | |
28 const int kRestoreDelayInMs = 60 * 1000; // 1 minute. | |
29 } // namespace | |
30 | |
31 RecommendationRestorer::RecommendationRestorer(Profile* profile) | |
32 : logged_in_(false) { | |
33 if (!chromeos::ProfileHelper::IsSigninProfile(profile)) | |
34 return; | |
35 | |
36 pref_change_registrar_.Init(profile->GetPrefs()); | |
37 pref_change_registrar_.Add(prefs::kLargeCursorEnabled, | |
38 base::Bind(&RecommendationRestorer::Restore, | |
39 base::Unretained(this), true)); | |
40 pref_change_registrar_.Add(prefs::kSpokenFeedbackEnabled, | |
41 base::Bind(&RecommendationRestorer::Restore, | |
42 base::Unretained(this), true)); | |
43 pref_change_registrar_.Add(prefs::kHighContrastEnabled, | |
44 base::Bind(&RecommendationRestorer::Restore, | |
45 base::Unretained(this), true)); | |
46 pref_change_registrar_.Add(prefs::kScreenMagnifierEnabled, | |
47 base::Bind(&RecommendationRestorer::Restore, | |
48 base::Unretained(this), true)); | |
49 pref_change_registrar_.Add(prefs::kScreenMagnifierType, | |
50 base::Bind(&RecommendationRestorer::Restore, | |
51 base::Unretained(this), true)); | |
52 | |
53 notification_registrar_.Add(this, chrome::NOTIFICATION_LOGIN_USER_CHANGED, | |
54 content::NotificationService::AllSources()); | |
55 | |
56 RestoreAll(); | |
57 } | |
58 | |
59 RecommendationRestorer::~RecommendationRestorer() { | |
60 } | |
61 | |
62 void RecommendationRestorer::Shutdown() { | |
63 StopTimer(); | |
64 pref_change_registrar_.RemoveAll(); | |
65 notification_registrar_.RemoveAll(); | |
66 } | |
67 | |
68 void RecommendationRestorer::Observe( | |
69 int type, | |
70 const content::NotificationSource& source, | |
71 const content::NotificationDetails& details) { | |
72 if (type == chrome::NOTIFICATION_LOGIN_USER_CHANGED) { | |
73 logged_in_ = true; | |
74 notification_registrar_.RemoveAll(); | |
75 StopTimer(); | |
76 RestoreAll(); | |
77 } else { | |
78 NOTREACHED(); | |
79 } | |
80 } | |
81 | |
82 void RecommendationRestorer::OnUserActivity() { | |
83 if (restore_timer_.IsRunning()) | |
84 restore_timer_.Reset(); | |
85 } | |
86 | |
87 void RecommendationRestorer::Restore(bool allow_delay, | |
88 const std::string& pref_name) { | |
89 const PrefService::Preference* pref = | |
90 pref_change_registrar_.prefs()->FindPreference(pref_name.c_str()); | |
91 if (!pref) { | |
92 NOTREACHED(); | |
93 return; | |
94 } | |
95 | |
96 if (!pref->GetRecommendedValue() || !pref->HasUserSetting()) | |
97 return; | |
98 | |
99 if (!logged_in_ && allow_delay) | |
100 StartTimer(); | |
101 else | |
102 pref_change_registrar_.prefs()->ClearPref(pref->name().c_str()); | |
103 } | |
104 | |
105 void RecommendationRestorer::RestoreAll() { | |
106 Restore(false, prefs::kLargeCursorEnabled); | |
107 Restore(false, prefs::kSpokenFeedbackEnabled); | |
108 Restore(false, prefs::kHighContrastEnabled); | |
109 Restore(false, prefs::kScreenMagnifierEnabled); | |
110 Restore(false, prefs::kScreenMagnifierType); | |
111 } | |
112 | |
113 void RecommendationRestorer::StartTimer() { | |
114 // Listen for user activity so that the timer can be reset while the user is | |
115 // active, causing it to fire only when the user remains idle for | |
116 // |kRestoreDelayInMs|. | |
117 if (ash::Shell::HasInstance()) { | |
118 ash::UserActivityDetector* user_activity_detector = | |
119 ash::Shell::GetInstance()->user_activity_detector(); | |
120 if (!user_activity_detector->HasObserver(this)) | |
121 user_activity_detector->AddObserver(this); | |
122 } | |
123 | |
124 // There should be a separate timer for each pref. However, in the common | |
125 // case of the user changing settings, a single timer is sufficient. This is | |
126 // because a change initiated by the user implies user activity, so that even | |
127 // if there was a separate timer per pref, they would all be reset at that | |
128 // point, causing them to fire at exactly the same time. In the much rarer | |
129 // case of a recommended value changing, a single timer is a close | |
130 // approximation of the behavior that would be obtained by resetting the timer | |
131 // for the affected pref only. | |
132 restore_timer_.Start(FROM_HERE, | |
133 base::TimeDelta::FromMilliseconds(kRestoreDelayInMs), | |
134 base::Bind(&RecommendationRestorer::RestoreAll, | |
135 base::Unretained(this))); | |
136 } | |
137 | |
138 void RecommendationRestorer::StopTimer() { | |
139 restore_timer_.Stop(); | |
140 if (ash::Shell::HasInstance()) | |
141 ash::Shell::GetInstance()->user_activity_detector()->RemoveObserver(this); | |
142 } | |
143 | |
144 } // namespace policy | |
OLD | NEW |