| Index: components/policy/core/common/cloud/component_cloud_policy_service.cc
|
| diff --git a/components/policy/core/common/cloud/component_cloud_policy_service.cc b/components/policy/core/common/cloud/component_cloud_policy_service.cc
|
| index 0ba5db11f3d5736ce033cf6d8615c8abe48624f6..e70e783f573c450bb2a3bce0a94ccc3572b8c102 100644
|
| --- a/components/policy/core/common/cloud/component_cloud_policy_service.cc
|
| +++ b/components/policy/core/common/cloud/component_cloud_policy_service.cc
|
| @@ -8,10 +8,12 @@
|
|
|
| #include "base/bind.h"
|
| #include "base/bind_helpers.h"
|
| +#include "base/containers/scoped_ptr_hash_map.h"
|
| #include "base/location.h"
|
| #include "base/logging.h"
|
| #include "base/message_loop/message_loop_proxy.h"
|
| #include "base/sequenced_task_runner.h"
|
| +#include "base/stl_util.h"
|
| #include "components/policy/core/common/cloud/cloud_policy_constants.h"
|
| #include "components/policy/core/common/cloud/cloud_policy_refresh_scheduler.h"
|
| #include "components/policy/core/common/cloud/component_cloud_policy_store.h"
|
| @@ -25,10 +27,20 @@
|
|
|
| namespace em = enterprise_management;
|
|
|
| +typedef base::ScopedPtrHashMap<policy::PolicyNamespace, em::PolicyFetchResponse>
|
| + ScopedResponseMap;
|
| +
|
| namespace policy {
|
|
|
| namespace {
|
|
|
| +bool NotInResponseMap(const ScopedResponseMap& map,
|
| + const std::string& component_id) {
|
| + // This helper only works for POLICY_DOMAIN_EXTENSIONS for now. Parameterize
|
| + // this and update SetCurrentPolicies() below later if appropriate.
|
| + return !map.contains(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, component_id));
|
| +}
|
| +
|
| bool NotInSchemaMap(const scoped_refptr<SchemaMap> schema_map,
|
| PolicyDomain domain,
|
| const std::string& component_id) {
|
| @@ -70,9 +82,12 @@ class ComponentCloudPolicyService::Backend
|
| // Loads the |store_| and starts downloading updates.
|
| void Init(scoped_refptr<SchemaMap> schema_map);
|
|
|
| - // Passes a policy protobuf to the backend, to start its validation and
|
| - // eventual download of the policy data on the background thread.
|
| - void UpdateExternalPolicy(scoped_ptr<em::PolicyFetchResponse> response);
|
| + // Passes a vector with all the PolicyFetchResponses currently set at the
|
| + // server for components. Any components without an entry in |responses|
|
| + // will have their cache purged after this call.
|
| + // Otherwise the backend will start the validation and eventual download of
|
| + // the policy data for each PolicyFetchResponse in |responses|.
|
| + void SetCurrentPolicies(scoped_ptr<ScopedResponseMap> responses);
|
|
|
| // ComponentCloudPolicyStore::Delegate implementation:
|
| void OnComponentCloudPolicyStoreUpdated() override;
|
| @@ -161,9 +176,16 @@ void ComponentCloudPolicyService::Backend::Init(
|
| initialized_ = true;
|
| }
|
|
|
| -void ComponentCloudPolicyService::Backend::UpdateExternalPolicy(
|
| - scoped_ptr<em::PolicyFetchResponse> response) {
|
| - updater_->UpdateExternalPolicy(response.Pass());
|
| +void ComponentCloudPolicyService::Backend::SetCurrentPolicies(
|
| + scoped_ptr<ScopedResponseMap> responses) {
|
| + // Purge any components that don't have a policy configured at the server.
|
| + store_.Purge(POLICY_DOMAIN_EXTENSIONS,
|
| + base::Bind(&NotInResponseMap, base::ConstRef(*responses)));
|
| +
|
| + for (ScopedResponseMap::iterator it = responses->begin();
|
| + it != responses->end(); ++it) {
|
| + updater_->UpdateExternalPolicy(responses->take(it));
|
| + }
|
| }
|
|
|
| void ComponentCloudPolicyService::Backend::
|
| @@ -392,24 +414,39 @@ void ComponentCloudPolicyService::OnPolicyFetched(CloudPolicyClient* client) {
|
| return;
|
| }
|
|
|
| - // Pass each PolicyFetchResponse whose policy type is registered to the
|
| - // Backend.
|
| + // If the latest policy fetch didn't request policy for extensions then
|
| + // ignore the current ResponseMap, since it's incomplete.
|
| + // This is important, because otherwise the backend will drop all the
|
| + // caches for policy for extensions.
|
| + if (!ContainsKey(
|
| + core_->client()->namespaces_requested(),
|
| + PolicyNamespaceKey(dm_protocol::kChromeExtensionPolicyType, ""))) {
|
| + return;
|
| + }
|
| +
|
| + // Pass a complete list of all the currently managed extensions to the
|
| + // backend. The cache will purge the storage for any extensions that are not
|
| + // in this list.
|
| + scoped_ptr<ScopedResponseMap> valid_responses(new ScopedResponseMap());
|
| +
|
| const CloudPolicyClient::ResponseMap& responses =
|
| core_->client()->responses();
|
| for (CloudPolicyClient::ResponseMap::const_iterator it = responses.begin();
|
| it != responses.end(); ++it) {
|
| PolicyNamespace ns;
|
| - if (ToPolicyNamespace(it->first, &ns) &&
|
| - current_schema_map_->GetSchema(ns)) {
|
| - scoped_ptr<em::PolicyFetchResponse> response(
|
| - new em::PolicyFetchResponse(*it->second));
|
| - backend_task_runner_->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&Backend::UpdateExternalPolicy,
|
| - base::Unretained(backend_.get()),
|
| - base::Passed(&response)));
|
| + if (!ToPolicyNamespace(it->first, &ns) ||
|
| + !current_schema_map_->GetSchema(ns)) {
|
| + continue;
|
| }
|
| + valid_responses->set(
|
| + ns, make_scoped_ptr(new em::PolicyFetchResponse(*it->second)));
|
| }
|
| +
|
| + backend_task_runner_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&Backend::SetCurrentPolicies,
|
| + base::Unretained(backend_.get()),
|
| + base::Passed(&valid_responses)));
|
| }
|
|
|
| void ComponentCloudPolicyService::OnRegistrationStateChanged(
|
|
|