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

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

Powered by Google App Engine
This is Rietveld 408576698