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 ToPolicyNamespace(const PolicyNamespaceKey& key, PolicyNamespace* ns) { 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!ComponentCloudPolicyStore::GetPolicyDomain(key.first, &ns->domain)) 40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ns->component_id = key.second; 42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} // namespace 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ComponentCloudPolicyService::Delegate::~Delegate() {} 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Owns the objects that live on the background thread, and posts back to the 5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// thread that the ComponentCloudPolicyService runs on whenever the policy 5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// changes. 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ComponentCloudPolicyService::Backend 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : public ComponentCloudPolicyStore::Delegate { 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 5558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // This class can be instantiated on any thread but from then on, may be 5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // accessed via the |task_runner_| only. Policy changes are posted to the 5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // |service| via the |service_task_runner|. The |cache| is used to load and 5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // store local copies of the downloaded policies. 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Backend(base::WeakPtr<ComponentCloudPolicyService> service, 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> task_runner, 6158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> service_task_runner, 62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<ResourceCache> cache, 63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<ExternalPolicyDataFetcher> external_policy_data_fetcher); 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual ~Backend(); 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // |username| and |dm_token| will be used to validate the cached policies. 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SetCredentials(const std::string& username, const std::string& dm_token); 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Loads the |store_| and starts downloading updates. 71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void Init(scoped_refptr<SchemaMap> schema_map); 72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Passes a policy protobuf to the backend, to start its validation and 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // eventual download of the policy data on the background thread. 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void UpdateExternalPolicy(scoped_ptr<em::PolicyFetchResponse> response); 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ComponentCloudPolicyStore::Delegate implementation: 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnComponentCloudPolicyStoreUpdated() OVERRIDE; 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Passes the current SchemaMap so that the disk cache can purge components 81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // that aren't being tracked anymore. 82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // |removed| is a list of namespaces that were present in the previous 83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // schema and have been removed in the updated version. 84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void OnSchemasUpdated(scoped_refptr<SchemaMap> schema_map, 85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<PolicyNamespaceList> removed); 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 8858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // The ComponentCloudPolicyService that owns |this|. Used to inform the 8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // |service_| when policy changes. 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::WeakPtr<ComponentCloudPolicyService> service_; 9158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // The thread that |this| runs on. Used to post tasks to be run by |this|. 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> task_runner_; 9458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 9558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // The thread that the |service_| runs on. Used to post policy changes to the 9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // right thread. 9758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> service_task_runner_; 9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceCache> cache_; 100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<ExternalPolicyDataFetcher> external_policy_data_fetcher_; 101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ComponentCloudPolicyStore store_; 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ComponentCloudPolicyUpdater> updater_; 103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool initialized_; 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(Backend); 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ComponentCloudPolicyService::Backend::Backend( 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::WeakPtr<ComponentCloudPolicyService> service, 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> task_runner, 11158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> service_task_runner, 112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<ResourceCache> cache, 113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<ExternalPolicyDataFetcher> external_policy_data_fetcher) 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : service_(service), 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) task_runner_(task_runner), 11658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) service_task_runner_(service_task_runner), 117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) cache_(cache.Pass()), 118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) external_policy_data_fetcher_(external_policy_data_fetcher.Pass()), 119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch store_(this, cache_.get()), 120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch initialized_(false) {} 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ComponentCloudPolicyService::Backend::~Backend() {} 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ComponentCloudPolicyService::Backend::SetCredentials( 125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& username, 126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& dm_token) { 127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (username.empty() || dm_token.empty()) { 128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // No sign-in credentials, so drop any cached policy. 129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) store_.Clear(); 130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) store_.SetCredentials(username, dm_token); 132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ComponentCloudPolicyService::Backend::Init( 136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<SchemaMap> schema_map) { 137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(!initialized_); 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OnSchemasUpdated(schema_map, scoped_ptr<PolicyNamespaceList>()); 140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Read the initial policy. Note that this does not trigger notifications 142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // through OnComponentCloudPolicyStoreUpdated. Note also that the cached 143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // data may contain names or values that don't match the schema for that 144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // component; the data must be cached without modifications so that its 145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // integrity can be verified using the hash, but it must also be filtered 146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // right after a Load(). 147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) store_.Load(); 148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<PolicyBundle> bundle(new PolicyBundle); 149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bundle->CopyFrom(store_.policy()); 150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Start downloading any pending data. 152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) updater_.reset(new ComponentCloudPolicyUpdater( 153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) task_runner_, external_policy_data_fetcher_.Pass(), &store_)); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 15558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) service_task_runner_->PostTask( 15658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) FROM_HERE, 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&ComponentCloudPolicyService::OnBackendInitialized, 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) service_, 159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Passed(&bundle))); 160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch initialized_ = true; 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ComponentCloudPolicyService::Backend::UpdateExternalPolicy( 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<em::PolicyFetchResponse> response) { 166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) updater_->UpdateExternalPolicy(response.Pass()); 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ComponentCloudPolicyService::Backend:: 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnComponentCloudPolicyStoreUpdated() { 171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!initialized_) { 172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Ignore notifications triggered by the initial Purge or Clear. 173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<PolicyBundle> bundle(new PolicyBundle); 177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bundle->CopyFrom(store_.policy()); 17858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) service_task_runner_->PostTask( 17958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) FROM_HERE, 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&ComponentCloudPolicyService::OnPolicyUpdated, 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) service_, 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&bundle))); 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ComponentCloudPolicyService::Backend::OnSchemasUpdated( 186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<SchemaMap> schema_map, 187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<PolicyNamespaceList> removed) { 188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Purge any components that have been removed. 189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const DomainMap& domains = schema_map->GetDomains(); 190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (DomainMap::const_iterator domain = domains.begin(); 191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) domain != domains.end(); ++domain) { 192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) store_.Purge(domain->first, 193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Bind(&NotInSchemaMap, schema_map, domain->first)); 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (removed) { 197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (size_t i = 0; i < removed->size(); ++i) 198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) updater_->CancelUpdate((*removed)[i]); 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ComponentCloudPolicyService::ComponentCloudPolicyService( 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Delegate* delegate, 204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SchemaRegistry* schema_registry, 205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CloudPolicyCore* core, 20658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_ptr<ResourceCache> cache, 207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<net::URLRequestContextGetter> request_context, 20858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> backend_task_runner, 20958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> io_task_runner) 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : delegate_(delegate), 211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) schema_registry_(schema_registry), 212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) core_(core), 213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) request_context_(request_context), 21458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) backend_task_runner_(backend_task_runner), 21558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) io_task_runner_(io_task_runner), 216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) current_schema_map_(new SchemaMap), 217116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch unfiltered_policy_(new PolicyBundle), 218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) started_loading_initial_policy_(false), 219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) loaded_initial_policy_(false), 220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) is_registered_for_cloud_policy_(false), 221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_ptr_factory_(this) { 222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) external_policy_data_fetcher_backend_.reset( 223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new ExternalPolicyDataFetcherBackend(io_task_runner_, request_context)); 224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) backend_.reset( 226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new Backend(weak_ptr_factory_.GetWeakPtr(), 227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) backend_task_runner_, 228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::MessageLoopProxy::current(), 229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) cache.Pass(), 230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) external_policy_data_fetcher_backend_->CreateFrontend( 231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) backend_task_runner_))); 232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) schema_registry_->AddObserver(this); 234f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) core_->store()->AddObserver(this); 235f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Wait for the store and the schema registry to become ready before 237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // initializing the backend, so that it can get the initial list of 238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // components and the cached credentials (if any) to validate the cached 239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // policies. 240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (core_->store()->is_initialized()) 241f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OnStoreLoaded(core_->store()); 242116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 243116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Start observing the core and tracking the state of the client. 244116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch core_->AddObserver(this); 245116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (core_->client()) 246116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch OnCoreConnected(core_); 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ComponentCloudPolicyService::~ComponentCloudPolicyService() { 25058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(CalledOnValidThread()); 251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) schema_registry_->RemoveObserver(this); 253f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) core_->store()->RemoveObserver(this); 254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) core_->RemoveObserver(this); 255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (core_->client()) 256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OnCoreDisconnecting(core_); 257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 25858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) io_task_runner_->DeleteSoon(FROM_HERE, 25958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) external_policy_data_fetcher_backend_.release()); 26058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) backend_task_runner_->DeleteSoon(FROM_HERE, backend_.release()); 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ComponentCloudPolicyService::SupportsDomain(PolicyDomain domain) { 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ComponentCloudPolicyStore::SupportsDomain(domain); 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 268a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ComponentCloudPolicyService::ClearCache() { 269a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(CalledOnValidThread()); 270a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Empty credentials will wipe the cache. 271a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) backend_task_runner_->PostTask(FROM_HERE, 272a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Bind(&Backend::SetCredentials, 273a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Unretained(backend_.get()), 274a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::string(), std::string())); 275a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 276a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ComponentCloudPolicyService::OnSchemaRegistryReady() { 27858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(CalledOnValidThread()); 279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InitializeIfReady(); 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ComponentCloudPolicyService::OnSchemaRegistryUpdated( 283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool has_new_schemas) { 28458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(CalledOnValidThread()); 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Ignore schema updates until the backend is initialized. 287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // OnBackendInitialized() will send the current schema to the backend again, 288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // in case it was updated before the backend initialized. 289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!loaded_initial_policy_) 290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ReloadSchema(); 293116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 294116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Filter the |unfiltered_policy_| again, now that |current_schema_map_| has 295116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // been updated. We must make sure we never serve invalid policy; we must 296116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // also filter again if an invalid Schema has now been loaded. 297116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch OnPolicyUpdated(unfiltered_policy_.Pass()); 298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ComponentCloudPolicyService::OnCoreConnected(CloudPolicyCore* core) { 301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(CalledOnValidThread()); 302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_EQ(core_, core); 303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) core_->client()->AddObserver(this); 305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 3065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Register the supported policy domains at the client. 3075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu core_->client()->AddNamespaceToFetch( 3085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu PolicyNamespaceKey(dm_protocol::kChromeExtensionPolicyType, "")); 3095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Immediately load any PolicyFetchResponses that the client may already 311116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // have if the backend is ready. 312116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (loaded_initial_policy_) 313116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch OnPolicyFetched(core_->client()); 314f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ComponentCloudPolicyService::OnCoreDisconnecting(CloudPolicyCore* core) { 317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(CalledOnValidThread()); 318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_EQ(core_, core); 319f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) core_->client()->RemoveObserver(this); 321f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 322f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Remove all the namespaces from the client. 3235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu core_->client()->RemoveNamespaceToFetch( 3245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu PolicyNamespaceKey(dm_protocol::kChromeExtensionPolicyType, "")); 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ComponentCloudPolicyService::OnRefreshSchedulerStarted( 328f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CloudPolicyCore* core) { 329f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Ignored. 330f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 331f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 332f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ComponentCloudPolicyService::OnStoreLoaded(CloudPolicyStore* store) { 33358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(CalledOnValidThread()); 334f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_EQ(core_->store(), store); 335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 336f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const bool was_registered_before = is_registered_for_cloud_policy_; 337f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 338f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Send the current credentials to the backend; do this whenever the store 339f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // updates, to handle the case of the user registering for policy after the 340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // session starts, or the user signing out. 341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const em::PolicyData* policy = core_->store()->policy(); 342f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string username; 343f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string request_token; 344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (policy && policy->has_username() && policy->has_request_token()) { 345f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) is_registered_for_cloud_policy_ = true; 346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) username = policy->username(); 347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) request_token = policy->request_token(); 348f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 349f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) is_registered_for_cloud_policy_ = false; 350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 352f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Empty credentials will wipe the cache. 35390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) backend_task_runner_->PostTask(FROM_HERE, 354f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Bind(&Backend::SetCredentials, 35558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::Unretained(backend_.get()), 356f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) username, 357f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) request_token)); 358f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 359f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!loaded_initial_policy_) { 360f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // This is the initial load; check if we're ready to initialize the 361f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // backend, regardless of the signin state. 362f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InitializeIfReady(); 363f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else if (!was_registered_before && is_registered_for_cloud_policy_) { 364f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // We are already initialized, but just sent credentials to the backend for 365f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // the first time; this means that the user was not registered for cloud 366f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // policy on startup but registered during the session. 367f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // 368f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // When that happens, OnPolicyFetched() is sent to observers before the 369f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // CloudPolicyStore gets a chance to verify the user policy. In those cases, 370f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // the backend gets the PolicyFetchResponses before it has the credentials 371f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // and therefore the validation of those responses fails. 372f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Reload any PolicyFetchResponses that the client may have now so that 373f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // validation is retried with the credentials in place. 374f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (core_->client()) 375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OnPolicyFetched(core_->client()); 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 377f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 37890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 379f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ComponentCloudPolicyService::OnStoreError(CloudPolicyStore* store) { 380f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(CalledOnValidThread()); 381f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OnStoreLoaded(store); 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ComponentCloudPolicyService::OnPolicyFetched(CloudPolicyClient* client) { 38558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(CalledOnValidThread()); 386f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_EQ(core_->client(), client); 387f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 388f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!is_registered_for_cloud_policy_) { 389f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Trying to load any policies now will fail validation. An OnStoreLoaded() 390f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // notification should follow soon, after the main user policy has been 391f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // validated and stored. 392f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 393f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 394f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Pass each PolicyFetchResponse whose policy type is registered to the 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Backend. 397f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const CloudPolicyClient::ResponseMap& responses = 398f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) core_->client()->responses(); 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (CloudPolicyClient::ResponseMap::const_iterator it = responses.begin(); 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != responses.end(); ++it) { 401f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PolicyNamespace ns; 402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (ToPolicyNamespace(it->first, &ns) && 403f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) current_schema_map_->GetSchema(ns)) { 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<em::PolicyFetchResponse> response( 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new em::PolicyFetchResponse(*it->second)); 40658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) backend_task_runner_->PostTask( 40758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) FROM_HERE, 40858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::Bind(&Backend::UpdateExternalPolicy, 40958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::Unretained(backend_.get()), 41058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::Passed(&response))); 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ComponentCloudPolicyService::OnRegistrationStateChanged( 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CloudPolicyClient* client) { 41758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(CalledOnValidThread()); 418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Ignored; the registration state is tracked by looking at the 419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // CloudPolicyStore instead. 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ComponentCloudPolicyService::OnClientError(CloudPolicyClient* client) { 42358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(CalledOnValidThread()); 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Ignored. 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 427f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ComponentCloudPolicyService::InitializeIfReady() { 42858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(CalledOnValidThread()); 429f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (started_loading_initial_policy_ || !schema_registry_->IsReady() || 430f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) !core_->store()->is_initialized()) { 431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 433116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 434f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The initial list of components is ready. Initialize the backend now, which 435f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // will call back to OnBackendInitialized. 436f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) backend_task_runner_->PostTask(FROM_HERE, 437f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Bind(&Backend::Init, 438f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Unretained(backend_.get()), 439f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) schema_registry_->schema_map())); 440f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) started_loading_initial_policy_ = true; 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ComponentCloudPolicyService::OnBackendInitialized( 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<PolicyBundle> initial_policy) { 44558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(CalledOnValidThread()); 446f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(!loaded_initial_policy_); 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 448f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) loaded_initial_policy_ = true; 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Send the current schema to the backend, in case it has changed while the 4515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // backend was initializing. 4525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ReloadSchema(); 4535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 454116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // We're now ready to serve the initial policy; notify the policy observers. 455116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch OnPolicyUpdated(initial_policy.Pass()); 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid ComponentCloudPolicyService::ReloadSchema() { 45958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(CalledOnValidThread()); 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 461f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<PolicyNamespaceList> removed(new PolicyNamespaceList); 462f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PolicyNamespaceList added; 463f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const scoped_refptr<SchemaMap>& new_schema_map = 464f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) schema_registry_->schema_map(); 465f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new_schema_map->GetChanges(current_schema_map_, removed.get(), &added); 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 467f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) current_schema_map_ = new_schema_map; 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Send the updated SchemaMap and a list of removed components to the 4705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // backend. 471f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) backend_task_runner_->PostTask(FROM_HERE, 472f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Bind(&Backend::OnSchemasUpdated, 473f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Unretained(backend_.get()), 474f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) current_schema_map_, 475f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Passed(&removed))); 476116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 477116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Have another look at the client if the core is already connected. 478116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // The client may have already fetched policy for some component and it was 479116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // previously ignored because the component wasn't listed in the schema map. 480116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // There's no point in fetching policy from the server again; the server 481116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // always pushes all the components it knows about. 482116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (core_->client()) 483116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch OnPolicyFetched(core_->client()); 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 486f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ComponentCloudPolicyService::OnPolicyUpdated( 487f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<PolicyBundle> policy) { 48858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(CalledOnValidThread()); 489116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 490116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Store the current unfiltered policies. 491116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch unfiltered_policy_ = policy.Pass(); 492116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 493116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Make a copy in |policy_| and filter it; this is what's passed to the 494116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // outside world. 495116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch policy_.CopyFrom(*unfiltered_policy_); 496116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_schema_map_->FilterBundle(&policy_); 497116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 498f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_->OnComponentCloudPolicyUpdated(); 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace policy 502