Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(147)

Side by Side Diff: chrome/browser/policy/cloud_policy_refresh_scheduler.cc

Issue 12189011: Split up chrome/browser/policy subdirectory (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase, add chrome/browser/chromeos/policy/OWNERS Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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 "chrome/browser/policy/cloud_policy_refresh_scheduler.h"
6
7 #include <algorithm>
8
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/sequenced_task_runner.h"
13 #include "base/time/default_tick_clock.h"
14 #include "base/time/tick_clock.h"
15 #include "chrome/browser/policy/cloud_policy_constants.h"
16 #include "chrome/common/chrome_notification_types.h"
17 #include "content/public/browser/notification_details.h"
18
19 namespace policy {
20
21 namespace {
22
23 // The maximum rate at which to refresh policies.
24 const size_t kMaxRefreshesPerHour = 5;
25
26 } // namespace
27
28 const int64 CloudPolicyRefreshScheduler::kDefaultRefreshDelayMs =
29 3 * 60 * 60 * 1000; // 3 hours.
30 const int64 CloudPolicyRefreshScheduler::kUnmanagedRefreshDelayMs =
31 24 * 60 * 60 * 1000; // 1 day.
32 const int64 CloudPolicyRefreshScheduler::kInitialErrorRetryDelayMs =
33 5 * 60 * 1000; // 5 minutes.
34 const int64 CloudPolicyRefreshScheduler::kRefreshDelayMinMs =
35 30 * 60 * 1000; // 30 minutes.
36 const int64 CloudPolicyRefreshScheduler::kRefreshDelayMaxMs =
37 24 * 60 * 60 * 1000; // 1 day.
38
39 CloudPolicyRefreshScheduler::CloudPolicyRefreshScheduler(
40 CloudPolicyClient* client,
41 CloudPolicyStore* store,
42 const scoped_refptr<base::SequencedTaskRunner>& task_runner)
43 : client_(client),
44 store_(store),
45 task_runner_(task_runner),
46 error_retry_delay_ms_(kInitialErrorRetryDelayMs),
47 refresh_delay_ms_(kDefaultRefreshDelayMs),
48 rate_limiter_(kMaxRefreshesPerHour,
49 base::TimeDelta::FromHours(1),
50 base::Bind(&CloudPolicyRefreshScheduler::RefreshNow,
51 base::Unretained(this)),
52 task_runner_,
53 scoped_ptr<base::TickClock>(new base::DefaultTickClock())) {
54 client_->AddObserver(this);
55 store_->AddObserver(this);
56 net::NetworkChangeNotifier::AddIPAddressObserver(this);
57
58 UpdateLastRefreshFromPolicy();
59 ScheduleRefresh();
60 }
61
62 CloudPolicyRefreshScheduler::~CloudPolicyRefreshScheduler() {
63 store_->RemoveObserver(this);
64 client_->RemoveObserver(this);
65 net::NetworkChangeNotifier::RemoveIPAddressObserver(this);
66 }
67
68 void CloudPolicyRefreshScheduler::SetRefreshDelay(int64 refresh_delay) {
69 refresh_delay_ms_ = std::min(std::max(refresh_delay, kRefreshDelayMinMs),
70 kRefreshDelayMaxMs);
71 ScheduleRefresh();
72 }
73
74 void CloudPolicyRefreshScheduler::RefreshSoon() {
75 rate_limiter_.PostRequest();
76 }
77
78 void CloudPolicyRefreshScheduler::OnPolicyFetched(CloudPolicyClient* client) {
79 error_retry_delay_ms_ = kInitialErrorRetryDelayMs;
80
81 // Schedule the next refresh.
82 last_refresh_ = base::Time::NowFromSystemTime();
83 ScheduleRefresh();
84 }
85
86 void CloudPolicyRefreshScheduler::OnRegistrationStateChanged(
87 CloudPolicyClient* client) {
88 error_retry_delay_ms_ = kInitialErrorRetryDelayMs;
89
90 // The client might have registered, so trigger an immediate refresh.
91 RefreshNow();
92 }
93
94 void CloudPolicyRefreshScheduler::OnClientError(CloudPolicyClient* client) {
95 // Save the status for below.
96 DeviceManagementStatus status = client_->status();
97
98 // Schedule an error retry if applicable.
99 last_refresh_ = base::Time::NowFromSystemTime();
100 ScheduleRefresh();
101
102 // Update the retry delay.
103 if (client->is_registered() &&
104 (status == DM_STATUS_REQUEST_FAILED ||
105 status == DM_STATUS_TEMPORARY_UNAVAILABLE)) {
106 error_retry_delay_ms_ = std::min(error_retry_delay_ms_ * 2,
107 refresh_delay_ms_);
108 } else {
109 error_retry_delay_ms_ = kInitialErrorRetryDelayMs;
110 }
111 }
112
113 void CloudPolicyRefreshScheduler::OnStoreLoaded(CloudPolicyStore* store) {
114 UpdateLastRefreshFromPolicy();
115
116 // Re-schedule the next refresh in case the is_managed bit changed.
117 ScheduleRefresh();
118 }
119
120 void CloudPolicyRefreshScheduler::OnStoreError(CloudPolicyStore* store) {
121 // If |store_| fails, the is_managed bit that it provides may become stale.
122 // The best guess in that situation is to assume is_managed didn't change and
123 // continue using the stale information. Thus, no specific response to a store
124 // error is required. NB: Changes to is_managed fire OnStoreLoaded().
125 }
126
127 void CloudPolicyRefreshScheduler::OnIPAddressChanged() {
128 if (client_->status() == DM_STATUS_REQUEST_FAILED)
129 RefreshAfter(0);
130 }
131
132 void CloudPolicyRefreshScheduler::UpdateLastRefreshFromPolicy() {
133 if (!last_refresh_.is_null())
134 return;
135
136 // If the client has already fetched policy, assume that happened recently. If
137 // that assumption ever breaks, the proper thing to do probably is to move the
138 // |last_refresh_| bookkeeping to CloudPolicyClient.
139 if (!client_->responses().empty()) {
140 last_refresh_ = base::Time::NowFromSystemTime();
141 return;
142 }
143
144 // If there is a cached non-managed response, make sure to only re-query the
145 // server after kUnmanagedRefreshDelayMs. NB: For existing policy, an
146 // immediate refresh is intentional.
147 if (store_->has_policy() && !store_->is_managed()) {
148 last_refresh_ =
149 base::Time::UnixEpoch() +
150 base::TimeDelta::FromMilliseconds(store_->policy()->timestamp());
151 }
152 }
153
154 void CloudPolicyRefreshScheduler::RefreshNow() {
155 last_refresh_ = base::Time();
156 ScheduleRefresh();
157 }
158
159 void CloudPolicyRefreshScheduler::ScheduleRefresh() {
160 // If the client isn't registered, there is nothing to do.
161 if (!client_->is_registered()) {
162 refresh_callback_.Cancel();
163 return;
164 }
165
166 // If there is a registration, go by the client's status. That will tell us
167 // what the appropriate refresh delay should be.
168 switch (client_->status()) {
169 case DM_STATUS_SUCCESS:
170 if (store_->is_managed())
171 RefreshAfter(refresh_delay_ms_);
172 else
173 RefreshAfter(kUnmanagedRefreshDelayMs);
174 return;
175 case DM_STATUS_SERVICE_ACTIVATION_PENDING:
176 case DM_STATUS_SERVICE_POLICY_NOT_FOUND:
177 RefreshAfter(refresh_delay_ms_);
178 return;
179 case DM_STATUS_REQUEST_FAILED:
180 case DM_STATUS_TEMPORARY_UNAVAILABLE:
181 RefreshAfter(error_retry_delay_ms_);
182 return;
183 case DM_STATUS_REQUEST_INVALID:
184 case DM_STATUS_HTTP_STATUS_ERROR:
185 case DM_STATUS_RESPONSE_DECODING_ERROR:
186 case DM_STATUS_SERVICE_MANAGEMENT_NOT_SUPPORTED:
187 RefreshAfter(kUnmanagedRefreshDelayMs);
188 return;
189 case DM_STATUS_SERVICE_MANAGEMENT_TOKEN_INVALID:
190 case DM_STATUS_SERVICE_DEVICE_NOT_FOUND:
191 case DM_STATUS_SERVICE_INVALID_SERIAL_NUMBER:
192 case DM_STATUS_SERVICE_DEVICE_ID_CONFLICT:
193 case DM_STATUS_SERVICE_MISSING_LICENSES:
194 // Need a re-registration, no use in retrying.
195 return;
196 }
197
198 NOTREACHED() << "Invalid client status " << client_->status();
199 RefreshAfter(kUnmanagedRefreshDelayMs);
200 }
201
202 void CloudPolicyRefreshScheduler::PerformRefresh() {
203 if (client_->is_registered()) {
204 // Update |last_refresh_| so another fetch isn't triggered inadvertently.
205 last_refresh_ = base::Time::NowFromSystemTime();
206
207 // The result of this operation will be reported through a callback, at
208 // which point the next refresh will be scheduled.
209 client_->FetchPolicy();
210 return;
211 }
212
213 // This should never happen, as the registration change should have been
214 // handled via OnRegistrationStateChanged().
215 NOTREACHED();
216 }
217
218 void CloudPolicyRefreshScheduler::RefreshAfter(int delta_ms) {
219 base::TimeDelta delta(base::TimeDelta::FromMilliseconds(delta_ms));
220 refresh_callback_.Cancel();
221
222 // Schedule the callback.
223 base::TimeDelta delay =
224 std::max((last_refresh_ + delta) - base::Time::NowFromSystemTime(),
225 base::TimeDelta());
226 refresh_callback_.Reset(
227 base::Bind(&CloudPolicyRefreshScheduler::PerformRefresh,
228 base::Unretained(this)));
229 task_runner_->PostDelayedTask(FROM_HERE, refresh_callback_.callback(), delay);
230 }
231
232 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698