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

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

Issue 5331008: Persist 'this device is not managed' information (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 10 years 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/rand_util.h"
11 #include "base/task.h" 11 #include "base/task.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/proto/device_management_constants.h" 15 #include "chrome/browser/policy/proto/device_management_constants.h"
16 #include "chrome/browser/policy/proto/device_management_local.pb.h"
16 #include "chrome/common/chrome_paths.h" 17 #include "chrome/common/chrome_paths.h"
17 #include "chrome/common/chrome_switches.h" 18 #include "chrome/common/chrome_switches.h"
18 #include "chrome/common/notification_service.h" 19 #include "chrome/common/notification_service.h"
19 #include "chrome/common/notification_type.h" 20 #include "chrome/common/notification_type.h"
20 21
21 namespace policy { 22 namespace policy {
22 23
24 namespace em = enterprise_management;
25
23 const int64 kPolicyRefreshRateInMilliseconds = 3 * 60 * 60 * 1000; // 3 hours 26 const int64 kPolicyRefreshRateInMilliseconds = 3 * 60 * 60 * 1000; // 3 hours
24 const int64 kPolicyRefreshMaxEarlierInMilliseconds = 20 * 60 * 1000; // 20 mins 27 const int64 kPolicyRefreshMaxEarlierInMilliseconds = 20 * 60 * 1000; // 20 mins
25 // These are the base values for delays before retrying after an error. They 28 // These are the base values for delays before retrying after an error. They
26 // will be doubled each time they are used. 29 // will be doubled each time they are used.
27 const int64 kPolicyRefreshErrorDelayInMilliseconds = 3 * 1000; // 3 seconds 30 const int64 kPolicyRefreshErrorDelayInMilliseconds = 3 * 1000; // 3 seconds
28 const int64 kDeviceTokenRefreshErrorDelayInMilliseconds = 3 * 1000; 31 const int64 kDeviceTokenRefreshErrorDelayInMilliseconds = 3 * 1000;
32 // For unmanaged devices, check once per day whether they're still unmanaged.
33 const int64 kPolicyRefreshUnmanagedDeviceInMilliseconds = 24 * 60 * 60 * 1000;
34
35 const char* kDeviceTokenFilename = "Token";
36 const char* kPolicyFilename = "Policy";
37 const char* kUnmanagedDeviceMarkerFilename = "UnmanagedDevice";
danno 2010/11/25 16:35:01 It occurs to me that the information in this file
Jakob Kummerow 2010/11/26 09:17:23 Done.
29 38
30 // Ensures that the portion of the policy provider implementation that requires 39 // Ensures that the portion of the policy provider implementation that requires
31 // the IOThread is deferred until the IOThread is fully initialized. The policy 40 // the IOThread is deferred until the IOThread is fully initialized. The policy
32 // provider posts this task on the UI thread during its constructor, thereby 41 // provider posts this task on the UI thread during its constructor, thereby
33 // guaranteeing that the code won't get executed until after the UI and IO 42 // guaranteeing that the code won't get executed until after the UI and IO
34 // threads are fully constructed. 43 // threads are fully constructed.
35 class DeviceManagementPolicyProvider::InitializeAfterIOThreadExistsTask 44 class DeviceManagementPolicyProvider::InitializeAfterIOThreadExistsTask
36 : public Task { 45 : public Task {
37 public: 46 public:
38 explicit InitializeAfterIOThreadExistsTask( 47 explicit InitializeAfterIOThreadExistsTask(
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 const ConfigurationPolicyProvider::PolicyDefinitionList* policy_list, 80 const ConfigurationPolicyProvider::PolicyDefinitionList* policy_list,
72 DeviceManagementBackend* backend, 81 DeviceManagementBackend* backend,
73 TokenService* token_service, 82 TokenService* token_service,
74 const FilePath& storage_dir) 83 const FilePath& storage_dir)
75 : ConfigurationPolicyProvider(policy_list), 84 : ConfigurationPolicyProvider(policy_list),
76 backend_(backend), 85 backend_(backend),
77 token_service_(token_service), 86 token_service_(token_service),
78 storage_dir_(GetOrCreateDeviceManagementDir(storage_dir)), 87 storage_dir_(GetOrCreateDeviceManagementDir(storage_dir)),
79 policy_request_pending_(false), 88 policy_request_pending_(false),
80 refresh_task_pending_(false), 89 refresh_task_pending_(false),
90 waiting_for_initial_policies_(true),
81 policy_refresh_rate_ms_(kPolicyRefreshRateInMilliseconds), 91 policy_refresh_rate_ms_(kPolicyRefreshRateInMilliseconds),
82 policy_refresh_max_earlier_ms_(kPolicyRefreshMaxEarlierInMilliseconds), 92 policy_refresh_max_earlier_ms_(kPolicyRefreshMaxEarlierInMilliseconds),
83 policy_refresh_error_delay_ms_(kPolicyRefreshErrorDelayInMilliseconds), 93 policy_refresh_error_delay_ms_(kPolicyRefreshErrorDelayInMilliseconds),
84 token_fetch_error_delay_ms_(kDeviceTokenRefreshErrorDelayInMilliseconds) { 94 token_fetch_error_delay_ms_(kDeviceTokenRefreshErrorDelayInMilliseconds),
95 unmanaged_device_refresh_rate_ms_(
96 kPolicyRefreshUnmanagedDeviceInMilliseconds) {
85 Initialize(); 97 Initialize();
86 } 98 }
87 99
88 DeviceManagementPolicyProvider::~DeviceManagementPolicyProvider() {} 100 DeviceManagementPolicyProvider::~DeviceManagementPolicyProvider() {}
89 101
90 bool DeviceManagementPolicyProvider::Provide( 102 bool DeviceManagementPolicyProvider::Provide(
91 ConfigurationPolicyStoreInterface* policy_store) { 103 ConfigurationPolicyStoreInterface* policy_store) {
92 scoped_ptr<DictionaryValue> policies(cache_->GetPolicy()); 104 scoped_ptr<DictionaryValue> policies(cache_->GetPolicy());
93 DecodePolicyValueTree(policies.get(), policy_store); 105 DecodePolicyValueTree(policies.get(), policy_store);
94 return true; 106 return true;
95 } 107 }
96 108
97 void DeviceManagementPolicyProvider::HandlePolicyResponse( 109 void DeviceManagementPolicyProvider::HandlePolicyResponse(
98 const em::DevicePolicyResponse& response) { 110 const em::DevicePolicyResponse& response) {
99 if (cache_->SetPolicy(response)) 111 if (cache_->SetPolicy(response))
100 NotifyStoreOfPolicyChange(); 112 NotifyStoreOfPolicyChange();
101 policy_request_pending_ = false; 113 policy_request_pending_ = false;
102 // Reset the error delay since policy fetching succeeded this time. 114 // Reset the error delay since policy fetching succeeded this time.
103 policy_refresh_error_delay_ms_ = kPolicyRefreshErrorDelayInMilliseconds; 115 policy_refresh_error_delay_ms_ = kPolicyRefreshErrorDelayInMilliseconds;
104 ScheduleRefreshTask(GetRefreshTaskDelay()); 116 ScheduleRefreshTask(GetRefreshTaskDelay());
117 // Update this provider's internal waiting state, but don't notify anyone
118 // else yet (that's done by the PrefValueStore that receives the policy).
119 waiting_for_initial_policies_ = false;
105 } 120 }
106 121
107 void DeviceManagementPolicyProvider::OnError( 122 void DeviceManagementPolicyProvider::OnError(
108 DeviceManagementBackend::ErrorCode code) { 123 DeviceManagementBackend::ErrorCode code) {
109 policy_request_pending_ = false; 124 policy_request_pending_ = false;
110 LOG(WARNING) << "Could not provide policy from the device manager (error = " 125 LOG(WARNING) << "Could not provide policy from the device manager (error = "
111 << code << "), will retry in " 126 << code << "), will retry in "
112 << (policy_refresh_error_delay_ms_/1000) << " seconds."; 127 << (policy_refresh_error_delay_ms_/1000) << " seconds.";
113 ScheduleRefreshTask(policy_refresh_error_delay_ms_); 128 ScheduleRefreshTask(policy_refresh_error_delay_ms_);
114 policy_refresh_error_delay_ms_ *= 2; 129 policy_refresh_error_delay_ms_ *= 2;
115 if (policy_refresh_rate_ms_ && 130 if (policy_refresh_rate_ms_ &&
116 policy_refresh_rate_ms_ < policy_refresh_error_delay_ms_) { 131 policy_refresh_rate_ms_ < policy_refresh_error_delay_ms_) {
117 policy_refresh_error_delay_ms_ = policy_refresh_rate_ms_; 132 policy_refresh_error_delay_ms_ = policy_refresh_rate_ms_;
118 } 133 }
119 #if defined(OS_CHROMEOS) 134 StopWaitingForInitialPolicies();
120 // Send a CLOUD_POLICY_UPDATE notification to unblock ChromeOS logins that
121 // are waiting for an initial policy fetch to complete.
122 NotifyCloudPolicyUpdate();
123 #endif
124 } 135 }
125 136
126 #if defined(OS_CHROMEOS)
127 void DeviceManagementPolicyProvider::NotifyCloudPolicyUpdate() const {
128 NotificationService::current()->Notify(
129 NotificationType::CLOUD_POLICY_UPDATE,
130 Source<DeviceManagementPolicyProvider>(this),
131 NotificationService::NoDetails());
132 }
133 #endif
134
135 void DeviceManagementPolicyProvider::OnTokenSuccess() { 137 void DeviceManagementPolicyProvider::OnTokenSuccess() {
136 if (policy_request_pending_) 138 BrowserThread::PostTask(
137 return; 139 BrowserThread::FILE,
140 FROM_HERE,
141 NewRunnableFunction(
142 &DeviceManagementPolicyProvider::DeleteUnmanagedDeviceMarker,
143 storage_dir_));
138 SendPolicyRequest(); 144 SendPolicyRequest();
139 } 145 }
140 146
141 void DeviceManagementPolicyProvider::OnTokenError() { 147 void DeviceManagementPolicyProvider::OnTokenError() {
142 LOG(WARNING) << "Could not retrieve device token."; 148 LOG(WARNING) << "Could not retrieve device token.";
143 ScheduleRefreshTask(token_fetch_error_delay_ms_); 149 ScheduleRefreshTask(token_fetch_error_delay_ms_);
144 token_fetch_error_delay_ms_ *= 2; 150 token_fetch_error_delay_ms_ *= 2;
145 if (token_fetch_error_delay_ms_ > policy_refresh_rate_ms_) 151 if (token_fetch_error_delay_ms_ > policy_refresh_rate_ms_)
146 token_fetch_error_delay_ms_ = policy_refresh_rate_ms_; 152 token_fetch_error_delay_ms_ = policy_refresh_rate_ms_;
153 StopWaitingForInitialPolicies();
147 } 154 }
148 155
149 void DeviceManagementPolicyProvider::OnNotManaged() { 156 void DeviceManagementPolicyProvider::OnNotManaged() {
150 VLOG(1) << "This device is not managed."; 157 VLOG(1) << "This device is not managed.";
158 BrowserThread::PostTask(
159 BrowserThread::FILE,
160 FROM_HERE,
161 NewRunnableFunction(
162 &DeviceManagementPolicyProvider::CreateUnmanagedDeviceMarker,
163 storage_dir_,
164 base::Time::NowFromSystemTime()));
165 ScheduleRefreshTask(unmanaged_device_refresh_rate_ms_);
166 StopWaitingForInitialPolicies();
151 } 167 }
152 168
153 void DeviceManagementPolicyProvider::Shutdown() { 169 void DeviceManagementPolicyProvider::Shutdown() {
154 token_service_ = NULL; 170 token_service_ = NULL;
155 if (token_fetcher_) 171 if (token_fetcher_)
156 token_fetcher_->Shutdown(); 172 token_fetcher_->Shutdown();
157 } 173 }
158 174
159 void DeviceManagementPolicyProvider::Initialize() { 175 void DeviceManagementPolicyProvider::Initialize() {
160 const FilePath policy_path = storage_dir_.Append( 176 const FilePath policy_path = storage_dir_.Append(
161 FILE_PATH_LITERAL("Policy")); 177 FILE_PATH_LITERAL(kPolicyFilename));
178 if (UnmanagedDeviceMarkerExists()) {
179 // This is a non-first login on an unmanaged device.
180 waiting_for_initial_policies_ = false;
181 // Defer token_fetcher_ initialization until this device should ask for
182 // a device token again.
183 base::Time unmanaged_timestamp = GetUnmanagedDeviceTimestamp();
184 int64 delay = unmanaged_device_refresh_rate_ms_ -
185 (base::Time::NowFromSystemTime().ToInternalValue() -
186 unmanaged_timestamp.ToInternalValue());
187 if (delay < 0)
188 delay = 0;
189 BrowserThread::PostDelayedTask(
190 BrowserThread::UI, FROM_HERE,
191 new InitializeAfterIOThreadExistsTask(AsWeakPtr()),
192 delay);
193 } else {
194 if (file_util::PathExists(
195 storage_dir_.Append(FILE_PATH_LITERAL(kDeviceTokenFilename)))) {
196 // This is a non-first login on a managed device.
197 waiting_for_initial_policies_ = false;
198 }
199 // Defer initialization that requires the IOThread until after the IOThread
200 // has been initialized.
201 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
202 new InitializeAfterIOThreadExistsTask(AsWeakPtr()));
203 }
162 cache_.reset(new DeviceManagementPolicyCache(policy_path)); 204 cache_.reset(new DeviceManagementPolicyCache(policy_path));
163 cache_->LoadPolicyFromFile(); 205 cache_->LoadPolicyFromFile();
164
165 // Defer initialization that requires the IOThread until after the IOThread
166 // has been initialized.
167 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
168 new InitializeAfterIOThreadExistsTask(AsWeakPtr()));
169 } 206 }
170 207
171 void DeviceManagementPolicyProvider::InitializeAfterIOThreadExists() { 208 void DeviceManagementPolicyProvider::InitializeAfterIOThreadExists() {
172 const FilePath token_path = storage_dir_.Append( 209 const FilePath token_path = storage_dir_.Append(
173 FILE_PATH_LITERAL("Token")); 210 FILE_PATH_LITERAL(kDeviceTokenFilename));
174 if (token_service_) { 211 if (token_service_) {
175 token_fetcher_ = 212 token_fetcher_ =
176 new DeviceTokenFetcher(backend_.get(), token_service_, token_path); 213 new DeviceTokenFetcher(backend_.get(), token_service_, token_path);
177 registrar_.Init(token_fetcher_); 214 registrar_.Init(token_fetcher_);
178 registrar_.AddObserver(this); 215 registrar_.AddObserver(this);
179 token_fetcher_->StartFetching(); 216 token_fetcher_->StartFetching();
180 } 217 }
181 } 218 }
182 219
183 void DeviceManagementPolicyProvider::SendPolicyRequest() { 220 void DeviceManagementPolicyProvider::SendPolicyRequest() {
184 if (!policy_request_pending_) { 221 if (policy_request_pending_)
danno 2010/11/25 16:35:01 Why reverse this? Seems like an unrelated change.
Jakob Kummerow 2010/11/25 16:54:24 It is indeed unrelated and merely a formatting cha
185 policy_request_pending_ = true; 222 return;
186 em::DevicePolicyRequest policy_request; 223 policy_request_pending_ = true;
187 policy_request.set_policy_scope(kChromePolicyScope); 224 em::DevicePolicyRequest policy_request;
188 em::DevicePolicySettingRequest* setting = 225 policy_request.set_policy_scope(kChromePolicyScope);
189 policy_request.add_setting_request(); 226 em::DevicePolicySettingRequest* setting =
190 setting->set_key(kChromeDevicePolicySettingKey); 227 policy_request.add_setting_request();
191 backend_->ProcessPolicyRequest(token_fetcher_->GetDeviceToken(), 228 setting->set_key(kChromeDevicePolicySettingKey);
192 token_fetcher_->GetDeviceID(), 229 backend_->ProcessPolicyRequest(token_fetcher_->GetDeviceToken(),
193 policy_request, this); 230 token_fetcher_->GetDeviceID(),
194 } 231 policy_request, this);
195 } 232 }
196 233
197 void DeviceManagementPolicyProvider::RefreshTaskExecute() { 234 void DeviceManagementPolicyProvider::RefreshTaskExecute() {
198 DCHECK(refresh_task_pending_); 235 DCHECK(refresh_task_pending_);
199 refresh_task_pending_ = false; 236 refresh_task_pending_ = false;
200 // If there is no valid device token, the token_fetcher_ apparently failed, 237 // If there is no valid device token, the token_fetcher_ apparently failed,
201 // so it must be restarted. 238 // so it must be restarted.
202 if (!token_fetcher_->IsTokenValid()) { 239 if (!token_fetcher_->IsTokenValid()) {
203 if (token_fetcher_->IsTokenPending()) { 240 if (token_fetcher_->IsTokenPending()) {
204 NOTREACHED(); 241 NOTREACHED();
(...skipping 19 matching lines...) Expand all
224 delay_in_milliseconds); 261 delay_in_milliseconds);
225 } 262 }
226 263
227 int64 DeviceManagementPolicyProvider::GetRefreshTaskDelay() { 264 int64 DeviceManagementPolicyProvider::GetRefreshTaskDelay() {
228 int64 delay = policy_refresh_rate_ms_; 265 int64 delay = policy_refresh_rate_ms_;
229 if (policy_refresh_max_earlier_ms_) 266 if (policy_refresh_max_earlier_ms_)
230 delay -= base::RandGenerator(policy_refresh_max_earlier_ms_); 267 delay -= base::RandGenerator(policy_refresh_max_earlier_ms_);
231 return delay; 268 return delay;
232 } 269 }
233 270
271 void DeviceManagementPolicyProvider::StopWaitingForInitialPolicies() {
272 waiting_for_initial_policies_ = false;
273 #if defined(OS_CHROMEOS)
danno 2010/11/25 16:35:01 Do you need this #define here? sending the notific
Jakob Kummerow 2010/11/25 16:54:24 This is Markus' code, I only moved it. Battle it o
274 // Send a CLOUD_POLICY_UPDATE notification to unblock ChromeOS logins that
275 // are waiting for an initial policy fetch to complete.
276 NotifyCloudPolicyUpdate();
danno 2010/11/25 16:35:01 Would it be possible to create a specific observer
Jakob Kummerow 2010/11/25 16:54:24 Same as above -- not my code. I'm just keeping the
277 #endif
278 }
279
280 #if defined(OS_CHROMEOS)
281 void DeviceManagementPolicyProvider::NotifyCloudPolicyUpdate() const {
282 NotificationService::current()->Notify(
283 NotificationType::CLOUD_POLICY_UPDATE,
284 Source<DeviceManagementPolicyProvider>(this),
285 NotificationService::NoDetails());
286 }
287 #endif
288
289 // static
290 FilePath DeviceManagementPolicyProvider::GetUnmanagedDeviceMarkerPath(
291 const FilePath& storage_dir) {
292 return storage_dir.Append(FILE_PATH_LITERAL(kUnmanagedDeviceMarkerFilename));
293 }
294
295 // static
296 void DeviceManagementPolicyProvider::CreateUnmanagedDeviceMarker(
297 const FilePath& storage_dir, const base::Time& timestamp) {
298 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
299 std::string data;
300 em::UnmanagedDevice unmanaged_device;
301 unmanaged_device.set_timestamp(timestamp.ToInternalValue());
302 if (!unmanaged_device.SerializeToString(&data)) {
303 LOG(WARNING) << "Failed to serialize UnmanagedDevice timestamp.";
304 return;
305 }
306 int size = data.size();
307 FilePath path(GetUnmanagedDeviceMarkerPath(storage_dir));
308 if (file_util::WriteFile(path, data.c_str(), size) != size) {
309 LOG(WARNING) << "Failed to write "<< path.value();
310 }
311 }
312
313 // static
314 void DeviceManagementPolicyProvider::DeleteUnmanagedDeviceMarker(
315 const FilePath& storage_dir) {
316 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
317 FilePath marker_file = GetUnmanagedDeviceMarkerPath(storage_dir);
318 if (file_util::PathExists(marker_file)) {
319 if (!file_util::Delete(marker_file, false)) {
320 LOG(WARNING) << "Failed to delete UnmanagedDevice marker from "
321 << marker_file.value();
322 }
323 }
324 }
325
326 bool DeviceManagementPolicyProvider::UnmanagedDeviceMarkerExists() {
327 return file_util::PathExists(GetUnmanagedDeviceMarkerPath(storage_dir_));
328 }
329
330 base::Time DeviceManagementPolicyProvider::GetUnmanagedDeviceTimestamp() {
331 FilePath file_path(GetUnmanagedDeviceMarkerPath(storage_dir_));
332 DCHECK(file_util::PathExists(file_path));
333 std::string data;
334 if (!file_util::ReadFileToString(file_path, &data)) {
335 LOG(WARNING) << "Failed to read UnmanagedDevice timestamp from "
336 << file_path.value();
337 }
338 em::UnmanagedDevice unmanaged_device;
339 if (!unmanaged_device.ParseFromArray(data.c_str(), data.size())) {
340 LOG(WARNING) << "Failed to parse UnmanagedDevice timestamp.";
341 }
342 return base::Time::FromInternalValue(unmanaged_device.timestamp());
343 }
344
234 // static 345 // static
235 std::string DeviceManagementPolicyProvider::GetDeviceManagementURL() { 346 std::string DeviceManagementPolicyProvider::GetDeviceManagementURL() {
236 return CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 347 return CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
237 switches::kDeviceManagementUrl); 348 switches::kDeviceManagementUrl);
238 } 349 }
239 350
240 // static 351 // static
241 FilePath DeviceManagementPolicyProvider::GetOrCreateDeviceManagementDir( 352 FilePath DeviceManagementPolicyProvider::GetOrCreateDeviceManagementDir(
242 const FilePath& user_data_dir) { 353 const FilePath& user_data_dir) {
243 const FilePath device_management_dir = user_data_dir.Append( 354 const FilePath device_management_dir = user_data_dir.Append(
244 FILE_PATH_LITERAL("Device Management")); 355 FILE_PATH_LITERAL("Device Management"));
245 if (!file_util::DirectoryExists(device_management_dir)) { 356 if (!file_util::DirectoryExists(device_management_dir)) {
246 if (!file_util::CreateDirectory(device_management_dir)) 357 if (!file_util::CreateDirectory(device_management_dir))
247 NOTREACHED(); 358 NOTREACHED();
248 } 359 }
249 return device_management_dir; 360 return device_management_dir;
250 } 361 }
251 362
252 bool DeviceManagementPolicyProvider::IsPolicyCacheEmpty() const {
253 return cache_->last_policy_refresh_time().is_null();
254 }
255
256 bool DeviceManagementPolicyProvider::WaitingForInitialPolicies() const { 363 bool DeviceManagementPolicyProvider::WaitingForInitialPolicies() const {
257 return (IsPolicyCacheEmpty() && IsPolicyRequestPending()); 364 return waiting_for_initial_policies_;
258 } 365 }
259 366
260 } // namespace policy 367 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698