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 |