OLD | NEW |
---|---|
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/cloud/component_cloud_policy_service.h" | 5 #include "chrome/browser/policy/cloud/component_cloud_policy_service.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
11 #include "base/location.h" | 11 #include "base/location.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/message_loop/message_loop_proxy.h" | 13 #include "base/message_loop/message_loop_proxy.h" |
14 #include "base/sequenced_task_runner.h" | 14 #include "base/sequenced_task_runner.h" |
15 #include "base/time/time.h" | 15 #include "base/time/time.h" |
bartfab (slow)
2013/11/18 13:15:39
Nit: No longer used.
Joao da Silva
2013/11/18 14:54:18
Done.
| |
16 #include "chrome/browser/policy/cloud/cloud_policy_constants.h" | 16 #include "chrome/browser/policy/cloud/cloud_policy_constants.h" |
17 #include "chrome/browser/policy/cloud/cloud_policy_refresh_scheduler.h" | |
17 #include "chrome/browser/policy/cloud/component_cloud_policy_store.h" | 18 #include "chrome/browser/policy/cloud/component_cloud_policy_store.h" |
18 #include "chrome/browser/policy/cloud/component_cloud_policy_updater.h" | 19 #include "chrome/browser/policy/cloud/component_cloud_policy_updater.h" |
19 #include "chrome/browser/policy/cloud/external_policy_data_fetcher.h" | 20 #include "chrome/browser/policy/cloud/external_policy_data_fetcher.h" |
20 #include "chrome/browser/policy/cloud/resource_cache.h" | 21 #include "chrome/browser/policy/cloud/resource_cache.h" |
21 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h" | 22 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h" |
22 #include "chrome/browser/policy/schema_map.h" | 23 #include "chrome/browser/policy/schema_map.h" |
23 #include "components/policy/core/common/schema.h" | 24 #include "components/policy/core/common/schema.h" |
24 #include "net/url_request/url_request_context_getter.h" | 25 #include "net/url_request/url_request_context_getter.h" |
25 | 26 |
26 namespace em = enterprise_management; | 27 namespace em = enterprise_management; |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
123 service_task_runner_(service_task_runner), | 124 service_task_runner_(service_task_runner), |
124 cache_(cache.Pass()), | 125 cache_(cache.Pass()), |
125 external_policy_data_fetcher_(external_policy_data_fetcher.Pass()), | 126 external_policy_data_fetcher_(external_policy_data_fetcher.Pass()), |
126 store_(this, cache_.get()) {} | 127 store_(this, cache_.get()) {} |
127 | 128 |
128 ComponentCloudPolicyService::Backend::~Backend() {} | 129 ComponentCloudPolicyService::Backend::~Backend() {} |
129 | 130 |
130 void ComponentCloudPolicyService::Backend::SetCredentials( | 131 void ComponentCloudPolicyService::Backend::SetCredentials( |
131 const std::string& username, | 132 const std::string& username, |
132 const std::string& dm_token) { | 133 const std::string& dm_token) { |
133 store_.SetCredentials(username, dm_token); | 134 if (username.empty() || dm_token.empty()) { |
135 // No sign-in credentials, so drop any cached policy. | |
136 store_.Clear(); | |
137 } else { | |
138 store_.SetCredentials(username, dm_token); | |
139 } | |
134 } | 140 } |
135 | 141 |
136 void ComponentCloudPolicyService::Backend::Init( | 142 void ComponentCloudPolicyService::Backend::Init( |
137 scoped_refptr<SchemaMap> schema_map) { | 143 scoped_refptr<SchemaMap> schema_map) { |
138 DCHECK(!schema_map_); | 144 DCHECK(!schema_map_); |
139 | 145 |
140 OnSchemasUpdated(schema_map, scoped_ptr<PolicyNamespaceList>()); | 146 OnSchemasUpdated(schema_map, scoped_ptr<PolicyNamespaceList>()); |
141 | 147 |
142 // Read the initial policy. Note that this does not trigger notifications | 148 // Read the initial policy. Note that this does not trigger notifications |
143 // through OnComponentCloudPolicyStoreUpdated. | 149 // through OnComponentCloudPolicyStoreUpdated. |
(...skipping 13 matching lines...) Expand all Loading... | |
157 } | 163 } |
158 | 164 |
159 void ComponentCloudPolicyService::Backend::UpdateExternalPolicy( | 165 void ComponentCloudPolicyService::Backend::UpdateExternalPolicy( |
160 scoped_ptr<em::PolicyFetchResponse> response) { | 166 scoped_ptr<em::PolicyFetchResponse> response) { |
161 updater_->UpdateExternalPolicy(response.Pass()); | 167 updater_->UpdateExternalPolicy(response.Pass()); |
162 } | 168 } |
163 | 169 |
164 void ComponentCloudPolicyService::Backend:: | 170 void ComponentCloudPolicyService::Backend:: |
165 OnComponentCloudPolicyStoreUpdated() { | 171 OnComponentCloudPolicyStoreUpdated() { |
166 if (!schema_map_) { | 172 if (!schema_map_) { |
167 // Ignore notifications triggered by the initial Purge. | 173 // Ignore notifications triggered by the initial Purge or Clear. |
168 return; | 174 return; |
169 } | 175 } |
170 | 176 |
171 scoped_ptr<PolicyBundle> bundle(new PolicyBundle); | 177 scoped_ptr<PolicyBundle> bundle(new PolicyBundle); |
172 bundle->CopyFrom(store_.policy()); | 178 bundle->CopyFrom(store_.policy()); |
173 schema_map_->FilterBundle(bundle.get()); | 179 schema_map_->FilterBundle(bundle.get()); |
174 service_task_runner_->PostTask( | 180 service_task_runner_->PostTask( |
175 FROM_HERE, | 181 FROM_HERE, |
176 base::Bind(&ComponentCloudPolicyService::OnPolicyUpdated, | 182 base::Bind(&ComponentCloudPolicyService::OnPolicyUpdated, |
177 service_, | 183 service_, |
(...skipping 17 matching lines...) Expand all Loading... | |
195 | 201 |
196 if (removed) { | 202 if (removed) { |
197 for (size_t i = 0; i < removed->size(); ++i) | 203 for (size_t i = 0; i < removed->size(); ++i) |
198 updater_->CancelUpdate((*removed)[i]); | 204 updater_->CancelUpdate((*removed)[i]); |
199 } | 205 } |
200 } | 206 } |
201 | 207 |
202 ComponentCloudPolicyService::ComponentCloudPolicyService( | 208 ComponentCloudPolicyService::ComponentCloudPolicyService( |
203 Delegate* delegate, | 209 Delegate* delegate, |
204 SchemaRegistry* schema_registry, | 210 SchemaRegistry* schema_registry, |
205 CloudPolicyStore* store, | 211 CloudPolicyCore* core, |
206 scoped_ptr<ResourceCache> cache, | 212 scoped_ptr<ResourceCache> cache, |
207 CloudPolicyClient* client, | |
208 scoped_refptr<net::URLRequestContextGetter> request_context, | 213 scoped_refptr<net::URLRequestContextGetter> request_context, |
209 scoped_refptr<base::SequencedTaskRunner> backend_task_runner, | 214 scoped_refptr<base::SequencedTaskRunner> backend_task_runner, |
210 scoped_refptr<base::SequencedTaskRunner> io_task_runner) | 215 scoped_refptr<base::SequencedTaskRunner> io_task_runner) |
211 : delegate_(delegate), | 216 : delegate_(delegate), |
212 schema_registry_(schema_registry), | 217 schema_registry_(schema_registry), |
213 store_(store), | 218 core_(core), |
214 client_(client), | |
215 request_context_(request_context), | 219 request_context_(request_context), |
216 backend_task_runner_(backend_task_runner), | 220 backend_task_runner_(backend_task_runner), |
217 io_task_runner_(io_task_runner), | 221 io_task_runner_(io_task_runner), |
218 current_schema_map_(new SchemaMap), | 222 current_schema_map_(new SchemaMap), |
219 is_initialized_(false), | 223 loaded_initial_policy_(false), |
220 has_credentials_(false), | 224 is_registered_for_cloud_policy_(false), |
221 weak_ptr_factory_(this) { | 225 weak_ptr_factory_(this) { |
222 schema_registry_->AddObserver(this); | |
223 store_->AddObserver(this); | |
224 client_->AddObserver(this); | |
225 | |
226 external_policy_data_fetcher_backend_.reset( | 226 external_policy_data_fetcher_backend_.reset( |
227 new ExternalPolicyDataFetcherBackend(io_task_runner_, request_context)); | 227 new ExternalPolicyDataFetcherBackend(io_task_runner_, request_context)); |
228 | 228 |
229 backend_.reset( | 229 backend_.reset( |
230 new Backend(weak_ptr_factory_.GetWeakPtr(), | 230 new Backend(weak_ptr_factory_.GetWeakPtr(), |
231 backend_task_runner_, | 231 backend_task_runner_, |
232 base::MessageLoopProxy::current(), | 232 base::MessageLoopProxy::current(), |
233 cache.Pass(), | 233 cache.Pass(), |
234 external_policy_data_fetcher_backend_->CreateFrontend( | 234 external_policy_data_fetcher_backend_->CreateFrontend( |
235 backend_task_runner_))); | 235 backend_task_runner_))); |
236 | 236 |
237 if (store_->is_initialized()) | 237 schema_registry_->AddObserver(this); |
238 OnStoreLoaded(store_); | 238 core_->store()->AddObserver(this); |
239 | |
240 // Wait for the store and the schema registry to become ready before | |
241 // initializing the backend, so that it can get the initial list of | |
242 // components and the cached credentials (if any) to validate the cached | |
243 // policies. | |
244 if (core_->store()->is_initialized()) | |
245 OnStoreLoaded(core_->store()); | |
239 } | 246 } |
240 | 247 |
241 ComponentCloudPolicyService::~ComponentCloudPolicyService() { | 248 ComponentCloudPolicyService::~ComponentCloudPolicyService() { |
242 DCHECK(CalledOnValidThread()); | 249 DCHECK(CalledOnValidThread()); |
250 | |
243 schema_registry_->RemoveObserver(this); | 251 schema_registry_->RemoveObserver(this); |
244 store_->RemoveObserver(this); | 252 core_->store()->RemoveObserver(this); |
245 client_->RemoveObserver(this); | 253 core_->RemoveObserver(this); |
246 | 254 if (core_->client()) |
247 // Remove all the namespaces from |client_| but don't send this empty schema | 255 OnCoreDisconnecting(core_); |
248 // to the backend, to avoid dropping the caches. | |
249 if (is_initialized()) { | |
250 scoped_refptr<SchemaMap> empty(new SchemaMap); | |
251 SetCurrentSchema(empty, false); | |
252 } | |
253 | 256 |
254 io_task_runner_->DeleteSoon(FROM_HERE, | 257 io_task_runner_->DeleteSoon(FROM_HERE, |
255 external_policy_data_fetcher_backend_.release()); | 258 external_policy_data_fetcher_backend_.release()); |
256 backend_task_runner_->DeleteSoon(FROM_HERE, backend_.release()); | 259 backend_task_runner_->DeleteSoon(FROM_HERE, backend_.release()); |
257 } | 260 } |
258 | 261 |
259 // static | 262 // static |
260 bool ComponentCloudPolicyService::SupportsDomain(PolicyDomain domain) { | 263 bool ComponentCloudPolicyService::SupportsDomain(PolicyDomain domain) { |
261 return ComponentCloudPolicyStore::SupportsDomain(domain); | 264 return ComponentCloudPolicyStore::SupportsDomain(domain); |
262 } | 265 } |
263 | 266 |
267 void ComponentCloudPolicyService::OnSchemaRegistryReady() { | |
268 DCHECK(CalledOnValidThread()); | |
269 InitializeIfReady(); | |
270 } | |
271 | |
272 void ComponentCloudPolicyService::OnSchemaRegistryUpdated( | |
273 bool has_new_schemas) { | |
274 DCHECK(CalledOnValidThread()); | |
275 | |
276 // Ignore schema updates until the backend is initialized. | |
277 // OnBackendInitialized() will send the current schema to the backend again, | |
278 // in case it was updated before the backend initialized. | |
279 if (!loaded_initial_policy_) | |
280 return; | |
281 | |
282 SetCurrentSchema(); | |
283 } | |
284 | |
285 void ComponentCloudPolicyService::OnCoreConnected(CloudPolicyCore* core) { | |
286 DCHECK(CalledOnValidThread()); | |
287 DCHECK_EQ(core_, core); | |
288 | |
289 core_->client()->AddObserver(this); | |
290 | |
291 // Immediately load any PolicyFetchResponses that the client may already | |
292 // have. | |
293 OnPolicyFetched(core_->client()); | |
294 | |
295 // Register the current namespaces at the client. | |
296 current_schema_map_ = new SchemaMap(); | |
297 SetCurrentSchema(); | |
298 } | |
299 | |
300 void ComponentCloudPolicyService::OnCoreDisconnecting(CloudPolicyCore* core) { | |
301 DCHECK(CalledOnValidThread()); | |
302 DCHECK_EQ(core_, core); | |
303 | |
304 core_->client()->RemoveObserver(this); | |
305 | |
306 // Remove all the namespaces from the client. | |
307 scoped_refptr<SchemaMap> empty = new SchemaMap(); | |
308 PolicyNamespaceList removed; | |
309 PolicyNamespaceList added; | |
310 empty->GetChanges(current_schema_map_, &removed, &added); | |
311 for (size_t i = 0; i < removed.size(); ++i) { | |
312 PolicyNamespaceKey key; | |
313 if (ToPolicyNamespaceKey(removed[i], &key)) | |
314 core_->client()->RemoveNamespaceToFetch(key); | |
315 } | |
316 } | |
317 | |
318 void ComponentCloudPolicyService::OnRefreshSchedulerStarted( | |
319 CloudPolicyCore* core) { | |
320 // Ignored. | |
321 } | |
322 | |
323 void ComponentCloudPolicyService::OnStoreLoaded(CloudPolicyStore* store) { | |
324 DCHECK(CalledOnValidThread()); | |
325 DCHECK_EQ(core_->store(), store); | |
326 | |
327 const bool was_registered_before = is_registered_for_cloud_policy_; | |
328 | |
329 // Send the current credentials to the backend; do this whenever the store | |
330 // updates, to handle the case of the user registering for policy after the | |
331 // session starts, or the user signing out. | |
332 const em::PolicyData* policy = core_->store()->policy(); | |
333 std::string username; | |
334 std::string request_token; | |
335 if (policy && policy->has_username() && policy->has_request_token()) { | |
336 is_registered_for_cloud_policy_ = true; | |
337 username = policy->username(); | |
338 request_token = policy->request_token(); | |
339 } else { | |
340 is_registered_for_cloud_policy_ = false; | |
341 } | |
342 | |
343 // Empty credentials will wipe the cache. | |
344 backend_task_runner_->PostTask(FROM_HERE, | |
345 base::Bind(&Backend::SetCredentials, | |
346 base::Unretained(backend_.get()), | |
347 username, | |
348 request_token)); | |
349 | |
350 if (!loaded_initial_policy_) { | |
351 // This is the initial load; check if we're ready to initialize the | |
352 // backend, regardless of the signin state. | |
353 InitializeIfReady(); | |
354 } else if (!was_registered_before && is_registered_for_cloud_policy_) { | |
355 // We are already initialized, but just sent credentials to the backend for | |
356 // the first time; this means that the user was not registered for cloud | |
357 // policy on startup but registered during the session. | |
358 // | |
359 // When that happens, OnPolicyFetched() is sent to observers before the | |
360 // CloudPolicyStore gets a chance to verify the user policy. In that case, | |
361 // if OnPolicyFetched() sent the PolicyFetchResponses to the backend then | |
bartfab (slow)
2013/11/18 13:15:39
I see what you are trying to say but the sentence
Joao da Silva
2013/11/18 14:54:18
Done.
| |
362 // they would fail validation, because the credentials weren't there yet. | |
363 // Reload any PolicyFetchResponses that the client may have now. | |
364 if (core_->client()) | |
365 OnPolicyFetched(core_->client()); | |
366 } | |
367 } | |
368 | |
369 void ComponentCloudPolicyService::OnStoreError(CloudPolicyStore* store) { | |
370 DCHECK(CalledOnValidThread()); | |
371 OnStoreLoaded(store); | |
372 } | |
373 | |
264 void ComponentCloudPolicyService::OnPolicyFetched(CloudPolicyClient* client) { | 374 void ComponentCloudPolicyService::OnPolicyFetched(CloudPolicyClient* client) { |
265 DCHECK(CalledOnValidThread()); | 375 DCHECK(CalledOnValidThread()); |
266 DCHECK_EQ(client_, client); | 376 DCHECK_EQ(core_->client(), client); |
267 | 377 |
268 if (!is_initialized() || !has_credentials_) | 378 if (!is_registered_for_cloud_policy_) { |
379 // Trying to load any policies now will fail validation. An OnStoreLoaded() | |
380 // notification should follow soon, after the main user policy has been | |
381 // validated and stored. | |
269 return; | 382 return; |
383 } | |
270 | 384 |
271 // Pass each PolicyFetchResponse whose policy type is registered to the | 385 // Pass each PolicyFetchResponse whose policy type is registered to the |
272 // Backend. | 386 // Backend. |
273 const CloudPolicyClient::ResponseMap& responses = client_->responses(); | 387 const CloudPolicyClient::ResponseMap& responses = |
388 core_->client()->responses(); | |
274 for (CloudPolicyClient::ResponseMap::const_iterator it = responses.begin(); | 389 for (CloudPolicyClient::ResponseMap::const_iterator it = responses.begin(); |
275 it != responses.end(); ++it) { | 390 it != responses.end(); ++it) { |
276 PolicyNamespace ns; | 391 PolicyNamespace ns; |
277 if (ToPolicyNamespace(it->first, &ns) && | 392 if (ToPolicyNamespace(it->first, &ns) && |
278 current_schema_map_->GetSchema(ns)) { | 393 current_schema_map_->GetSchema(ns)) { |
279 scoped_ptr<em::PolicyFetchResponse> response( | 394 scoped_ptr<em::PolicyFetchResponse> response( |
280 new em::PolicyFetchResponse(*it->second)); | 395 new em::PolicyFetchResponse(*it->second)); |
281 backend_task_runner_->PostTask( | 396 backend_task_runner_->PostTask( |
282 FROM_HERE, | 397 FROM_HERE, |
283 base::Bind(&Backend::UpdateExternalPolicy, | 398 base::Bind(&Backend::UpdateExternalPolicy, |
284 base::Unretained(backend_.get()), | 399 base::Unretained(backend_.get()), |
285 base::Passed(&response))); | 400 base::Passed(&response))); |
286 } | 401 } |
287 } | 402 } |
288 } | 403 } |
289 | 404 |
290 void ComponentCloudPolicyService::OnRegistrationStateChanged( | 405 void ComponentCloudPolicyService::OnRegistrationStateChanged( |
291 CloudPolicyClient* client) { | 406 CloudPolicyClient* client) { |
292 DCHECK(CalledOnValidThread()); | 407 DCHECK(CalledOnValidThread()); |
293 // Ignored. | 408 // Ignored; the registration state is tracked by looking at the |
409 // CloudPolicyStore instead. | |
294 } | 410 } |
295 | 411 |
296 void ComponentCloudPolicyService::OnClientError(CloudPolicyClient* client) { | 412 void ComponentCloudPolicyService::OnClientError(CloudPolicyClient* client) { |
297 DCHECK(CalledOnValidThread()); | 413 DCHECK(CalledOnValidThread()); |
298 // Ignored. | 414 // Ignored. |
299 } | 415 } |
300 | 416 |
301 void ComponentCloudPolicyService::OnStoreLoaded(CloudPolicyStore* store) { | |
302 DCHECK(CalledOnValidThread()); | |
303 DCHECK_EQ(store_, store); | |
304 | |
305 if (!store_->is_initialized()) | |
306 return; | |
307 | |
308 const em::PolicyData* policy = store_->policy(); | |
309 if (!has_credentials_ && policy && policy->has_username() && | |
310 policy->has_request_token()) { | |
311 // Send the current credentials to the backend, if they haven't been sent | |
312 // before. Usually this happens at startup if the user already had a cached | |
313 // cloud policy; otherwise it happens right after the initial registration | |
314 // for cloud policy. | |
315 backend_task_runner_->PostTask(FROM_HERE, | |
316 base::Bind(&Backend::SetCredentials, | |
317 base::Unretained(backend_.get()), | |
318 policy->username(), | |
319 policy->request_token())); | |
320 has_credentials_ = true; | |
321 if (is_initialized()) { | |
322 // This was the first policy fetch for this client. Process any | |
323 // PolicyFetchResponses that the client may have now; processing them | |
324 // before the credentials were sent to the backend would fail validation. | |
325 OnPolicyFetched(client_); | |
326 } | |
327 } | |
328 | |
329 if (!is_initialized()) | |
330 InitializeIfReady(); | |
331 } | |
332 | |
333 void ComponentCloudPolicyService::OnStoreError(CloudPolicyStore* store) { | |
334 DCHECK(CalledOnValidThread()); | |
335 OnStoreLoaded(store); | |
336 } | |
337 | |
338 void ComponentCloudPolicyService::OnSchemaRegistryReady() { | |
339 DCHECK(CalledOnValidThread()); | |
340 InitializeIfReady(); | |
341 } | |
342 | |
343 void ComponentCloudPolicyService::OnSchemaRegistryUpdated( | |
344 bool has_new_schemas) { | |
345 DCHECK(CalledOnValidThread()); | |
346 | |
347 if (!is_initialized()) | |
348 return; | |
349 | |
350 // When an extension is reloaded or updated, it triggers an unregister quickly | |
351 // followed by a register in the SchemaRegistry. If the intermediate version | |
352 // of the SchemaMap is passed to the backend then it will drop the cached | |
353 // policy for that extension and will trigger a new policy fetch soon after. | |
354 // Delaying the schema update here coalesces both updates into one, and the | |
355 // new schema will equal the older version in case of extension updates. | |
356 // | |
357 // TODO(joaodasilva): Increase this delay to 10 seconds. For now it's | |
358 // immediate so that tests don't get delayed. | |
359 schema_update_timer_.Start( | |
360 FROM_HERE, | |
361 base::TimeDelta::FromSeconds(0), | |
362 base::Bind(&ComponentCloudPolicyService::SetCurrentSchema, | |
363 base::Unretained(this), | |
364 schema_registry_->schema_map(), | |
365 true)); | |
366 } | |
367 | |
368 void ComponentCloudPolicyService::InitializeIfReady() { | 417 void ComponentCloudPolicyService::InitializeIfReady() { |
369 DCHECK(CalledOnValidThread()); | 418 DCHECK(CalledOnValidThread()); |
370 if (!schema_registry_->IsReady() || !store_->is_initialized()) | 419 if (!schema_registry_->IsReady() || !core_->store()->is_initialized()) |
371 return; | 420 return; |
421 // The initial list of components is ready. Initialize the backend now, which | |
422 // will call back to OnBackendInitialized. | |
372 backend_task_runner_->PostTask(FROM_HERE, | 423 backend_task_runner_->PostTask(FROM_HERE, |
373 base::Bind(&Backend::Init, | 424 base::Bind(&Backend::Init, |
374 base::Unretained(backend_.get()), | 425 base::Unretained(backend_.get()), |
375 schema_registry_->schema_map())); | 426 schema_registry_->schema_map())); |
376 } | 427 } |
377 | 428 |
378 void ComponentCloudPolicyService::OnBackendInitialized( | 429 void ComponentCloudPolicyService::OnBackendInitialized( |
379 scoped_ptr<PolicyBundle> initial_policy) { | 430 scoped_ptr<PolicyBundle> initial_policy) { |
380 DCHECK(CalledOnValidThread()); | 431 DCHECK(CalledOnValidThread()); |
381 | 432 |
382 is_initialized_ = true; | 433 loaded_initial_policy_ = true; |
383 | 434 |
384 // Send the current schema to the backend, in case it has changed while the | 435 // We're now ready to serve the initial policy; notify the policy observers. |
385 // backend was initializing. | 436 OnPolicyUpdated(initial_policy.Pass()); |
386 SetCurrentSchema(schema_registry_->schema_map(), true); | |
387 | 437 |
388 // Process any PolicyFetchResponses that the client may already have, or that | 438 // Start observing the core and tracking the state of the client. |
389 // may have been received while the backend was initializing. | 439 core_->AddObserver(this); |
390 OnPolicyFetched(client_); | |
391 | 440 |
392 // Finally tell the Delegate that the initial policy is available. | 441 if (core_->client()) { |
393 OnPolicyUpdated(initial_policy.Pass()); | 442 OnCoreConnected(core_); |
443 } else { | |
444 // Send the current schema to the backend, in case it has changed while the | |
445 // backend was initializing. OnCoreConnected() also does this if a client is | |
446 // already connected. | |
447 SetCurrentSchema(); | |
448 } | |
394 } | 449 } |
395 | 450 |
396 void ComponentCloudPolicyService::SetCurrentSchema( | 451 void ComponentCloudPolicyService::SetCurrentSchema() { |
397 const scoped_refptr<SchemaMap>& new_schema_map, | |
398 bool send_to_backend) { | |
399 DCHECK(CalledOnValidThread()); | 452 DCHECK(CalledOnValidThread()); |
400 DCHECK(is_initialized()); | |
401 | 453 |
402 scoped_ptr<PolicyNamespaceList> removed(new PolicyNamespaceList); | 454 scoped_ptr<PolicyNamespaceList> removed(new PolicyNamespaceList); |
403 PolicyNamespaceList added; | 455 PolicyNamespaceList added; |
456 const scoped_refptr<SchemaMap>& new_schema_map = | |
457 schema_registry_->schema_map(); | |
404 new_schema_map->GetChanges(current_schema_map_, removed.get(), &added); | 458 new_schema_map->GetChanges(current_schema_map_, removed.get(), &added); |
405 | 459 |
406 current_schema_map_ = new_schema_map; | 460 current_schema_map_ = new_schema_map; |
407 | 461 |
408 for (size_t i = 0; i < removed->size(); ++i) { | 462 if (core_->client()) { |
409 PolicyNamespaceKey key; | 463 for (size_t i = 0; i < removed->size(); ++i) { |
410 if (ToPolicyNamespaceKey((*removed)[i], &key)) | 464 PolicyNamespaceKey key; |
411 client_->RemoveNamespaceToFetch(key); | 465 if (ToPolicyNamespaceKey((*removed)[i], &key)) |
466 core_->client()->RemoveNamespaceToFetch(key); | |
467 } | |
468 | |
469 bool added_namespaces_to_client = false; | |
470 for (size_t i = 0; i < added.size(); ++i) { | |
471 PolicyNamespaceKey key; | |
472 if (ToPolicyNamespaceKey(added[i], &key)) { | |
473 core_->client()->AddNamespaceToFetch(key); | |
474 added_namespaces_to_client = true; | |
475 } | |
476 } | |
477 | |
478 if (added_namespaces_to_client) | |
479 core_->RefreshSoon(); | |
412 } | 480 } |
413 | 481 |
414 bool added_namespaces_to_client = false; | 482 backend_task_runner_->PostTask(FROM_HERE, |
415 for (size_t i = 0; i < added.size(); ++i) { | 483 base::Bind(&Backend::OnSchemasUpdated, |
416 PolicyNamespaceKey key; | 484 base::Unretained(backend_.get()), |
417 if (ToPolicyNamespaceKey(added[i], &key)) { | 485 current_schema_map_, |
418 client_->AddNamespaceToFetch(key); | 486 base::Passed(&removed))); |
419 added_namespaces_to_client = true; | |
420 } | |
421 } | |
422 | |
423 if (added_namespaces_to_client) | |
424 delegate_->OnComponentCloudPolicyRefreshNeeded(); | |
425 | |
426 if (send_to_backend) { | |
427 backend_task_runner_->PostTask(FROM_HERE, | |
428 base::Bind(&Backend::OnSchemasUpdated, | |
429 base::Unretained(backend_.get()), | |
430 current_schema_map_, | |
431 base::Passed(&removed))); | |
432 } | |
433 } | 487 } |
434 | 488 |
435 void ComponentCloudPolicyService::OnPolicyUpdated( | 489 void ComponentCloudPolicyService::OnPolicyUpdated( |
436 scoped_ptr<PolicyBundle> policy) { | 490 scoped_ptr<PolicyBundle> policy) { |
437 DCHECK(CalledOnValidThread()); | 491 DCHECK(CalledOnValidThread()); |
438 policy_.Swap(policy.get()); | 492 policy_.Swap(policy.get()); |
439 delegate_->OnComponentCloudPolicyUpdated(); | 493 delegate_->OnComponentCloudPolicyUpdated(); |
440 } | 494 } |
441 | 495 |
442 } // namespace policy | 496 } // namespace policy |
OLD | NEW |