| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/policy/cloud/component_cloud_policy_service.h" | 5 #include "chrome/browser/policy/cloud/component_cloud_policy_service.h" |
| 6 | 6 |
| 7 #include <map> |
| 8 #include <string> |
| 9 #include <utility> |
| 10 |
| 7 #include "base/bind.h" | 11 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 12 #include "base/bind_helpers.h" |
| 9 #include "base/location.h" | 13 #include "base/location.h" |
| 10 #include "base/logging.h" | 14 #include "base/logging.h" |
| 11 #include "base/message_loop/message_loop_proxy.h" | 15 #include "base/message_loop/message_loop_proxy.h" |
| 12 #include "base/pickle.h" | 16 #include "base/pickle.h" |
| 13 #include "base/sequenced_task_runner.h" | 17 #include "base/sequenced_task_runner.h" |
| 14 #include "base/stl_util.h" | 18 #include "base/stl_util.h" |
| 15 #include "chrome/browser/policy/cloud/component_cloud_policy_store.h" | 19 #include "chrome/browser/policy/cloud/component_cloud_policy_store.h" |
| 16 #include "chrome/browser/policy/cloud/component_cloud_policy_updater.h" | 20 #include "chrome/browser/policy/cloud/component_cloud_policy_updater.h" |
| 17 #include "chrome/browser/policy/cloud/external_policy_data_fetcher.h" | 21 #include "chrome/browser/policy/cloud/external_policy_data_fetcher.h" |
| 18 #include "chrome/browser/policy/cloud/resource_cache.h" | 22 #include "chrome/browser/policy/cloud/resource_cache.h" |
| 19 #include "chrome/browser/policy/policy_domain_descriptor.h" | |
| 20 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h" | 23 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h" |
| 24 #include "chrome/browser/policy/schema_map.h" |
| 25 #include "components/policy/core/common/schema.h" |
| 21 #include "net/url_request/url_request_context_getter.h" | 26 #include "net/url_request/url_request_context_getter.h" |
| 22 | 27 |
| 23 namespace em = enterprise_management; | 28 namespace em = enterprise_management; |
| 24 | 29 |
| 25 namespace policy { | 30 namespace policy { |
| 26 | 31 |
| 32 const char ComponentCloudPolicyService::kComponentNamespaceCache[] = |
| 33 "component-namespace-cache"; |
| 34 |
| 27 namespace { | 35 namespace { |
| 28 | 36 |
| 29 void GetComponentIds(scoped_refptr<const PolicyDomainDescriptor>& descriptor, | 37 bool NotInSchemaMap(const scoped_refptr<SchemaMap> schema_map, |
| 30 std::set<std::string>* set) { | 38 PolicyDomain domain, |
| 31 const PolicyDomainDescriptor::SchemaMap& map = descriptor->components(); | 39 const std::string& component_id) { |
| 32 for (PolicyDomainDescriptor::SchemaMap::const_iterator it = map.begin(); | 40 return schema_map->GetSchema(PolicyNamespace(domain, component_id)) == NULL; |
| 33 it != map.end(); ++it) { | |
| 34 set->insert(it->first); | |
| 35 } | |
| 36 } | 41 } |
| 37 | 42 |
| 38 } // namespace | 43 } // namespace |
| 39 | 44 |
| 40 const char ComponentCloudPolicyService::kComponentNamespaceCache[] = | |
| 41 "component-namespace-cache"; | |
| 42 | |
| 43 ComponentCloudPolicyService::Delegate::~Delegate() {} | 45 ComponentCloudPolicyService::Delegate::~Delegate() {} |
| 44 | 46 |
| 45 // Owns the objects that live on the background thread, and posts back to the | 47 // Owns the objects that live on the background thread, and posts back to the |
| 46 // thread that the ComponentCloudPolicyService runs on whenever the policy | 48 // thread that the ComponentCloudPolicyService runs on whenever the policy |
| 47 // changes. | 49 // changes. |
| 48 class ComponentCloudPolicyService::Backend | 50 class ComponentCloudPolicyService::Backend |
| 49 : public ComponentCloudPolicyStore::Delegate { | 51 : public ComponentCloudPolicyStore::Delegate { |
| 50 public: | 52 public: |
| 51 // This class can be instantiated on any thread but from then on, may be | 53 // This class can be instantiated on any thread but from then on, may be |
| 52 // accessed via the |task_runner_| only. Policy changes are posted to the | 54 // accessed via the |task_runner_| only. Policy changes are posted to the |
| (...skipping 24 matching lines...) Expand all Loading... |
| 77 void SetCredentials(const std::string& username, const std::string& dm_token); | 79 void SetCredentials(const std::string& username, const std::string& dm_token); |
| 78 | 80 |
| 79 // Passes a policy protobuf to the backend, to start its validation and | 81 // Passes a policy protobuf to the backend, to start its validation and |
| 80 // eventual download of the policy data on the background thread. | 82 // eventual download of the policy data on the background thread. |
| 81 // This is ignored if the backend isn't connected. | 83 // This is ignored if the backend isn't connected. |
| 82 void UpdateExternalPolicy(scoped_ptr<em::PolicyFetchResponse> response); | 84 void UpdateExternalPolicy(scoped_ptr<em::PolicyFetchResponse> response); |
| 83 | 85 |
| 84 // ComponentCloudPolicyStore::Delegate implementation: | 86 // ComponentCloudPolicyStore::Delegate implementation: |
| 85 virtual void OnComponentCloudPolicyStoreUpdated() OVERRIDE; | 87 virtual void OnComponentCloudPolicyStoreUpdated() OVERRIDE; |
| 86 | 88 |
| 87 // Passes the current descriptor of a domain, so that the disk cache | 89 // Passes the current SchemaMap so that the disk cache can purge components |
| 88 // can purge components that aren't being tracked anymore. | 90 // that aren't being tracked anymore. |
| 89 void RegisterPolicyDomain( | 91 void OnSchemasUpdated(scoped_refptr<SchemaMap> schema_map); |
| 90 scoped_refptr<const PolicyDomainDescriptor> descriptor); | |
| 91 | 92 |
| 92 private: | 93 private: |
| 93 typedef std::map<PolicyDomain, scoped_refptr<const PolicyDomainDescriptor> > | 94 scoped_ptr<PolicyNamespaceKeys> ReadCachedComponents(); |
| 94 DomainMap; | |
| 95 | |
| 96 scoped_ptr<ComponentMap> ReadCachedComponents(); | |
| 97 | 95 |
| 98 // The ComponentCloudPolicyService that owns |this|. Used to inform the | 96 // The ComponentCloudPolicyService that owns |this|. Used to inform the |
| 99 // |service_| when policy changes. | 97 // |service_| when policy changes. |
| 100 base::WeakPtr<ComponentCloudPolicyService> service_; | 98 base::WeakPtr<ComponentCloudPolicyService> service_; |
| 101 | 99 |
| 102 // The thread that |this| runs on. Used to post tasks to be run by |this|. | 100 // The thread that |this| runs on. Used to post tasks to be run by |this|. |
| 103 scoped_refptr<base::SequencedTaskRunner> task_runner_; | 101 scoped_refptr<base::SequencedTaskRunner> task_runner_; |
| 104 | 102 |
| 105 // The thread that the |service_| runs on. Used to post policy changes to the | 103 // The thread that the |service_| runs on. Used to post policy changes to the |
| 106 // right thread. | 104 // right thread. |
| 107 scoped_refptr<base::SequencedTaskRunner> service_task_runner_; | 105 scoped_refptr<base::SequencedTaskRunner> service_task_runner_; |
| 108 | 106 |
| 109 scoped_ptr<ResourceCache> cache_; | 107 scoped_ptr<ResourceCache> cache_; |
| 110 scoped_ptr<ComponentCloudPolicyStore> store_; | 108 scoped_ptr<ComponentCloudPolicyStore> store_; |
| 111 scoped_ptr<ComponentCloudPolicyUpdater> updater_; | 109 scoped_ptr<ComponentCloudPolicyUpdater> updater_; |
| 112 DomainMap domain_map_; | 110 scoped_refptr<SchemaMap> schema_map_; |
| 113 | 111 |
| 114 DISALLOW_COPY_AND_ASSIGN(Backend); | 112 DISALLOW_COPY_AND_ASSIGN(Backend); |
| 115 }; | 113 }; |
| 116 | 114 |
| 117 ComponentCloudPolicyService::Backend::Backend( | 115 ComponentCloudPolicyService::Backend::Backend( |
| 118 base::WeakPtr<ComponentCloudPolicyService> service, | 116 base::WeakPtr<ComponentCloudPolicyService> service, |
| 119 scoped_refptr<base::SequencedTaskRunner> task_runner, | 117 scoped_refptr<base::SequencedTaskRunner> task_runner, |
| 120 scoped_refptr<base::SequencedTaskRunner> service_task_runner, | 118 scoped_refptr<base::SequencedTaskRunner> service_task_runner, |
| 121 scoped_ptr<ResourceCache> cache) | 119 scoped_ptr<ResourceCache> cache) |
| 122 : service_(service), | 120 : service_(service), |
| 123 task_runner_(task_runner), | 121 task_runner_(task_runner), |
| 124 service_task_runner_(service_task_runner), | 122 service_task_runner_(service_task_runner), |
| 125 cache_(cache.Pass()) {} | 123 cache_(cache.Pass()) {} |
| 126 | 124 |
| 127 ComponentCloudPolicyService::Backend::~Backend() {} | 125 ComponentCloudPolicyService::Backend::~Backend() {} |
| 128 | 126 |
| 129 void ComponentCloudPolicyService::Backend::Init() { | 127 void ComponentCloudPolicyService::Backend::Init() { |
| 130 DCHECK(!store_); | 128 DCHECK(!store_); |
| 131 store_.reset(new ComponentCloudPolicyStore(this, cache_.get())); | 129 store_.reset(new ComponentCloudPolicyStore(this, cache_.get())); |
| 132 } | 130 } |
| 133 | 131 |
| 134 void ComponentCloudPolicyService::Backend::FinalizeInit() { | 132 void ComponentCloudPolicyService::Backend::FinalizeInit() { |
| 135 // Read the components that were cached in the last RegisterPolicyDomain() | 133 // Read the components that were cached in the last OnSchemasUpdated() call. |
| 136 // calls for each domain. | 134 scoped_ptr<PolicyNamespaceKeys> components = ReadCachedComponents(); |
| 137 scoped_ptr<ComponentMap> components = ReadCachedComponents(); | |
| 138 | 135 |
| 139 // Read the initial policy. | 136 // Read the initial policy. |
| 140 store_->Load(); | 137 store_->Load(); |
| 141 scoped_ptr<PolicyBundle> policy(new PolicyBundle); | 138 scoped_ptr<PolicyBundle> policy(new PolicyBundle); |
| 142 policy->CopyFrom(store_->policy()); | 139 policy->CopyFrom(store_->policy()); |
| 143 | 140 |
| 144 service_task_runner_->PostTask( | 141 service_task_runner_->PostTask( |
| 145 FROM_HERE, | 142 FROM_HERE, |
| 146 base::Bind(&ComponentCloudPolicyService::OnBackendInitialized, | 143 base::Bind(&ComponentCloudPolicyService::OnBackendInitialized, |
| 147 service_, | 144 service_, |
| (...skipping 20 matching lines...) Expand all Loading... |
| 168 } | 165 } |
| 169 | 166 |
| 170 void ComponentCloudPolicyService::Backend::UpdateExternalPolicy( | 167 void ComponentCloudPolicyService::Backend::UpdateExternalPolicy( |
| 171 scoped_ptr<em::PolicyFetchResponse> response) { | 168 scoped_ptr<em::PolicyFetchResponse> response) { |
| 172 if (updater_) | 169 if (updater_) |
| 173 updater_->UpdateExternalPolicy(response.Pass()); | 170 updater_->UpdateExternalPolicy(response.Pass()); |
| 174 } | 171 } |
| 175 | 172 |
| 176 void ComponentCloudPolicyService::Backend:: | 173 void ComponentCloudPolicyService::Backend:: |
| 177 OnComponentCloudPolicyStoreUpdated() { | 174 OnComponentCloudPolicyStoreUpdated() { |
| 175 if (!schema_map_) { |
| 176 // No schemas have been registered yet, so keep serving the initial policy |
| 177 // obtained from FinalizeInit(). |
| 178 return; |
| 179 } |
| 180 |
| 178 scoped_ptr<PolicyBundle> bundle(new PolicyBundle); | 181 scoped_ptr<PolicyBundle> bundle(new PolicyBundle); |
| 179 bundle->CopyFrom(store_->policy()); | 182 bundle->CopyFrom(store_->policy()); |
| 180 for (DomainMap::iterator it = domain_map_.begin(); | 183 schema_map_->FilterBundle(bundle.get()); |
| 181 it != domain_map_.end(); ++it) { | |
| 182 it->second->FilterBundle(bundle.get()); | |
| 183 } | |
| 184 | |
| 185 service_task_runner_->PostTask( | 184 service_task_runner_->PostTask( |
| 186 FROM_HERE, | 185 FROM_HERE, |
| 187 base::Bind(&ComponentCloudPolicyService::OnPolicyUpdated, | 186 base::Bind(&ComponentCloudPolicyService::OnPolicyUpdated, |
| 188 service_, | 187 service_, |
| 189 base::Passed(&bundle))); | 188 base::Passed(&bundle))); |
| 190 } | 189 } |
| 191 | 190 |
| 192 void ComponentCloudPolicyService::Backend::RegisterPolicyDomain( | 191 void ComponentCloudPolicyService::Backend::OnSchemasUpdated( |
| 193 scoped_refptr<const PolicyDomainDescriptor> descriptor) { | 192 scoped_refptr<SchemaMap> schema_map) { |
| 194 // Store the current list of components in the cache. | 193 // Store the current list of components in the cache. |
| 195 StringSet ids; | 194 const DomainMap& domains = schema_map->GetDomains(); |
| 196 std::string policy_type; | 195 for (DomainMap::const_iterator domain = domains.begin(); |
| 197 if (ComponentCloudPolicyStore::GetPolicyType(descriptor->domain(), | 196 domain != domains.end(); ++domain) { |
| 198 &policy_type)) { | 197 std::string domain_policy_type; |
| 199 GetComponentIds(descriptor, &ids); | 198 if (!ComponentCloudPolicyStore::GetPolicyType(domain->first, |
| 199 &domain_policy_type)) { |
| 200 continue; |
| 201 } |
| 200 Pickle pickle; | 202 Pickle pickle; |
| 201 for (StringSet::const_iterator it = ids.begin(); it != ids.end(); ++it) | 203 const ComponentMap& components = domain->second; |
| 202 pickle.WriteString(*it); | 204 for (ComponentMap::const_iterator comp = components.begin(); |
| 205 comp != components.end(); ++comp) { |
| 206 pickle.WriteString(comp->first); |
| 207 } |
| 203 std::string data(reinterpret_cast<const char*>(pickle.data()), | 208 std::string data(reinterpret_cast<const char*>(pickle.data()), |
| 204 pickle.size()); | 209 pickle.size()); |
| 205 cache_->Store(kComponentNamespaceCache, policy_type, data); | 210 cache_->Store(kComponentNamespaceCache, domain_policy_type, data); |
| 211 |
| 212 // Purge any components that have been removed. |
| 213 if (store_) { |
| 214 store_->Purge(domain->first, |
| 215 base::Bind(&NotInSchemaMap, schema_map, domain->first)); |
| 216 } |
| 206 } | 217 } |
| 207 | 218 |
| 208 domain_map_[descriptor->domain()] = descriptor; | 219 // Serve policies that may have updated while the backend was waiting for |
| 209 | 220 // the schema_map. |
| 210 // Purge any components that have been removed. | 221 const bool trigger_update = !schema_map_; |
| 211 if (store_) | 222 schema_map_ = schema_map; |
| 212 store_->Purge(descriptor->domain(), ids); | 223 if (trigger_update) |
| 224 OnComponentCloudPolicyStoreUpdated(); |
| 213 } | 225 } |
| 214 | 226 |
| 215 scoped_ptr<ComponentCloudPolicyService::ComponentMap> | 227 scoped_ptr<ComponentCloudPolicyService::PolicyNamespaceKeys> |
| 216 ComponentCloudPolicyService::Backend::ReadCachedComponents() { | 228 ComponentCloudPolicyService::Backend::ReadCachedComponents() { |
| 217 scoped_ptr<ComponentMap> components(new ComponentMap); | 229 scoped_ptr<PolicyNamespaceKeys> keys(new PolicyNamespaceKeys); |
| 218 std::map<std::string, std::string> contents; | 230 std::map<std::string, std::string> contents; |
| 219 cache_->LoadAllSubkeys(kComponentNamespaceCache, &contents); | 231 cache_->LoadAllSubkeys(kComponentNamespaceCache, &contents); |
| 220 for (std::map<std::string, std::string>::iterator it = contents.begin(); | 232 for (std::map<std::string, std::string>::iterator it = contents.begin(); |
| 221 it != contents.end(); ++it) { | 233 it != contents.end(); ++it) { |
| 222 PolicyDomain domain; | 234 PolicyDomain domain; |
| 223 if (ComponentCloudPolicyStore::GetPolicyDomain(it->first, &domain)) { | 235 if (ComponentCloudPolicyStore::GetPolicyDomain(it->first, &domain)) { |
| 224 StringSet& set = (*components)[domain]; | |
| 225 const Pickle pickle(it->second.data(), it->second.size()); | 236 const Pickle pickle(it->second.data(), it->second.size()); |
| 226 PickleIterator pickit(pickle); | 237 PickleIterator pickit(pickle); |
| 227 std::string id; | 238 std::string id; |
| 228 while (pickit.ReadString(&id)) | 239 while (pickit.ReadString(&id)) |
| 229 set.insert(id); | 240 keys->insert(std::make_pair(it->first, id)); |
| 230 } else { | 241 } else { |
| 231 cache_->Delete(kComponentNamespaceCache, it->first); | 242 cache_->Delete(kComponentNamespaceCache, it->first); |
| 232 } | 243 } |
| 233 } | 244 } |
| 234 return components.Pass(); | 245 return keys.Pass(); |
| 235 } | 246 } |
| 236 | 247 |
| 237 ComponentCloudPolicyService::ComponentCloudPolicyService( | 248 ComponentCloudPolicyService::ComponentCloudPolicyService( |
| 238 Delegate* delegate, | 249 Delegate* delegate, |
| 239 CloudPolicyStore* store, | 250 CloudPolicyStore* store, |
| 240 scoped_ptr<ResourceCache> cache, | 251 scoped_ptr<ResourceCache> cache, |
| 241 scoped_refptr<base::SequencedTaskRunner> backend_task_runner, | 252 scoped_refptr<base::SequencedTaskRunner> backend_task_runner, |
| 242 scoped_refptr<base::SequencedTaskRunner> io_task_runner) | 253 scoped_refptr<base::SequencedTaskRunner> io_task_runner) |
| 243 : delegate_(delegate), | 254 : delegate_(delegate), |
| 244 backend_task_runner_(backend_task_runner), | 255 backend_task_runner_(backend_task_runner), |
| 245 io_task_runner_(io_task_runner), | 256 io_task_runner_(io_task_runner), |
| 246 client_(NULL), | 257 client_(NULL), |
| 247 store_(store), | 258 store_(store), |
| 248 is_initialized_(false), | 259 is_initialized_(false), |
| 260 has_initial_keys_(false), |
| 249 weak_ptr_factory_(this) { | 261 weak_ptr_factory_(this) { |
| 250 store_->AddObserver(this); | 262 store_->AddObserver(this); |
| 251 | 263 |
| 252 backend_.reset(new Backend(weak_ptr_factory_.GetWeakPtr(), | 264 backend_.reset(new Backend(weak_ptr_factory_.GetWeakPtr(), |
| 253 backend_task_runner_, | 265 backend_task_runner_, |
| 254 base::MessageLoopProxy::current(), | 266 base::MessageLoopProxy::current(), |
| 255 cache.Pass())); | 267 cache.Pass())); |
| 256 backend_task_runner_->PostTask( | 268 backend_task_runner_->PostTask( |
| 257 FROM_HERE, base::Bind(&Backend::Init, base::Unretained(backend_.get()))); | 269 FROM_HERE, base::Bind(&Backend::Init, base::Unretained(backend_.get()))); |
| 258 | 270 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 293 base::Passed(external_policy_data_fetcher_backend_->CreateFrontend( | 305 base::Passed(external_policy_data_fetcher_backend_->CreateFrontend( |
| 294 backend_task_runner_)))); | 306 backend_task_runner_)))); |
| 295 if (is_initialized()) | 307 if (is_initialized()) |
| 296 InitializeClient(); | 308 InitializeClient(); |
| 297 } | 309 } |
| 298 | 310 |
| 299 void ComponentCloudPolicyService::Disconnect() { | 311 void ComponentCloudPolicyService::Disconnect() { |
| 300 DCHECK(CalledOnValidThread()); | 312 DCHECK(CalledOnValidThread()); |
| 301 if (client_) { | 313 if (client_) { |
| 302 // Unregister all the current components. | 314 // Unregister all the current components. |
| 303 for (ComponentMap::iterator it = registered_components_.begin(); | 315 RemoveNamespacesToFetch(keys_); |
| 304 it != registered_components_.end(); ++it) { | |
| 305 RemoveNamespacesToFetch(it->first, it->second); | |
| 306 } | |
| 307 | 316 |
| 308 client_->RemoveObserver(this); | 317 client_->RemoveObserver(this); |
| 309 client_ = NULL; | 318 client_ = NULL; |
| 310 | 319 |
| 311 io_task_runner_->DeleteSoon( | 320 io_task_runner_->DeleteSoon( |
| 312 FROM_HERE, external_policy_data_fetcher_backend_.release()); | 321 FROM_HERE, external_policy_data_fetcher_backend_.release()); |
| 313 backend_task_runner_->PostTask( | 322 backend_task_runner_->PostTask( |
| 314 FROM_HERE, | 323 FROM_HERE, |
| 315 base::Bind(&Backend::Disconnect, base::Unretained(backend_.get()))); | 324 base::Bind(&Backend::Disconnect, base::Unretained(backend_.get()))); |
| 316 } | 325 } |
| 317 } | 326 } |
| 318 | 327 |
| 319 void ComponentCloudPolicyService::RegisterPolicyDomain( | 328 void ComponentCloudPolicyService::OnSchemasUpdated( |
| 320 scoped_refptr<const PolicyDomainDescriptor> descriptor) { | 329 const scoped_refptr<SchemaMap>& schema_map) { |
| 321 DCHECK(CalledOnValidThread()); | 330 DCHECK(CalledOnValidThread()); |
| 322 DCHECK(SupportsDomain(descriptor->domain())); | |
| 323 | 331 |
| 324 // Send the new descriptor to the backend, to purge the cache. | 332 // Send the new schemas to the backend, to purge the cache. |
| 325 backend_task_runner_->PostTask(FROM_HERE, | 333 backend_task_runner_->PostTask(FROM_HERE, |
| 326 base::Bind(&Backend::RegisterPolicyDomain, | 334 base::Bind(&Backend::OnSchemasUpdated, |
| 327 base::Unretained(backend_.get()), | 335 base::Unretained(backend_.get()), |
| 328 descriptor)); | 336 schema_map)); |
| 329 | 337 |
| 330 // Register the current list of components for |domain| at the |client_|. | 338 // Register the current list of components for supported domains at the |
| 331 StringSet current_ids; | 339 // |client_|. |
| 332 GetComponentIds(descriptor, ¤t_ids); | 340 PolicyNamespaceKeys new_keys; |
| 333 StringSet& registered_ids = registered_components_[descriptor->domain()]; | 341 const DomainMap& domains = schema_map->GetDomains(); |
| 334 if (client_ && is_initialized()) { | 342 for (DomainMap::const_iterator domain = domains.begin(); |
| 335 if (UpdateClientNamespaces( | 343 domain != domains.end(); ++domain) { |
| 336 descriptor->domain(), registered_ids, current_ids)) { | 344 std::string domain_policy_type; |
| 337 delegate_->OnComponentCloudPolicyRefreshNeeded(); | 345 if (!ComponentCloudPolicyStore::GetPolicyType(domain->first, |
| 346 &domain_policy_type)) { |
| 347 continue; |
| 348 } |
| 349 const ComponentMap& components = domain->second; |
| 350 for (ComponentMap::const_iterator comp = components.begin(); |
| 351 comp != components.end(); ++comp) { |
| 352 new_keys.insert(std::make_pair(domain_policy_type, comp->first)); |
| 338 } | 353 } |
| 339 } | 354 } |
| 340 | 355 |
| 341 registered_ids = current_ids; | 356 if (client_ && is_initialized() && UpdateClientNamespaces(keys_, new_keys)) |
| 357 delegate_->OnComponentCloudPolicyRefreshNeeded(); |
| 358 |
| 359 keys_.swap(new_keys); |
| 360 has_initial_keys_ = true; |
| 342 } | 361 } |
| 343 | 362 |
| 344 void ComponentCloudPolicyService::OnPolicyFetched(CloudPolicyClient* client) { | 363 void ComponentCloudPolicyService::OnPolicyFetched(CloudPolicyClient* client) { |
| 345 DCHECK(CalledOnValidThread()); | 364 DCHECK(CalledOnValidThread()); |
| 346 DCHECK_EQ(client_, client); | 365 DCHECK_EQ(client_, client); |
| 347 // Pass each PolicyFetchResponse whose policy type is registered to the | 366 // Pass each PolicyFetchResponse whose policy type is registered to the |
| 348 // Backend. | 367 // Backend. |
| 349 const CloudPolicyClient::ResponseMap& responses = client_->responses(); | 368 const CloudPolicyClient::ResponseMap& responses = client_->responses(); |
| 350 for (CloudPolicyClient::ResponseMap::const_iterator it = responses.begin(); | 369 for (CloudPolicyClient::ResponseMap::const_iterator it = responses.begin(); |
| 351 it != responses.end(); ++it) { | 370 it != responses.end(); ++it) { |
| 352 const PolicyNamespaceKey& key(it->first); | 371 const PolicyNamespaceKey& key(it->first); |
| 353 PolicyDomain domain; | 372 if (ContainsKey(keys_, key)) { |
| 354 if (ComponentCloudPolicyStore::GetPolicyDomain(key.first, &domain) && | |
| 355 ContainsKey(registered_components_[domain], key.second)) { | |
| 356 scoped_ptr<em::PolicyFetchResponse> response( | 373 scoped_ptr<em::PolicyFetchResponse> response( |
| 357 new em::PolicyFetchResponse(*it->second)); | 374 new em::PolicyFetchResponse(*it->second)); |
| 358 backend_task_runner_->PostTask( | 375 backend_task_runner_->PostTask( |
| 359 FROM_HERE, | 376 FROM_HERE, |
| 360 base::Bind(&Backend::UpdateExternalPolicy, | 377 base::Bind(&Backend::UpdateExternalPolicy, |
| 361 base::Unretained(backend_.get()), | 378 base::Unretained(backend_.get()), |
| 362 base::Passed(&response))); | 379 base::Passed(&response))); |
| 363 } | 380 } |
| 364 } | 381 } |
| 365 } | 382 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 402 | 419 |
| 403 // Set the credentials for the initial policy load, if available. | 420 // Set the credentials for the initial policy load, if available. |
| 404 SetCredentialsAndReloadClient(); | 421 SetCredentialsAndReloadClient(); |
| 405 | 422 |
| 406 backend_task_runner_->PostTask( | 423 backend_task_runner_->PostTask( |
| 407 FROM_HERE, | 424 FROM_HERE, |
| 408 base::Bind(&Backend::FinalizeInit, base::Unretained(backend_.get()))); | 425 base::Bind(&Backend::FinalizeInit, base::Unretained(backend_.get()))); |
| 409 } | 426 } |
| 410 | 427 |
| 411 void ComponentCloudPolicyService::OnBackendInitialized( | 428 void ComponentCloudPolicyService::OnBackendInitialized( |
| 412 scoped_ptr<ComponentMap> cached_components, | 429 scoped_ptr<PolicyNamespaceKeys> initial_keys, |
| 413 scoped_ptr<PolicyBundle> initial_policy) { | 430 scoped_ptr<PolicyBundle> initial_policy) { |
| 414 DCHECK(CalledOnValidThread()); | 431 DCHECK(CalledOnValidThread()); |
| 415 // InitializeBackend() may be called multiple times if the |store_| fires | 432 // InitializeBackend() may be called multiple times if the |store_| fires |
| 416 // events while the backend is loading. | 433 // events while the backend is loading. |
| 417 if (is_initialized()) | 434 if (is_initialized()) |
| 418 return; | 435 return; |
| 419 | 436 |
| 420 // RegisterPolicyDomain() may have been called while the backend was | 437 // OnSchemasUpdated() may have been called while the backend was initializing; |
| 421 // initializing; only update |registered_components_| from |cached_components| | 438 // in that case ignore the cached keys. |
| 422 // for domains that haven't registered yet. | 439 if (!has_initial_keys_) |
| 423 for (ComponentMap::iterator it = cached_components->begin(); | 440 keys_.swap(*initial_keys); |
| 424 it != cached_components->end(); ++it) { | |
| 425 // Lookup without inserting an empty set. | |
| 426 if (registered_components_.find(it->first) != registered_components_.end()) | |
| 427 continue; // Ignore the cached list if a more recent one was registered. | |
| 428 registered_components_[it->first].swap(it->second); | |
| 429 } | |
| 430 | 441 |
| 431 // A client may have already connected while the backend was initializing. | 442 // A client may have already connected while the backend was initializing. |
| 432 if (client_) | 443 if (client_) |
| 433 InitializeClient(); | 444 InitializeClient(); |
| 434 | 445 |
| 435 // Set the initial policy, and send the initial update callback. | 446 // Set the initial policy, and send the initial update callback. |
| 436 is_initialized_ = true; | 447 is_initialized_ = true; |
| 437 OnPolicyUpdated(initial_policy.Pass()); | 448 OnPolicyUpdated(initial_policy.Pass()); |
| 438 } | 449 } |
| 439 | 450 |
| 440 void ComponentCloudPolicyService::InitializeClient() { | 451 void ComponentCloudPolicyService::InitializeClient() { |
| 441 DCHECK(CalledOnValidThread()); | 452 DCHECK(CalledOnValidThread()); |
| 442 // Register all the current components. | 453 // Register all the current components. |
| 443 bool added = false; | 454 AddNamespacesToFetch(keys_); |
| 444 for (ComponentMap::iterator it = registered_components_.begin(); | |
| 445 it != registered_components_.end(); ++it) { | |
| 446 added |= !it->second.empty(); | |
| 447 AddNamespacesToFetch(it->first, it->second); | |
| 448 } | |
| 449 // The client may already have PolicyFetchResponses for registered components; | 455 // The client may already have PolicyFetchResponses for registered components; |
| 450 // load them now. | 456 // load them now. |
| 451 OnPolicyFetched(client_); | 457 OnPolicyFetched(client_); |
| 452 if (added && is_initialized()) | 458 if (!keys_.empty() && is_initialized()) |
| 453 delegate_->OnComponentCloudPolicyRefreshNeeded(); | 459 delegate_->OnComponentCloudPolicyRefreshNeeded(); |
| 454 } | 460 } |
| 455 | 461 |
| 456 void ComponentCloudPolicyService::OnPolicyUpdated( | 462 void ComponentCloudPolicyService::OnPolicyUpdated( |
| 457 scoped_ptr<PolicyBundle> policy) { | 463 scoped_ptr<PolicyBundle> policy) { |
| 458 DCHECK(CalledOnValidThread()); | 464 DCHECK(CalledOnValidThread()); |
| 459 policy_.Swap(policy.get()); | 465 policy_.Swap(policy.get()); |
| 460 // Don't propagate updates until the initial store Load() has been done. | 466 // Don't propagate updates until the initial store Load() has been done. |
| 461 if (is_initialized()) | 467 if (is_initialized()) |
| 462 delegate_->OnComponentCloudPolicyUpdated(); | 468 delegate_->OnComponentCloudPolicyUpdated(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 475 // If this was the initial register, or if the signing key changed, then the | 481 // If this was the initial register, or if the signing key changed, then the |
| 476 // previous OnPolicyFetched() call had its PolicyFetchResponses rejected | 482 // previous OnPolicyFetched() call had its PolicyFetchResponses rejected |
| 477 // because the credentials weren't updated yet. Reload all the responses in | 483 // because the credentials weren't updated yet. Reload all the responses in |
| 478 // the client now to handle those cases; if those responses have already been | 484 // the client now to handle those cases; if those responses have already been |
| 479 // validated then they will be ignored. | 485 // validated then they will be ignored. |
| 480 if (client_) | 486 if (client_) |
| 481 OnPolicyFetched(client_); | 487 OnPolicyFetched(client_); |
| 482 } | 488 } |
| 483 | 489 |
| 484 bool ComponentCloudPolicyService::UpdateClientNamespaces( | 490 bool ComponentCloudPolicyService::UpdateClientNamespaces( |
| 485 PolicyDomain domain, | 491 const PolicyNamespaceKeys& old_keys, |
| 486 const StringSet& old_set, | 492 const PolicyNamespaceKeys& new_keys) { |
| 487 const StringSet& new_set) { | |
| 488 DCHECK(CalledOnValidThread()); | 493 DCHECK(CalledOnValidThread()); |
| 489 StringSet added = base::STLSetDifference<StringSet>(new_set, old_set); | 494 PolicyNamespaceKeys added = |
| 490 StringSet removed = base::STLSetDifference<StringSet>(old_set, new_set); | 495 base::STLSetDifference<PolicyNamespaceKeys>(new_keys, old_keys); |
| 491 AddNamespacesToFetch(domain, added); | 496 PolicyNamespaceKeys removed = |
| 492 RemoveNamespacesToFetch(domain, removed); | 497 base::STLSetDifference<PolicyNamespaceKeys>(old_keys, new_keys); |
| 498 AddNamespacesToFetch(added); |
| 499 RemoveNamespacesToFetch(removed); |
| 493 return !added.empty(); | 500 return !added.empty(); |
| 494 } | 501 } |
| 495 | 502 |
| 496 void ComponentCloudPolicyService::AddNamespacesToFetch(PolicyDomain domain, | 503 void ComponentCloudPolicyService::AddNamespacesToFetch( |
| 497 const StringSet& set) { | 504 const PolicyNamespaceKeys& keys) { |
| 498 DCHECK(CalledOnValidThread()); | 505 DCHECK(CalledOnValidThread()); |
| 499 std::string policy_type; | 506 for (PolicyNamespaceKeys::const_iterator it = keys.begin(); |
| 500 if (ComponentCloudPolicyStore::GetPolicyType(domain, &policy_type)) { | 507 it != keys.end(); ++it) { |
| 501 for (StringSet::const_iterator it = set.begin(); it != set.end(); ++it) | 508 client_->AddNamespaceToFetch(*it); |
| 502 client_->AddNamespaceToFetch(PolicyNamespaceKey(policy_type, *it)); | |
| 503 } | 509 } |
| 504 } | 510 } |
| 505 | 511 |
| 506 void ComponentCloudPolicyService::RemoveNamespacesToFetch( | 512 void ComponentCloudPolicyService::RemoveNamespacesToFetch( |
| 507 PolicyDomain domain, | 513 const PolicyNamespaceKeys& keys) { |
| 508 const StringSet& set) { | |
| 509 DCHECK(CalledOnValidThread()); | 514 DCHECK(CalledOnValidThread()); |
| 510 std::string policy_type; | 515 for (PolicyNamespaceKeys::const_iterator it = keys.begin(); |
| 511 if (ComponentCloudPolicyStore::GetPolicyType(domain, &policy_type)) { | 516 it != keys.end(); ++it) { |
| 512 for (StringSet::const_iterator it = set.begin(); it != set.end(); ++it) | 517 client_->RemoveNamespaceToFetch(*it); |
| 513 client_->RemoveNamespaceToFetch(PolicyNamespaceKey(policy_type, *it)); | |
| 514 } | 518 } |
| 515 } | 519 } |
| 516 | 520 |
| 517 } // namespace policy | 521 } // namespace policy |
| OLD | NEW |