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