| 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 "components/policy/core/common/cloud/component_cloud_policy_service.h" | 5 #include "components/policy/core/common/cloud/component_cloud_policy_service.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 scoped_refptr<base::SequencedTaskRunner> task_runner_; | 93 scoped_refptr<base::SequencedTaskRunner> task_runner_; |
| 94 | 94 |
| 95 // The thread that the |service_| runs on. Used to post policy changes to the | 95 // The thread that the |service_| runs on. Used to post policy changes to the |
| 96 // right thread. | 96 // right thread. |
| 97 scoped_refptr<base::SequencedTaskRunner> service_task_runner_; | 97 scoped_refptr<base::SequencedTaskRunner> service_task_runner_; |
| 98 | 98 |
| 99 scoped_ptr<ResourceCache> cache_; | 99 scoped_ptr<ResourceCache> cache_; |
| 100 scoped_ptr<ExternalPolicyDataFetcher> external_policy_data_fetcher_; | 100 scoped_ptr<ExternalPolicyDataFetcher> external_policy_data_fetcher_; |
| 101 ComponentCloudPolicyStore store_; | 101 ComponentCloudPolicyStore store_; |
| 102 scoped_ptr<ComponentCloudPolicyUpdater> updater_; | 102 scoped_ptr<ComponentCloudPolicyUpdater> updater_; |
| 103 scoped_refptr<SchemaMap> schema_map_; | 103 bool initialized_; |
| 104 | 104 |
| 105 DISALLOW_COPY_AND_ASSIGN(Backend); | 105 DISALLOW_COPY_AND_ASSIGN(Backend); |
| 106 }; | 106 }; |
| 107 | 107 |
| 108 ComponentCloudPolicyService::Backend::Backend( | 108 ComponentCloudPolicyService::Backend::Backend( |
| 109 base::WeakPtr<ComponentCloudPolicyService> service, | 109 base::WeakPtr<ComponentCloudPolicyService> service, |
| 110 scoped_refptr<base::SequencedTaskRunner> task_runner, | 110 scoped_refptr<base::SequencedTaskRunner> task_runner, |
| 111 scoped_refptr<base::SequencedTaskRunner> service_task_runner, | 111 scoped_refptr<base::SequencedTaskRunner> service_task_runner, |
| 112 scoped_ptr<ResourceCache> cache, | 112 scoped_ptr<ResourceCache> cache, |
| 113 scoped_ptr<ExternalPolicyDataFetcher> external_policy_data_fetcher) | 113 scoped_ptr<ExternalPolicyDataFetcher> external_policy_data_fetcher) |
| 114 : service_(service), | 114 : service_(service), |
| 115 task_runner_(task_runner), | 115 task_runner_(task_runner), |
| 116 service_task_runner_(service_task_runner), | 116 service_task_runner_(service_task_runner), |
| 117 cache_(cache.Pass()), | 117 cache_(cache.Pass()), |
| 118 external_policy_data_fetcher_(external_policy_data_fetcher.Pass()), | 118 external_policy_data_fetcher_(external_policy_data_fetcher.Pass()), |
| 119 store_(this, cache_.get()) {} | 119 store_(this, cache_.get()), |
| 120 initialized_(false) {} |
| 120 | 121 |
| 121 ComponentCloudPolicyService::Backend::~Backend() {} | 122 ComponentCloudPolicyService::Backend::~Backend() {} |
| 122 | 123 |
| 123 void ComponentCloudPolicyService::Backend::SetCredentials( | 124 void ComponentCloudPolicyService::Backend::SetCredentials( |
| 124 const std::string& username, | 125 const std::string& username, |
| 125 const std::string& dm_token) { | 126 const std::string& dm_token) { |
| 126 if (username.empty() || dm_token.empty()) { | 127 if (username.empty() || dm_token.empty()) { |
| 127 // No sign-in credentials, so drop any cached policy. | 128 // No sign-in credentials, so drop any cached policy. |
| 128 store_.Clear(); | 129 store_.Clear(); |
| 129 } else { | 130 } else { |
| 130 store_.SetCredentials(username, dm_token); | 131 store_.SetCredentials(username, dm_token); |
| 131 } | 132 } |
| 132 } | 133 } |
| 133 | 134 |
| 134 void ComponentCloudPolicyService::Backend::Init( | 135 void ComponentCloudPolicyService::Backend::Init( |
| 135 scoped_refptr<SchemaMap> schema_map) { | 136 scoped_refptr<SchemaMap> schema_map) { |
| 136 DCHECK(!schema_map_); | 137 DCHECK(!initialized_); |
| 137 | 138 |
| 138 OnSchemasUpdated(schema_map, scoped_ptr<PolicyNamespaceList>()); | 139 OnSchemasUpdated(schema_map, scoped_ptr<PolicyNamespaceList>()); |
| 139 | 140 |
| 140 // Read the initial policy. Note that this does not trigger notifications | 141 // Read the initial policy. Note that this does not trigger notifications |
| 141 // through OnComponentCloudPolicyStoreUpdated. Note also that the cached | 142 // through OnComponentCloudPolicyStoreUpdated. Note also that the cached |
| 142 // data may contain names or values that don't match the schema for that | 143 // data may contain names or values that don't match the schema for that |
| 143 // component; the data must be cached without modifications so that its | 144 // component; the data must be cached without modifications so that its |
| 144 // integrity can be verified using the hash, but it must also be filtered | 145 // integrity can be verified using the hash, but it must also be filtered |
| 145 // right after a Load(). | 146 // right after a Load(). |
| 146 store_.Load(); | 147 store_.Load(); |
| 147 scoped_ptr<PolicyBundle> bundle(new PolicyBundle); | 148 scoped_ptr<PolicyBundle> bundle(new PolicyBundle); |
| 148 bundle->CopyFrom(store_.policy()); | 149 bundle->CopyFrom(store_.policy()); |
| 149 schema_map_->FilterBundle(bundle.get()); | |
| 150 | 150 |
| 151 // Start downloading any pending data. | 151 // Start downloading any pending data. |
| 152 updater_.reset(new ComponentCloudPolicyUpdater( | 152 updater_.reset(new ComponentCloudPolicyUpdater( |
| 153 task_runner_, external_policy_data_fetcher_.Pass(), &store_)); | 153 task_runner_, external_policy_data_fetcher_.Pass(), &store_)); |
| 154 | 154 |
| 155 service_task_runner_->PostTask( | 155 service_task_runner_->PostTask( |
| 156 FROM_HERE, | 156 FROM_HERE, |
| 157 base::Bind(&ComponentCloudPolicyService::OnBackendInitialized, | 157 base::Bind(&ComponentCloudPolicyService::OnBackendInitialized, |
| 158 service_, | 158 service_, |
| 159 base::Passed(&bundle))); | 159 base::Passed(&bundle))); |
| 160 |
| 161 initialized_ = true; |
| 160 } | 162 } |
| 161 | 163 |
| 162 void ComponentCloudPolicyService::Backend::UpdateExternalPolicy( | 164 void ComponentCloudPolicyService::Backend::UpdateExternalPolicy( |
| 163 scoped_ptr<em::PolicyFetchResponse> response) { | 165 scoped_ptr<em::PolicyFetchResponse> response) { |
| 164 updater_->UpdateExternalPolicy(response.Pass()); | 166 updater_->UpdateExternalPolicy(response.Pass()); |
| 165 } | 167 } |
| 166 | 168 |
| 167 void ComponentCloudPolicyService::Backend:: | 169 void ComponentCloudPolicyService::Backend:: |
| 168 OnComponentCloudPolicyStoreUpdated() { | 170 OnComponentCloudPolicyStoreUpdated() { |
| 169 if (!schema_map_) { | 171 if (!initialized_) { |
| 170 // Ignore notifications triggered by the initial Purge or Clear. | 172 // Ignore notifications triggered by the initial Purge or Clear. |
| 171 return; | 173 return; |
| 172 } | 174 } |
| 173 | 175 |
| 174 scoped_ptr<PolicyBundle> bundle(new PolicyBundle); | 176 scoped_ptr<PolicyBundle> bundle(new PolicyBundle); |
| 175 bundle->CopyFrom(store_.policy()); | 177 bundle->CopyFrom(store_.policy()); |
| 176 schema_map_->FilterBundle(bundle.get()); | |
| 177 service_task_runner_->PostTask( | 178 service_task_runner_->PostTask( |
| 178 FROM_HERE, | 179 FROM_HERE, |
| 179 base::Bind(&ComponentCloudPolicyService::OnPolicyUpdated, | 180 base::Bind(&ComponentCloudPolicyService::OnPolicyUpdated, |
| 180 service_, | 181 service_, |
| 181 base::Passed(&bundle))); | 182 base::Passed(&bundle))); |
| 182 } | 183 } |
| 183 | 184 |
| 184 void ComponentCloudPolicyService::Backend::OnSchemasUpdated( | 185 void ComponentCloudPolicyService::Backend::OnSchemasUpdated( |
| 185 scoped_refptr<SchemaMap> schema_map, | 186 scoped_refptr<SchemaMap> schema_map, |
| 186 scoped_ptr<PolicyNamespaceList> removed) { | 187 scoped_ptr<PolicyNamespaceList> removed) { |
| 187 // Purge any components that have been removed. | 188 // Purge any components that have been removed. |
| 188 const DomainMap& domains = schema_map->GetDomains(); | 189 const DomainMap& domains = schema_map->GetDomains(); |
| 189 for (DomainMap::const_iterator domain = domains.begin(); | 190 for (DomainMap::const_iterator domain = domains.begin(); |
| 190 domain != domains.end(); ++domain) { | 191 domain != domains.end(); ++domain) { |
| 191 store_.Purge(domain->first, | 192 store_.Purge(domain->first, |
| 192 base::Bind(&NotInSchemaMap, schema_map, domain->first)); | 193 base::Bind(&NotInSchemaMap, schema_map, domain->first)); |
| 193 } | 194 } |
| 194 | 195 |
| 195 // Set |schema_map_| after purging so that the notifications from the store | |
| 196 // are ignored on the first OnSchemasUpdated() call from Init(). | |
| 197 schema_map_ = schema_map; | |
| 198 | |
| 199 if (removed) { | 196 if (removed) { |
| 200 for (size_t i = 0; i < removed->size(); ++i) | 197 for (size_t i = 0; i < removed->size(); ++i) |
| 201 updater_->CancelUpdate((*removed)[i]); | 198 updater_->CancelUpdate((*removed)[i]); |
| 202 } | 199 } |
| 203 } | 200 } |
| 204 | 201 |
| 205 ComponentCloudPolicyService::ComponentCloudPolicyService( | 202 ComponentCloudPolicyService::ComponentCloudPolicyService( |
| 206 Delegate* delegate, | 203 Delegate* delegate, |
| 207 SchemaRegistry* schema_registry, | 204 SchemaRegistry* schema_registry, |
| 208 CloudPolicyCore* core, | 205 CloudPolicyCore* core, |
| 209 scoped_ptr<ResourceCache> cache, | 206 scoped_ptr<ResourceCache> cache, |
| 210 scoped_refptr<net::URLRequestContextGetter> request_context, | 207 scoped_refptr<net::URLRequestContextGetter> request_context, |
| 211 scoped_refptr<base::SequencedTaskRunner> backend_task_runner, | 208 scoped_refptr<base::SequencedTaskRunner> backend_task_runner, |
| 212 scoped_refptr<base::SequencedTaskRunner> io_task_runner) | 209 scoped_refptr<base::SequencedTaskRunner> io_task_runner) |
| 213 : delegate_(delegate), | 210 : delegate_(delegate), |
| 214 schema_registry_(schema_registry), | 211 schema_registry_(schema_registry), |
| 215 core_(core), | 212 core_(core), |
| 216 request_context_(request_context), | 213 request_context_(request_context), |
| 217 backend_task_runner_(backend_task_runner), | 214 backend_task_runner_(backend_task_runner), |
| 218 io_task_runner_(io_task_runner), | 215 io_task_runner_(io_task_runner), |
| 219 current_schema_map_(new SchemaMap), | 216 current_schema_map_(new SchemaMap), |
| 217 unfiltered_policy_(new PolicyBundle), |
| 220 started_loading_initial_policy_(false), | 218 started_loading_initial_policy_(false), |
| 221 loaded_initial_policy_(false), | 219 loaded_initial_policy_(false), |
| 222 is_registered_for_cloud_policy_(false), | 220 is_registered_for_cloud_policy_(false), |
| 223 weak_ptr_factory_(this) { | 221 weak_ptr_factory_(this) { |
| 224 external_policy_data_fetcher_backend_.reset( | 222 external_policy_data_fetcher_backend_.reset( |
| 225 new ExternalPolicyDataFetcherBackend(io_task_runner_, request_context)); | 223 new ExternalPolicyDataFetcherBackend(io_task_runner_, request_context)); |
| 226 | 224 |
| 227 backend_.reset( | 225 backend_.reset( |
| 228 new Backend(weak_ptr_factory_.GetWeakPtr(), | 226 new Backend(weak_ptr_factory_.GetWeakPtr(), |
| 229 backend_task_runner_, | 227 backend_task_runner_, |
| 230 base::MessageLoopProxy::current(), | 228 base::MessageLoopProxy::current(), |
| 231 cache.Pass(), | 229 cache.Pass(), |
| 232 external_policy_data_fetcher_backend_->CreateFrontend( | 230 external_policy_data_fetcher_backend_->CreateFrontend( |
| 233 backend_task_runner_))); | 231 backend_task_runner_))); |
| 234 | 232 |
| 235 schema_registry_->AddObserver(this); | 233 schema_registry_->AddObserver(this); |
| 236 core_->store()->AddObserver(this); | 234 core_->store()->AddObserver(this); |
| 237 | 235 |
| 238 // Wait for the store and the schema registry to become ready before | 236 // Wait for the store and the schema registry to become ready before |
| 239 // initializing the backend, so that it can get the initial list of | 237 // initializing the backend, so that it can get the initial list of |
| 240 // components and the cached credentials (if any) to validate the cached | 238 // components and the cached credentials (if any) to validate the cached |
| 241 // policies. | 239 // policies. |
| 242 if (core_->store()->is_initialized()) | 240 if (core_->store()->is_initialized()) |
| 243 OnStoreLoaded(core_->store()); | 241 OnStoreLoaded(core_->store()); |
| 242 |
| 243 // Start observing the core and tracking the state of the client. |
| 244 core_->AddObserver(this); |
| 245 if (core_->client()) |
| 246 OnCoreConnected(core_); |
| 244 } | 247 } |
| 245 | 248 |
| 246 ComponentCloudPolicyService::~ComponentCloudPolicyService() { | 249 ComponentCloudPolicyService::~ComponentCloudPolicyService() { |
| 247 DCHECK(CalledOnValidThread()); | 250 DCHECK(CalledOnValidThread()); |
| 248 | 251 |
| 249 schema_registry_->RemoveObserver(this); | 252 schema_registry_->RemoveObserver(this); |
| 250 core_->store()->RemoveObserver(this); | 253 core_->store()->RemoveObserver(this); |
| 251 core_->RemoveObserver(this); | 254 core_->RemoveObserver(this); |
| 252 if (core_->client()) | 255 if (core_->client()) |
| 253 OnCoreDisconnecting(core_); | 256 OnCoreDisconnecting(core_); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 280 bool has_new_schemas) { | 283 bool has_new_schemas) { |
| 281 DCHECK(CalledOnValidThread()); | 284 DCHECK(CalledOnValidThread()); |
| 282 | 285 |
| 283 // Ignore schema updates until the backend is initialized. | 286 // Ignore schema updates until the backend is initialized. |
| 284 // OnBackendInitialized() will send the current schema to the backend again, | 287 // OnBackendInitialized() will send the current schema to the backend again, |
| 285 // in case it was updated before the backend initialized. | 288 // in case it was updated before the backend initialized. |
| 286 if (!loaded_initial_policy_) | 289 if (!loaded_initial_policy_) |
| 287 return; | 290 return; |
| 288 | 291 |
| 289 ReloadSchema(); | 292 ReloadSchema(); |
| 293 |
| 294 // Filter the |unfiltered_policy_| again, now that |current_schema_map_| has |
| 295 // been updated. We must make sure we never serve invalid policy; we must |
| 296 // also filter again if an invalid Schema has now been loaded. |
| 297 OnPolicyUpdated(unfiltered_policy_.Pass()); |
| 290 } | 298 } |
| 291 | 299 |
| 292 void ComponentCloudPolicyService::OnCoreConnected(CloudPolicyCore* core) { | 300 void ComponentCloudPolicyService::OnCoreConnected(CloudPolicyCore* core) { |
| 293 DCHECK(CalledOnValidThread()); | 301 DCHECK(CalledOnValidThread()); |
| 294 DCHECK_EQ(core_, core); | 302 DCHECK_EQ(core_, core); |
| 295 | 303 |
| 296 core_->client()->AddObserver(this); | 304 core_->client()->AddObserver(this); |
| 297 | 305 |
| 298 // Register the supported policy domains at the client. | 306 // Register the supported policy domains at the client. |
| 299 core_->client()->AddNamespaceToFetch( | 307 core_->client()->AddNamespaceToFetch( |
| 300 PolicyNamespaceKey(dm_protocol::kChromeExtensionPolicyType, "")); | 308 PolicyNamespaceKey(dm_protocol::kChromeExtensionPolicyType, "")); |
| 301 | 309 |
| 302 // Immediately load any PolicyFetchResponses that the client may already | 310 // Immediately load any PolicyFetchResponses that the client may already |
| 303 // have. | 311 // have if the backend is ready. |
| 304 OnPolicyFetched(core_->client()); | 312 if (loaded_initial_policy_) |
| 313 OnPolicyFetched(core_->client()); |
| 305 } | 314 } |
| 306 | 315 |
| 307 void ComponentCloudPolicyService::OnCoreDisconnecting(CloudPolicyCore* core) { | 316 void ComponentCloudPolicyService::OnCoreDisconnecting(CloudPolicyCore* core) { |
| 308 DCHECK(CalledOnValidThread()); | 317 DCHECK(CalledOnValidThread()); |
| 309 DCHECK_EQ(core_, core); | 318 DCHECK_EQ(core_, core); |
| 310 | 319 |
| 311 core_->client()->RemoveObserver(this); | 320 core_->client()->RemoveObserver(this); |
| 312 | 321 |
| 313 // Remove all the namespaces from the client. | 322 // Remove all the namespaces from the client. |
| 314 core_->client()->RemoveNamespaceToFetch( | 323 core_->client()->RemoveNamespaceToFetch( |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 414 DCHECK(CalledOnValidThread()); | 423 DCHECK(CalledOnValidThread()); |
| 415 // Ignored. | 424 // Ignored. |
| 416 } | 425 } |
| 417 | 426 |
| 418 void ComponentCloudPolicyService::InitializeIfReady() { | 427 void ComponentCloudPolicyService::InitializeIfReady() { |
| 419 DCHECK(CalledOnValidThread()); | 428 DCHECK(CalledOnValidThread()); |
| 420 if (started_loading_initial_policy_ || !schema_registry_->IsReady() || | 429 if (started_loading_initial_policy_ || !schema_registry_->IsReady() || |
| 421 !core_->store()->is_initialized()) { | 430 !core_->store()->is_initialized()) { |
| 422 return; | 431 return; |
| 423 } | 432 } |
| 433 |
| 424 // The initial list of components is ready. Initialize the backend now, which | 434 // The initial list of components is ready. Initialize the backend now, which |
| 425 // will call back to OnBackendInitialized. | 435 // will call back to OnBackendInitialized. |
| 426 backend_task_runner_->PostTask(FROM_HERE, | 436 backend_task_runner_->PostTask(FROM_HERE, |
| 427 base::Bind(&Backend::Init, | 437 base::Bind(&Backend::Init, |
| 428 base::Unretained(backend_.get()), | 438 base::Unretained(backend_.get()), |
| 429 schema_registry_->schema_map())); | 439 schema_registry_->schema_map())); |
| 430 started_loading_initial_policy_ = true; | 440 started_loading_initial_policy_ = true; |
| 431 } | 441 } |
| 432 | 442 |
| 433 void ComponentCloudPolicyService::OnBackendInitialized( | 443 void ComponentCloudPolicyService::OnBackendInitialized( |
| 434 scoped_ptr<PolicyBundle> initial_policy) { | 444 scoped_ptr<PolicyBundle> initial_policy) { |
| 435 DCHECK(CalledOnValidThread()); | 445 DCHECK(CalledOnValidThread()); |
| 436 DCHECK(!loaded_initial_policy_); | 446 DCHECK(!loaded_initial_policy_); |
| 437 | 447 |
| 438 loaded_initial_policy_ = true; | 448 loaded_initial_policy_ = true; |
| 439 | 449 |
| 440 // We're now ready to serve the initial policy; notify the policy observers. | |
| 441 OnPolicyUpdated(initial_policy.Pass()); | |
| 442 | |
| 443 // Send the current schema to the backend, in case it has changed while the | 450 // Send the current schema to the backend, in case it has changed while the |
| 444 // backend was initializing. | 451 // backend was initializing. |
| 445 ReloadSchema(); | 452 ReloadSchema(); |
| 446 | 453 |
| 447 // Start observing the core and tracking the state of the client. | 454 // We're now ready to serve the initial policy; notify the policy observers. |
| 448 core_->AddObserver(this); | 455 OnPolicyUpdated(initial_policy.Pass()); |
| 449 | |
| 450 if (core_->client()) | |
| 451 OnCoreConnected(core_); | |
| 452 } | 456 } |
| 453 | 457 |
| 454 void ComponentCloudPolicyService::ReloadSchema() { | 458 void ComponentCloudPolicyService::ReloadSchema() { |
| 455 DCHECK(CalledOnValidThread()); | 459 DCHECK(CalledOnValidThread()); |
| 456 | 460 |
| 457 scoped_ptr<PolicyNamespaceList> removed(new PolicyNamespaceList); | 461 scoped_ptr<PolicyNamespaceList> removed(new PolicyNamespaceList); |
| 458 PolicyNamespaceList added; | 462 PolicyNamespaceList added; |
| 459 const scoped_refptr<SchemaMap>& new_schema_map = | 463 const scoped_refptr<SchemaMap>& new_schema_map = |
| 460 schema_registry_->schema_map(); | 464 schema_registry_->schema_map(); |
| 461 new_schema_map->GetChanges(current_schema_map_, removed.get(), &added); | 465 new_schema_map->GetChanges(current_schema_map_, removed.get(), &added); |
| 462 | 466 |
| 463 current_schema_map_ = new_schema_map; | 467 current_schema_map_ = new_schema_map; |
| 464 | 468 |
| 465 // Schedule a policy refresh if a new managed component was added. | |
| 466 if (core_->client() && !added.empty()) | |
| 467 core_->RefreshSoon(); | |
| 468 | |
| 469 // Send the updated SchemaMap and a list of removed components to the | 469 // Send the updated SchemaMap and a list of removed components to the |
| 470 // backend. | 470 // backend. |
| 471 backend_task_runner_->PostTask(FROM_HERE, | 471 backend_task_runner_->PostTask(FROM_HERE, |
| 472 base::Bind(&Backend::OnSchemasUpdated, | 472 base::Bind(&Backend::OnSchemasUpdated, |
| 473 base::Unretained(backend_.get()), | 473 base::Unretained(backend_.get()), |
| 474 current_schema_map_, | 474 current_schema_map_, |
| 475 base::Passed(&removed))); | 475 base::Passed(&removed))); |
| 476 |
| 477 // Have another look at the client if the core is already connected. |
| 478 // The client may have already fetched policy for some component and it was |
| 479 // previously ignored because the component wasn't listed in the schema map. |
| 480 // There's no point in fetching policy from the server again; the server |
| 481 // always pushes all the components it knows about. |
| 482 if (core_->client()) |
| 483 OnPolicyFetched(core_->client()); |
| 476 } | 484 } |
| 477 | 485 |
| 478 void ComponentCloudPolicyService::OnPolicyUpdated( | 486 void ComponentCloudPolicyService::OnPolicyUpdated( |
| 479 scoped_ptr<PolicyBundle> policy) { | 487 scoped_ptr<PolicyBundle> policy) { |
| 480 DCHECK(CalledOnValidThread()); | 488 DCHECK(CalledOnValidThread()); |
| 481 policy_.Swap(policy.get()); | 489 |
| 490 // Store the current unfiltered policies. |
| 491 unfiltered_policy_ = policy.Pass(); |
| 492 |
| 493 // Make a copy in |policy_| and filter it; this is what's passed to the |
| 494 // outside world. |
| 495 policy_.CopyFrom(*unfiltered_policy_); |
| 496 current_schema_map_->FilterBundle(&policy_); |
| 497 |
| 482 delegate_->OnComponentCloudPolicyUpdated(); | 498 delegate_->OnComponentCloudPolicyUpdated(); |
| 483 } | 499 } |
| 484 | 500 |
| 485 } // namespace policy | 501 } // namespace policy |
| OLD | NEW |