Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(280)

Side by Side Diff: chrome/browser/policy/cloud/component_cloud_policy_service.cc

Issue 56623005: Policy providers all get a SchemaRegistry to work with. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@chrome-policy-schema-9-purge-with-callback
Patch Set: Fixed mac tests Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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, &current_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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698