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

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

Powered by Google App Engine
This is Rietveld 408576698