| 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 cd783abdd25def15c31ed0f8778d4a5337f45815..54db23006191130a175bbf9166a70153638ee0dc 100644
|
| --- a/components/policy/core/common/cloud/component_cloud_policy_service.cc
|
| +++ b/components/policy/core/common/cloud/component_cloud_policy_service.cc
|
| @@ -100,7 +100,7 @@ class ComponentCloudPolicyService::Backend
|
| scoped_ptr<ExternalPolicyDataFetcher> external_policy_data_fetcher_;
|
| ComponentCloudPolicyStore store_;
|
| scoped_ptr<ComponentCloudPolicyUpdater> updater_;
|
| - scoped_refptr<SchemaMap> schema_map_;
|
| + bool initialized_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(Backend);
|
| };
|
| @@ -116,7 +116,8 @@ ComponentCloudPolicyService::Backend::Backend(
|
| service_task_runner_(service_task_runner),
|
| cache_(cache.Pass()),
|
| external_policy_data_fetcher_(external_policy_data_fetcher.Pass()),
|
| - store_(this, cache_.get()) {}
|
| + store_(this, cache_.get()),
|
| + initialized_(false) {}
|
|
|
| ComponentCloudPolicyService::Backend::~Backend() {}
|
|
|
| @@ -133,7 +134,7 @@ void ComponentCloudPolicyService::Backend::SetCredentials(
|
|
|
| void ComponentCloudPolicyService::Backend::Init(
|
| scoped_refptr<SchemaMap> schema_map) {
|
| - DCHECK(!schema_map_);
|
| + DCHECK(!initialized_);
|
|
|
| OnSchemasUpdated(schema_map, scoped_ptr<PolicyNamespaceList>());
|
|
|
| @@ -146,7 +147,6 @@ void ComponentCloudPolicyService::Backend::Init(
|
| store_.Load();
|
| scoped_ptr<PolicyBundle> bundle(new PolicyBundle);
|
| bundle->CopyFrom(store_.policy());
|
| - schema_map_->FilterBundle(bundle.get());
|
|
|
| // Start downloading any pending data.
|
| updater_.reset(new ComponentCloudPolicyUpdater(
|
| @@ -157,6 +157,8 @@ void ComponentCloudPolicyService::Backend::Init(
|
| base::Bind(&ComponentCloudPolicyService::OnBackendInitialized,
|
| service_,
|
| base::Passed(&bundle)));
|
| +
|
| + initialized_ = true;
|
| }
|
|
|
| void ComponentCloudPolicyService::Backend::UpdateExternalPolicy(
|
| @@ -166,14 +168,13 @@ void ComponentCloudPolicyService::Backend::UpdateExternalPolicy(
|
|
|
| void ComponentCloudPolicyService::Backend::
|
| OnComponentCloudPolicyStoreUpdated() {
|
| - if (!schema_map_) {
|
| + if (!initialized_) {
|
| // Ignore notifications triggered by the initial Purge or Clear.
|
| return;
|
| }
|
|
|
| scoped_ptr<PolicyBundle> bundle(new PolicyBundle);
|
| bundle->CopyFrom(store_.policy());
|
| - schema_map_->FilterBundle(bundle.get());
|
| service_task_runner_->PostTask(
|
| FROM_HERE,
|
| base::Bind(&ComponentCloudPolicyService::OnPolicyUpdated,
|
| @@ -192,10 +193,6 @@ void ComponentCloudPolicyService::Backend::OnSchemasUpdated(
|
| base::Bind(&NotInSchemaMap, schema_map, domain->first));
|
| }
|
|
|
| - // Set |schema_map_| after purging so that the notifications from the store
|
| - // are ignored on the first OnSchemasUpdated() call from Init().
|
| - schema_map_ = schema_map;
|
| -
|
| if (removed) {
|
| for (size_t i = 0; i < removed->size(); ++i)
|
| updater_->CancelUpdate((*removed)[i]);
|
| @@ -217,6 +214,7 @@ ComponentCloudPolicyService::ComponentCloudPolicyService(
|
| backend_task_runner_(backend_task_runner),
|
| io_task_runner_(io_task_runner),
|
| current_schema_map_(new SchemaMap),
|
| + unfiltered_policy_(new PolicyBundle),
|
| started_loading_initial_policy_(false),
|
| loaded_initial_policy_(false),
|
| is_registered_for_cloud_policy_(false),
|
| @@ -241,6 +239,11 @@ ComponentCloudPolicyService::ComponentCloudPolicyService(
|
| // policies.
|
| if (core_->store()->is_initialized())
|
| OnStoreLoaded(core_->store());
|
| +
|
| + // Start observing the core and tracking the state of the client.
|
| + core_->AddObserver(this);
|
| + if (core_->client())
|
| + OnCoreConnected(core_);
|
| }
|
|
|
| ComponentCloudPolicyService::~ComponentCloudPolicyService() {
|
| @@ -287,6 +290,11 @@ void ComponentCloudPolicyService::OnSchemaRegistryUpdated(
|
| return;
|
|
|
| ReloadSchema();
|
| +
|
| + // Filter the |unfiltered_policy_| again, now that |current_schema_map_| has
|
| + // been updated. We must make sure we never serve invalid policy; we must
|
| + // also filter again if an invalid Schema has now been loaded.
|
| + OnPolicyUpdated(unfiltered_policy_.Pass());
|
| }
|
|
|
| void ComponentCloudPolicyService::OnCoreConnected(CloudPolicyCore* core) {
|
| @@ -300,8 +308,9 @@ void ComponentCloudPolicyService::OnCoreConnected(CloudPolicyCore* core) {
|
| PolicyNamespaceKey(dm_protocol::kChromeExtensionPolicyType, ""));
|
|
|
| // Immediately load any PolicyFetchResponses that the client may already
|
| - // have.
|
| - OnPolicyFetched(core_->client());
|
| + // have if the backend is ready.
|
| + if (loaded_initial_policy_)
|
| + OnPolicyFetched(core_->client());
|
| }
|
|
|
| void ComponentCloudPolicyService::OnCoreDisconnecting(CloudPolicyCore* core) {
|
| @@ -421,6 +430,7 @@ void ComponentCloudPolicyService::InitializeIfReady() {
|
| !core_->store()->is_initialized()) {
|
| return;
|
| }
|
| +
|
| // The initial list of components is ready. Initialize the backend now, which
|
| // will call back to OnBackendInitialized.
|
| backend_task_runner_->PostTask(FROM_HERE,
|
| @@ -437,18 +447,12 @@ void ComponentCloudPolicyService::OnBackendInitialized(
|
|
|
| loaded_initial_policy_ = true;
|
|
|
| - // We're now ready to serve the initial policy; notify the policy observers.
|
| - OnPolicyUpdated(initial_policy.Pass());
|
| -
|
| // Send the current schema to the backend, in case it has changed while the
|
| // backend was initializing.
|
| ReloadSchema();
|
|
|
| - // Start observing the core and tracking the state of the client.
|
| - core_->AddObserver(this);
|
| -
|
| - if (core_->client())
|
| - OnCoreConnected(core_);
|
| + // We're now ready to serve the initial policy; notify the policy observers.
|
| + OnPolicyUpdated(initial_policy.Pass());
|
| }
|
|
|
| void ComponentCloudPolicyService::ReloadSchema() {
|
| @@ -462,10 +466,6 @@ void ComponentCloudPolicyService::ReloadSchema() {
|
|
|
| current_schema_map_ = new_schema_map;
|
|
|
| - // Schedule a policy refresh if a new managed component was added.
|
| - if (core_->client() && !added.empty())
|
| - core_->RefreshSoon();
|
| -
|
| // Send the updated SchemaMap and a list of removed components to the
|
| // backend.
|
| backend_task_runner_->PostTask(FROM_HERE,
|
| @@ -473,12 +473,28 @@ void ComponentCloudPolicyService::ReloadSchema() {
|
| base::Unretained(backend_.get()),
|
| current_schema_map_,
|
| base::Passed(&removed)));
|
| +
|
| + // Have another look at the client if the core is already connected.
|
| + // The client may have already fetched policy for some component and it was
|
| + // previously ignored because the component wasn't listed in the schema map.
|
| + // There's no point in fetching policy from the server again; the server
|
| + // always pushes all the components it knows about.
|
| + if (core_->client())
|
| + OnPolicyFetched(core_->client());
|
| }
|
|
|
| void ComponentCloudPolicyService::OnPolicyUpdated(
|
| scoped_ptr<PolicyBundle> policy) {
|
| DCHECK(CalledOnValidThread());
|
| - policy_.Swap(policy.get());
|
| +
|
| + // Store the current unfiltered policies.
|
| + unfiltered_policy_ = policy.Pass();
|
| +
|
| + // Make a copy in |policy_| and filter it; this is what's passed to the
|
| + // outside world.
|
| + policy_.CopyFrom(*unfiltered_policy_);
|
| + current_schema_map_->FilterBundle(&policy_);
|
| +
|
| delegate_->OnComponentCloudPolicyUpdated();
|
| }
|
|
|
|
|