component_cloud_policy_service.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/component_cloud_policy_service.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <string> 8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind_helpers.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/location.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 13b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/sequenced_task_runner.h" 15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_constants.h" 16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_refresh_scheduler.h" 17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/component_cloud_policy_store.h" 18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/component_cloud_policy_updater.h" 19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/external_policy_data_fetcher.h" 20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/resource_cache.h" 21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/schema.h" 22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/schema_map.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/url_request/url_request_context_getter.h" 24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "policy/proto/device_management_backend.pb.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace em = enterprise_management; 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace policy { 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace { 3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool NotInSchemaMap(const scoped_refptr<SchemaMap> schema_map, 33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PolicyDomain domain, 34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& component_id) { 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return schema_map->GetSchema(PolicyNamespace(domain, component_id)) == NULL; 3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool ToPolicyNamespaceKey(const PolicyNamespace& ns, PolicyNamespaceKey* key) { 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!ComponentCloudPolicyStore::GetPolicyType(ns.domain, &key->first)) 40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) key->second = ns.component_id; 42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool ToPolicyNamespace(const PolicyNamespaceKey& key, PolicyNamespace* ns) { 46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!ComponentCloudPolicyStore::GetPolicyDomain(key.first, &ns->domain)) 47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ns->component_id = key.second; 49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} // namespace 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ComponentCloudPolicyService::Delegate::~Delegate() {} 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Owns the objects that live on the background thread, and posts back to the 5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// thread that the ComponentCloudPolicyService runs on whenever the policy 5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// changes. 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ComponentCloudPolicyService::Backend 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : public ComponentCloudPolicyStore::Delegate { 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 6258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // This class can be instantiated on any thread but from then on, may be 6358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // accessed via the |task_runner_| only. Policy changes are posted to the 6458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // |service| via the |service_task_runner|. The |cache| is used to load and 6558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // store local copies of the downloaded policies. 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Backend(base::WeakPtr<ComponentCloudPolicyService> service, 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> task_runner, 6858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> service_task_runner, 69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<ResourceCache> cache, 70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<ExternalPolicyDataFetcher> external_policy_data_fetcher); 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual ~Backend(); 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // |username| and |dm_token| will be used to validate the cached policies. 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SetCredentials(const std::string& username, const std::string& dm_token); 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Loads the |store_| and starts downloading updates. 78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void Init(scoped_refptr<SchemaMap> schema_map); 79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Passes a policy protobuf to the backend, to start its validation and 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // eventual download of the policy data on the background thread. 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void UpdateExternalPolicy(scoped_ptr<em::PolicyFetchResponse> response); 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ComponentCloudPolicyStore::Delegate implementation: 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnComponentCloudPolicyStoreUpdated() OVERRIDE; 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Passes the current SchemaMap so that the disk cache can purge components 88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // that aren't being tracked anymore. 89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // |removed| is a list of namespaces that were present in the previous 90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // schema and have been removed in the updated version. 91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void OnSchemasUpdated(scoped_refptr<SchemaMap> schema_map, 92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<PolicyNamespaceList> removed); 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 9558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // The ComponentCloudPolicyService that owns |this|. Used to inform the 9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // |service_| when policy changes. 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::WeakPtr<ComponentCloudPolicyService> service_; 9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 9958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // The thread that |this| runs on. Used to post tasks to be run by |this|. 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> task_runner_; 10158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 10258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // The thread that the |service_| runs on. Used to post policy changes to the 10358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // right thread. 10458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> service_task_runner_; 10558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceCache> cache_; 107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<ExternalPolicyDataFetcher> external_policy_data_fetcher_; 108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ComponentCloudPolicyStore store_; 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ComponentCloudPolicyUpdater> updater_; 110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<SchemaMap> schema_map_; 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(Backend); 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ComponentCloudPolicyService::Backend::Backend( 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::WeakPtr<ComponentCloudPolicyService> service, 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> task_runner, 11858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> service_task_runner, 119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<ResourceCache> cache, 120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<ExternalPolicyDataFetcher> external_policy_data_fetcher) 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : service_(service), 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) task_runner_(task_runner), 12358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) service_task_runner_(service_task_runner), 124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) cache_(cache.Pass()), 125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) external_policy_data_fetcher_(external_policy_data_fetcher.Pass()), 126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) store_(this, cache_.get()) {} 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ComponentCloudPolicyService::Backend::~Backend() {} 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ComponentCloudPolicyService::Backend::SetCredentials( 131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& username, 132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& dm_token) { 133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (username.empty() || dm_token.empty()) { 134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // No sign-in credentials, so drop any cached policy. 135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) store_.Clear(); 136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) store_.SetCredentials(username, dm_token); 138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ComponentCloudPolicyService::Backend::Init( 142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<SchemaMap> schema_map) { 143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(!schema_map_); 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OnSchemasUpdated(schema_map, scoped_ptr<PolicyNamespaceList>()); 146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Read the initial policy. Note that this does not trigger notifications 148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // through OnComponentCloudPolicyStoreUpdated. Note also that the cached 149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // data may contain names or values that don't match the schema for that 150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // component; the data must be cached without modifications so that its 151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // integrity can be verified using the hash, but it must also be filtered 152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // right after a Load(). 153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) store_.Load(); 154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<PolicyBundle> bundle(new PolicyBundle); 155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bundle->CopyFrom(store_.policy()); 156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) schema_map_->FilterBundle(bundle.get()); 157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Start downloading any pending data. 159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) updater_.reset(new ComponentCloudPolicyUpdater( 160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) task_runner_, external_policy_data_fetcher_.Pass(), &store_)); 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 16258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) service_task_runner_->PostTask( 16358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) FROM_HERE, 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&ComponentCloudPolicyService::OnBackendInitialized, 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) service_, 166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Passed(&bundle))); 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ComponentCloudPolicyService::Backend::UpdateExternalPolicy( 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<em::PolicyFetchResponse> response) { 171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) updater_->UpdateExternalPolicy(response.Pass()); 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ComponentCloudPolicyService::Backend:: 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnComponentCloudPolicyStoreUpdated() { 176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!schema_map_) { 177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Ignore notifications triggered by the initial Purge or Clear. 178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<PolicyBundle> bundle(new PolicyBundle); 182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bundle->CopyFrom(store_.policy()); 183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) schema_map_->FilterBundle(bundle.get()); 18458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) service_task_runner_->PostTask( 18558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) FROM_HERE, 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&ComponentCloudPolicyService::OnPolicyUpdated, 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) service_, 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&bundle))); 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ComponentCloudPolicyService::Backend::OnSchemasUpdated( 192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<SchemaMap> schema_map, 193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<PolicyNamespaceList> removed) { 194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Purge any components that have been removed. 195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const DomainMap& domains = schema_map->GetDomains(); 196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (DomainMap::const_iterator domain = domains.begin(); 197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) domain != domains.end(); ++domain) { 198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) store_.Purge(domain->first, 199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Bind(&NotInSchemaMap, schema_map, domain->first)); 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Set |schema_map_| after purging so that the notifications from the store 203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // are ignored on the first OnSchemasUpdated() call from Init(). 204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) schema_map_ = schema_map; 20590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (removed) { 207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (size_t i = 0; i < removed->size(); ++i) 208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) updater_->CancelUpdate((*removed)[i]); 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ComponentCloudPolicyService::ComponentCloudPolicyService( 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Delegate* delegate, 214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SchemaRegistry* schema_registry, 215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CloudPolicyCore* core, 21658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_ptr<ResourceCache> cache, 217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<net::URLRequestContextGetter> request_context, 21858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> backend_task_runner, 21958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> io_task_runner) 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : delegate_(delegate), 221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) schema_registry_(schema_registry), 222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) core_(core), 223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) request_context_(request_context), 22458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) backend_task_runner_(backend_task_runner), 22558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) io_task_runner_(io_task_runner), 226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) current_schema_map_(new SchemaMap), 227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) started_loading_initial_policy_(false), 228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) loaded_initial_policy_(false), 229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) is_registered_for_cloud_policy_(false), 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_ptr_factory_(this) { 231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) external_policy_data_fetcher_backend_.reset( 232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new ExternalPolicyDataFetcherBackend(io_task_runner_, request_context)); 233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 234f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) backend_.reset( 235f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new Backend(weak_ptr_factory_.GetWeakPtr(), 236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) backend_task_runner_, 237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::MessageLoopProxy::current(), 238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) cache.Pass(), 239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) external_policy_data_fetcher_backend_->CreateFrontend( 240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) backend_task_runner_))); 241f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) schema_registry_->AddObserver(this); 243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) core_->store()->AddObserver(this); 244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Wait for the store and the schema registry to become ready before 246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // initializing the backend, so that it can get the initial list of 247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // components and the cached credentials (if any) to validate the cached 248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // policies. 249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (core_->store()->is_initialized()) 250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OnStoreLoaded(core_->store()); 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ComponentCloudPolicyService::~ComponentCloudPolicyService() { 25458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(CalledOnValidThread()); 255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) schema_registry_->RemoveObserver(this); 257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) core_->store()->RemoveObserver(this); 258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) core_->RemoveObserver(this); 259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (core_->client()) 260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OnCoreDisconnecting(core_); 261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 26258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) io_task_runner_->DeleteSoon(FROM_HERE, 26358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) external_policy_data_fetcher_backend_.release()); 26458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) backend_task_runner_->DeleteSoon(FROM_HERE, backend_.release()); 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ComponentCloudPolicyService::SupportsDomain(PolicyDomain domain) { 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ComponentCloudPolicyStore::SupportsDomain(domain); 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 272a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ComponentCloudPolicyService::ClearCache() { 273a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(CalledOnValidThread()); 274a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Empty credentials will wipe the cache. 275a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) backend_task_runner_->PostTask(FROM_HERE, 276a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Bind(&Backend::SetCredentials, 277a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Unretained(backend_.get()), 278a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::string(), std::string())); 279a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 280a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ComponentCloudPolicyService::OnSchemaRegistryReady() { 28258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(CalledOnValidThread()); 283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InitializeIfReady(); 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ComponentCloudPolicyService::OnSchemaRegistryUpdated( 287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool has_new_schemas) { 28858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(CalledOnValidThread()); 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Ignore schema updates until the backend is initialized. 291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // OnBackendInitialized() will send the current schema to the backend again, 292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // in case it was updated before the backend initialized. 293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!loaded_initial_policy_) 294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SetCurrentSchema(); 297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ComponentCloudPolicyService::OnCoreConnected(CloudPolicyCore* core) { 300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(CalledOnValidThread()); 301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_EQ(core_, core); 302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) core_->client()->AddObserver(this); 304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Immediately load any PolicyFetchResponses that the client may already 306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // have. 307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OnPolicyFetched(core_->client()); 308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Register the current namespaces at the client. 310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) current_schema_map_ = new SchemaMap(); 311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SetCurrentSchema(); 312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 313f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 314f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ComponentCloudPolicyService::OnCoreDisconnecting(CloudPolicyCore* core) { 315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(CalledOnValidThread()); 316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_EQ(core_, core); 317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) core_->client()->RemoveObserver(this); 319f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Remove all the namespaces from the client. 321f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<SchemaMap> empty = new SchemaMap(); 322f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PolicyNamespaceList removed; 323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PolicyNamespaceList added; 324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) empty->GetChanges(current_schema_map_, &removed, &added); 325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (size_t i = 0; i < removed.size(); ++i) { 326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PolicyNamespaceKey key; 327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (ToPolicyNamespaceKey(removed[i], &key)) 328f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) core_->client()->RemoveNamespaceToFetch(key); 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 332f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ComponentCloudPolicyService::OnRefreshSchedulerStarted( 333f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CloudPolicyCore* core) { 334f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Ignored. 335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 336f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 337f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ComponentCloudPolicyService::OnStoreLoaded(CloudPolicyStore* store) { 33858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(CalledOnValidThread()); 339f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_EQ(core_->store(), store); 340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const bool was_registered_before = is_registered_for_cloud_policy_; 342f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 343f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Send the current credentials to the backend; do this whenever the store 344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // updates, to handle the case of the user registering for policy after the 345f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // session starts, or the user signing out. 346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const em::PolicyData* policy = core_->store()->policy(); 347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string username; 348f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string request_token; 349f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (policy && policy->has_username() && policy->has_request_token()) { 350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) is_registered_for_cloud_policy_ = true; 351f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) username = policy->username(); 352f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) request_token = policy->request_token(); 353f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 354f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) is_registered_for_cloud_policy_ = false; 355f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 357f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Empty credentials will wipe the cache. 35890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) backend_task_runner_->PostTask(FROM_HERE, 359f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Bind(&Backend::SetCredentials, 36058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::Unretained(backend_.get()), 361f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) username, 362f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) request_token)); 363f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 364f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!loaded_initial_policy_) { 365f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // This is the initial load; check if we're ready to initialize the 366f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // backend, regardless of the signin state. 367f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InitializeIfReady(); 368f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else if (!was_registered_before && is_registered_for_cloud_policy_) { 369f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // We are already initialized, but just sent credentials to the backend for 370f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // the first time; this means that the user was not registered for cloud 371f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // policy on startup but registered during the session. 372f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // 373f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // When that happens, OnPolicyFetched() is sent to observers before the 374f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // CloudPolicyStore gets a chance to verify the user policy. In those cases, 375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // the backend gets the PolicyFetchResponses before it has the credentials 376f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // and therefore the validation of those responses fails. 377f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Reload any PolicyFetchResponses that the client may have now so that 378f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // validation is retried with the credentials in place. 379f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (core_->client()) 380f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OnPolicyFetched(core_->client()); 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 382f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 38390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 384f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ComponentCloudPolicyService::OnStoreError(CloudPolicyStore* store) { 385f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(CalledOnValidThread()); 386f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OnStoreLoaded(store); 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ComponentCloudPolicyService::OnPolicyFetched(CloudPolicyClient* client) { 39058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(CalledOnValidThread()); 391f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_EQ(core_->client(), client); 392f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 393f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!is_registered_for_cloud_policy_) { 394f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Trying to load any policies now will fail validation. An OnStoreLoaded() 395f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // notification should follow soon, after the main user policy has been 396f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // validated and stored. 397f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 398f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 399f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Pass each PolicyFetchResponse whose policy type is registered to the 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Backend. 402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const CloudPolicyClient::ResponseMap& responses = 403f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) core_->client()->responses(); 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (CloudPolicyClient::ResponseMap::const_iterator it = responses.begin(); 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != responses.end(); ++it) { 406f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PolicyNamespace ns; 407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (ToPolicyNamespace(it->first, &ns) && 408f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) current_schema_map_->GetSchema(ns)) { 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<em::PolicyFetchResponse> response( 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new em::PolicyFetchResponse(*it->second)); 41158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) backend_task_runner_->PostTask( 41258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) FROM_HERE, 41358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::Bind(&Backend::UpdateExternalPolicy, 41458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::Unretained(backend_.get()), 41558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::Passed(&response))); 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ComponentCloudPolicyService::OnRegistrationStateChanged( 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CloudPolicyClient* client) { 42258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(CalledOnValidThread()); 423f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Ignored; the registration state is tracked by looking at the 424f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // CloudPolicyStore instead. 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ComponentCloudPolicyService::OnClientError(CloudPolicyClient* client) { 42858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(CalledOnValidThread()); 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Ignored. 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 432f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ComponentCloudPolicyService::InitializeIfReady() { 43358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(CalledOnValidThread()); 434f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (started_loading_initial_policy_ || !schema_registry_->IsReady() || 435f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) !core_->store()->is_initialized()) { 436f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 438f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The initial list of components is ready. Initialize the backend now, which 439f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // will call back to OnBackendInitialized. 440f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) backend_task_runner_->PostTask(FROM_HERE, 441f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Bind(&Backend::Init, 442f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Unretained(backend_.get()), 443f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) schema_registry_->schema_map())); 444f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) started_loading_initial_policy_ = true; 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ComponentCloudPolicyService::OnBackendInitialized( 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<PolicyBundle> initial_policy) { 44958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(CalledOnValidThread()); 450f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(!loaded_initial_policy_); 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 452f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) loaded_initial_policy_ = true; 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 454f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // We're now ready to serve the initial policy; notify the policy observers. 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnPolicyUpdated(initial_policy.Pass()); 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 457f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Start observing the core and tracking the state of the client. 458f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) core_->AddObserver(this); 459f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 460f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (core_->client()) { 461f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OnCoreConnected(core_); 462f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 463f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Send the current schema to the backend, in case it has changed while the 464f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // backend was initializing. OnCoreConnected() also does this if a client is 465f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // already connected. 466f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SetCurrentSchema(); 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 470f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ComponentCloudPolicyService::SetCurrentSchema() { 47158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(CalledOnValidThread()); 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 473f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<PolicyNamespaceList> removed(new PolicyNamespaceList); 474f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PolicyNamespaceList added; 475f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const scoped_refptr<SchemaMap>& new_schema_map = 476f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) schema_registry_->schema_map(); 477f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new_schema_map->GetChanges(current_schema_map_, removed.get(), &added); 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 479f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) current_schema_map_ = new_schema_map; 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 481f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (core_->client()) { 482f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (size_t i = 0; i < removed->size(); ++i) { 483f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PolicyNamespaceKey key; 484f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (ToPolicyNamespaceKey((*removed)[i], &key)) 485f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) core_->client()->RemoveNamespaceToFetch(key); 486f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 487f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 488f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool added_namespaces_to_client = false; 489f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (size_t i = 0; i < added.size(); ++i) { 490f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PolicyNamespaceKey key; 491f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (ToPolicyNamespaceKey(added[i], &key)) { 492f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) core_->client()->AddNamespaceToFetch(key); 493f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) added_namespaces_to_client = true; 494f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 495f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 496f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 497f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (added_namespaces_to_client) 498f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) core_->RefreshSoon(); 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 500f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 501f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) backend_task_runner_->PostTask(FROM_HERE, 502f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Bind(&Backend::OnSchemasUpdated, 503f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Unretained(backend_.get()), 504f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) current_schema_map_, 505f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Passed(&removed))); 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 508f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ComponentCloudPolicyService::OnPolicyUpdated( 509f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<PolicyBundle> policy) { 51058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(CalledOnValidThread()); 511f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) policy_.Swap(policy.get()); 512f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_->OnComponentCloudPolicyUpdated(); 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace policy 516