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

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

Issue 5219006: Refresh policies from DM server periodically (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 10 years, 1 month 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
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/policy/device_management_policy_provider.h" 5 #include "chrome/browser/policy/device_management_policy_provider.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/file_util.h" 8 #include "base/file_util.h"
9 #include "base/path_service.h" 9 #include "base/path_service.h"
10 #include "base/rand_util.h"
10 #include "base/task.h" 11 #include "base/task.h"
11 #include "base/time.h"
12 #include "chrome/browser/browser_thread.h" 12 #include "chrome/browser/browser_thread.h"
13 #include "chrome/browser/policy/device_management_backend.h" 13 #include "chrome/browser/policy/device_management_backend.h"
14 #include "chrome/browser/policy/device_management_backend_impl.h" 14 #include "chrome/browser/policy/device_management_backend_impl.h"
15 #include "chrome/browser/policy/device_management_policy_cache.h" 15 #include "chrome/browser/policy/device_management_policy_cache.h"
16 #include "chrome/browser/policy/device_token_fetcher.h"
17 #include "chrome/common/chrome_paths.h" 16 #include "chrome/common/chrome_paths.h"
18 #include "chrome/common/chrome_switches.h" 17 #include "chrome/common/chrome_switches.h"
19 #include "chrome/common/notification_service.h" 18 #include "chrome/common/notification_service.h"
20 #include "chrome/common/notification_type.h" 19 #include "chrome/common/notification_type.h"
21 20
22 namespace { 21 namespace {
23 22
24 const char kChromePolicyScope[] = "cros/device"; 23 const char kChromePolicyScope[] = "cros/device";
25 const char kChromeDevicePolicySettingKey[] = "chrome-policy"; 24 const char kChromeDevicePolicySettingKey[] = "chrome-policy";
26 const int64 kPolicyRefreshRateInMinutes = 3 * 60; // 3 hours 25 const int64 kPolicyRefreshRateInMilliseconds = 3 * 60 * 60 * 1000; // 3 hours
26 const int64 kPolicyRefreshMaxEarlierInMilliseconds = 20 * 60 * 1000; // 20 mins
27 // These are the base values for delays before retrying after an error. They
28 // will be doubled each time they are used.
29 const int64 kPolicyRefreshErrorDelayInMilliseconds = 3 * 1000; // 3 seconds
30 const int64 kDeviceTokenRefreshErrorDelayInMilliseconds = 3 * 1000;
27 31
28 } // namespace 32 } // namespace
29 33
30 namespace policy { 34 namespace policy {
31 35
32 // Ensures that the portion of the policy provider implementation that requires 36 // Ensures that the portion of the policy provider implementation that requires
33 // the IOThread is deferred until the IOThread is fully initialized. The policy 37 // the IOThread is deferred until the IOThread is fully initialized. The policy
34 // provider posts this task on the UI thread during its constructor, thereby 38 // provider posts this task on the UI thread during its constructor, thereby
35 // guaranteeing that the code won't get executed until after the UI and IO 39 // guaranteeing that the code won't get executed until after the UI and IO
36 // threads are fully constructed. 40 // threads are fully constructed.
37 class DeviceManagementPolicyProvider::InitializeAfterIOThreadExistsTask 41 class DeviceManagementPolicyProvider::InitializeAfterIOThreadExistsTask
38 : public Task { 42 : public Task {
39 public: 43 public:
40 explicit InitializeAfterIOThreadExistsTask( 44 explicit InitializeAfterIOThreadExistsTask(
41 base::WeakPtr<DeviceManagementPolicyProvider> provider) 45 base::WeakPtr<DeviceManagementPolicyProvider> provider)
42 : provider_(provider) { 46 : provider_(provider) {
43 } 47 }
44 48
45 // Task implementation: 49 // Task implementation:
46 virtual void Run() { 50 virtual void Run() {
47 DeviceManagementPolicyProvider* provider = provider_.get(); 51 DeviceManagementPolicyProvider* provider = provider_.get();
48 if (provider) 52 if (provider)
49 provider->InitializeAfterIOThreadExists(); 53 provider->InitializeAfterIOThreadExists();
50 } 54 }
51 55
52 private: 56 private:
53 base::WeakPtr<DeviceManagementPolicyProvider> provider_; 57 base::WeakPtr<DeviceManagementPolicyProvider> provider_;
54 }; 58 };
55 59
60 class DeviceManagementPolicyProvider::RefreshTask : public Task {
61 public:
62 explicit RefreshTask(base::WeakPtr<DeviceManagementPolicyProvider> provider)
63 : provider_(provider) {}
64
65 // Task implementation:
66 virtual void Run() {
67 DeviceManagementPolicyProvider* provider = provider_.get();
68 if (provider)
69 provider->RefreshTaskExecute();
70 }
71
72 private:
73 base::WeakPtr<DeviceManagementPolicyProvider> provider_;
74 };
75
56 DeviceManagementPolicyProvider::DeviceManagementPolicyProvider( 76 DeviceManagementPolicyProvider::DeviceManagementPolicyProvider(
57 const ConfigurationPolicyProvider::PolicyDefinitionList* policy_list, 77 const ConfigurationPolicyProvider::PolicyDefinitionList* policy_list,
58 DeviceManagementBackend* backend, 78 DeviceManagementBackend* backend,
59 TokenService* token_service, 79 TokenService* token_service,
60 const FilePath& storage_dir) 80 const FilePath& storage_dir)
61 : ConfigurationPolicyProvider(policy_list), 81 : ConfigurationPolicyProvider(policy_list),
62 backend_(backend), 82 backend_(backend),
63 token_service_(token_service), 83 token_service_(token_service),
64 storage_dir_(GetOrCreateDeviceManagementDir(storage_dir)), 84 storage_dir_(GetOrCreateDeviceManagementDir(storage_dir)),
65 policy_request_pending_(false) { 85 policy_request_pending_(false),
86 refresh_task_pending_(false),
87 policy_refresh_rate_ms_(kPolicyRefreshRateInMilliseconds),
88 policy_refresh_max_earlier_ms_(kPolicyRefreshMaxEarlierInMilliseconds),
89 policy_refresh_error_delay_ms_(kPolicyRefreshErrorDelayInMilliseconds),
90 token_fetch_error_delay_ms_(kDeviceTokenRefreshErrorDelayInMilliseconds) {
66 Initialize(); 91 Initialize();
67 } 92 }
68 93
69 DeviceManagementPolicyProvider::~DeviceManagementPolicyProvider() {} 94 DeviceManagementPolicyProvider::~DeviceManagementPolicyProvider() {}
70 95
71 bool DeviceManagementPolicyProvider::Provide( 96 bool DeviceManagementPolicyProvider::Provide(
72 ConfigurationPolicyStoreInterface* policy_store) { 97 ConfigurationPolicyStoreInterface* policy_store) {
73 scoped_ptr<DictionaryValue> policies(cache_->GetPolicy()); 98 scoped_ptr<DictionaryValue> policies(cache_->GetPolicy());
74 DecodePolicyValueTree(policies.get(), policy_store); 99 DecodePolicyValueTree(policies.get(), policy_store);
75 return true; 100 return true;
76 } 101 }
77 102
78 void DeviceManagementPolicyProvider::Observe(
79 NotificationType type,
80 const NotificationSource& source,
81 const NotificationDetails& details) {
82 if (type == NotificationType::DEVICE_TOKEN_AVAILABLE) {
83 if (token_fetcher_.get() == Source<DeviceTokenFetcher>(source).ptr() &&
84 !policy_request_pending_ &&
85 IsPolicyStale()) {
86 SendPolicyRequest();
87 }
88 } else {
89 NOTREACHED();
90 }
91 }
92
93 void DeviceManagementPolicyProvider::HandlePolicyResponse( 103 void DeviceManagementPolicyProvider::HandlePolicyResponse(
94 const em::DevicePolicyResponse& response) { 104 const em::DevicePolicyResponse& response) {
95 cache_->SetPolicy(response); 105 if (cache_->SetPolicy(response))
96 NotifyStoreOfPolicyChange(); 106 NotifyStoreOfPolicyChange();
97 policy_request_pending_ = false; 107 policy_request_pending_ = false;
108 // Reset the error delay since policy fetching succeeded this time.
109 policy_refresh_error_delay_ms_ = kPolicyRefreshErrorDelayInMilliseconds;
110 ScheduleRefreshTask(GetRefreshTaskDelay(
111 policy_refresh_rate_ms_, policy_refresh_max_earlier_ms_));
98 } 112 }
99 113
100 void DeviceManagementPolicyProvider::OnError( 114 void DeviceManagementPolicyProvider::OnError(
101 DeviceManagementBackend::ErrorCode code) { 115 DeviceManagementBackend::ErrorCode code) {
102 LOG(WARNING) << "could not provide policy from the device manager (error = " 116 LOG(WARNING) << "Could not provide policy from the device manager (error = "
103 << code << ")"; 117 << code << ")";
danno 2010/11/22 13:47:50 you may want to add a "retrying in x millis ...."
Jakob Kummerow (corp) 2010/11/22 16:56:08 Done.
104 policy_request_pending_ = false; 118 policy_request_pending_ = false;
105 // TODO(danno): do something sensible in the error case, perhaps retry later? 119 policy_refresh_error_delay_ms_ *= 2;
120 if (policy_refresh_rate_ms_ &&
121 policy_refresh_rate_ms_ < policy_refresh_error_delay_ms_) {
122 policy_refresh_error_delay_ms_ = policy_refresh_rate_ms_;
123 }
124 ScheduleRefreshTask(policy_refresh_error_delay_ms_);
125 }
126
127 void DeviceManagementPolicyProvider::OnTokenSuccess() {
128 if (policy_request_pending_)
129 return;
130 SendPolicyRequest();
131 }
132
133 void DeviceManagementPolicyProvider::OnTokenError() {
134 LOG(WARNING) << "Could not retrieve device token.";
135 token_fetch_error_delay_ms_ *= 2;
136 if (token_fetch_error_delay_ms_ > policy_refresh_rate_ms_)
137 token_fetch_error_delay_ms_ = policy_refresh_rate_ms_;
138 ScheduleRefreshTask(token_fetch_error_delay_ms_);
danno 2010/11/22 13:47:50 Perhaps a second, token-specific task to address m
Jakob Kummerow (corp) 2010/11/22 16:56:08 See my answer below.
106 } 139 }
107 140
108 void DeviceManagementPolicyProvider::Shutdown() { 141 void DeviceManagementPolicyProvider::Shutdown() {
109 token_service_ = NULL; 142 token_service_ = NULL;
110 if (token_fetcher_) 143 if (token_fetcher_)
111 token_fetcher_->Shutdown(); 144 token_fetcher_->Shutdown();
112 } 145 }
113 146
114 DeviceManagementBackend* DeviceManagementPolicyProvider::GetBackend() { 147 DeviceManagementBackend* DeviceManagementPolicyProvider::GetBackend() {
115 if (!backend_.get()) { 148 if (!backend_.get()) {
116 backend_.reset(new DeviceManagementBackendImpl( 149 backend_.reset(new DeviceManagementBackendImpl(
117 GetDeviceManagementURL())); 150 GetDeviceManagementURL()));
118 } 151 }
119 return backend_.get(); 152 return backend_.get();
120 } 153 }
121 154
122 void DeviceManagementPolicyProvider::Initialize() { 155 void DeviceManagementPolicyProvider::Initialize() {
123 registrar_.Add(this,
124 NotificationType::DEVICE_TOKEN_AVAILABLE,
125 NotificationService::AllSources());
126
127 const FilePath policy_path = storage_dir_.Append( 156 const FilePath policy_path = storage_dir_.Append(
128 FILE_PATH_LITERAL("Policy")); 157 FILE_PATH_LITERAL("Policy"));
129 cache_.reset(new DeviceManagementPolicyCache(policy_path)); 158 cache_.reset(new DeviceManagementPolicyCache(policy_path));
130 cache_->LoadPolicyFromFile(); 159 cache_->LoadPolicyFromFile();
131 160
132 // Defer initialization that requires the IOThread until after the IOThread 161 // Defer initialization that requires the IOThread until after the IOThread
133 // has been initialized. 162 // has been initialized.
134 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 163 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
135 new InitializeAfterIOThreadExistsTask(AsWeakPtr())); 164 new InitializeAfterIOThreadExistsTask(AsWeakPtr()));
136 } 165 }
137 166
138 void DeviceManagementPolicyProvider::InitializeAfterIOThreadExists() { 167 void DeviceManagementPolicyProvider::InitializeAfterIOThreadExists() {
139 const FilePath token_path = storage_dir_.Append( 168 const FilePath token_path = storage_dir_.Append(
140 FILE_PATH_LITERAL("Token")); 169 FILE_PATH_LITERAL("Token"));
141 if (token_service_) { 170 if (token_service_) {
142 token_fetcher_ = 171 token_fetcher_ =
143 new DeviceTokenFetcher(GetBackend(), token_service_, token_path); 172 new DeviceTokenFetcher(GetBackend(), token_service_, token_path);
173 token_fetcher_->AddObserver(this);
danno 2010/11/22 13:47:50 What ensures that the observer gets removed? You p
Jakob Kummerow (corp) 2010/11/22 16:56:08 Done. Added a registrar mechanism.
144 token_fetcher_->StartFetching(); 174 token_fetcher_->StartFetching();
145 } 175 }
146 } 176 }
147 177
148 void DeviceManagementPolicyProvider::SendPolicyRequest() { 178 void DeviceManagementPolicyProvider::SendPolicyRequest() {
149 if (!policy_request_pending_) { 179 if (!policy_request_pending_) {
180 policy_request_pending_ = true;
150 em::DevicePolicyRequest policy_request; 181 em::DevicePolicyRequest policy_request;
151 policy_request.set_policy_scope(kChromePolicyScope); 182 policy_request.set_policy_scope(kChromePolicyScope);
152 em::DevicePolicySettingRequest* setting = 183 em::DevicePolicySettingRequest* setting =
153 policy_request.add_setting_request(); 184 policy_request.add_setting_request();
154 setting->set_key(kChromeDevicePolicySettingKey); 185 setting->set_key(kChromeDevicePolicySettingKey);
155 GetBackend()->ProcessPolicyRequest(token_fetcher_->GetDeviceToken(), 186 GetBackend()->ProcessPolicyRequest(token_fetcher_->GetDeviceToken(),
156 policy_request, 187 policy_request,
157 this); 188 this);
158 policy_request_pending_ = true; 189 } else {
190 LOG(WARNING) << "Not sending another PolicyRequest.";
159 } 191 }
160 } 192 }
161 193
162 bool DeviceManagementPolicyProvider::IsPolicyStale() const { 194 void DeviceManagementPolicyProvider::RefreshTaskExecute() {
danno 2010/11/22 13:47:50 Combining both the token request and the policy re
Jakob Kummerow (corp) 2010/11/22 16:56:08 I don't see what's wrong with a task that assesses
163 base::Time now(base::Time::NowFromSystemTime()); 195 refresh_task_pending_ = false;
danno 2010/11/22 13:47:50 DCHECK(refresh_task_pending_) before?
Jakob Kummerow (corp) 2010/11/22 16:56:08 Done.
164 base::Time last_policy_refresh_time = 196 // If there is no valid device token, the token_fetcher_ apparently failed,
165 cache_->last_policy_refresh_time(); 197 // so it must be restarted.
166 base::Time policy_expiration_time = 198 if (!token_fetcher_->IsTokenValid()) {
167 last_policy_refresh_time + base::TimeDelta::FromMinutes( 199 if (token_fetcher_->IsTokenPending()) {
168 kPolicyRefreshRateInMinutes); 200 NOTREACHED();
169 return (now > policy_expiration_time); 201 return;
202 }
203 token_fetcher_->Restart();
204 return;
205 }
206 // If there is a device token, just refresh policies.
207 SendPolicyRequest();
208 }
209
210 void DeviceManagementPolicyProvider::ScheduleRefreshTask(
211 int64 delay_in_milliseconds) {
212 // This check is simply a safeguard, the situation currently cannot happen.
213 if (refresh_task_pending_) {
214 NOTREACHED();
215 return;
216 }
217 refresh_task_pending_ = true;
218 BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
219 new RefreshTask(AsWeakPtr()),
220 delay_in_milliseconds);
170 } 221 }
171 222
172 // static 223 // static
224 int64 DeviceManagementPolicyProvider::GetRefreshTaskDelay(
225 int64 policy_refresh_rate_ms,
226 int64 policy_refresh_max_random_earlier_ms) {
227 if (policy_refresh_max_random_earlier_ms)
228 policy_refresh_rate_ms -=
229 base::RandGenerator(policy_refresh_max_random_earlier_ms);
230 return policy_refresh_rate_ms;
231 }
232
233 // static
173 std::string DeviceManagementPolicyProvider::GetDeviceManagementURL() { 234 std::string DeviceManagementPolicyProvider::GetDeviceManagementURL() {
174 return CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 235 return CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
175 switches::kDeviceManagementUrl); 236 switches::kDeviceManagementUrl);
176 } 237 }
177 238
178 // static 239 // static
179 FilePath DeviceManagementPolicyProvider::GetOrCreateDeviceManagementDir( 240 FilePath DeviceManagementPolicyProvider::GetOrCreateDeviceManagementDir(
180 const FilePath& user_data_dir) { 241 const FilePath& user_data_dir) {
181 const FilePath device_management_dir = user_data_dir.Append( 242 const FilePath device_management_dir = user_data_dir.Append(
182 FILE_PATH_LITERAL("Device Management")); 243 FILE_PATH_LITERAL("Device Management"));
183 if (!file_util::DirectoryExists(device_management_dir)) { 244 if (!file_util::DirectoryExists(device_management_dir)) {
184 if (!file_util::CreateDirectory(device_management_dir)) 245 if (!file_util::CreateDirectory(device_management_dir))
185 NOTREACHED(); 246 NOTREACHED();
186 } 247 }
187 return device_management_dir; 248 return device_management_dir;
188 } 249 }
189 250
190 } // namespace policy 251 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698