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( |