cloud_policy_manager.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "components/policy/core/common/cloud/cloud_policy_manager.h" 6 7#include "base/bind.h" 8#include "base/bind_helpers.h" 9#include "base/command_line.h" 10#include "base/files/file_path.h" 11#include "base/logging.h" 12#include "base/prefs/pref_service.h" 13#include "components/policy/core/common/cloud/cloud_policy_service.h" 14#include "components/policy/core/common/policy_bundle.h" 15#include "components/policy/core/common/policy_map.h" 16#include "components/policy/core/common/policy_switches.h" 17#include "net/url_request/url_request_context_getter.h" 18 19#if !defined(OS_ANDROID) && !defined(OS_IOS) 20#include "components/policy/core/common/cloud/resource_cache.h" 21#endif 22 23namespace policy { 24 25CloudPolicyManager::CloudPolicyManager( 26 const PolicyNamespaceKey& policy_ns_key, 27 CloudPolicyStore* cloud_policy_store, 28 const scoped_refptr<base::SequencedTaskRunner>& task_runner, 29 const scoped_refptr<base::SequencedTaskRunner>& file_task_runner, 30 const scoped_refptr<base::SequencedTaskRunner>& io_task_runner) 31 : core_(policy_ns_key, cloud_policy_store, task_runner), 32 waiting_for_policy_refresh_(false), 33 file_task_runner_(file_task_runner), 34 io_task_runner_(io_task_runner) { 35 store()->AddObserver(this); 36 37 // If the underlying store is already initialized, publish the loaded 38 // policy. Otherwise, request a load now. 39 if (store()->is_initialized()) 40 CheckAndPublishPolicy(); 41 else 42 store()->Load(); 43} 44 45CloudPolicyManager::~CloudPolicyManager() {} 46 47void CloudPolicyManager::Shutdown() { 48 component_policy_service_.reset(); 49 core_.Disconnect(); 50 store()->RemoveObserver(this); 51 ConfigurationPolicyProvider::Shutdown(); 52} 53 54bool CloudPolicyManager::IsInitializationComplete(PolicyDomain domain) const { 55 if (domain == POLICY_DOMAIN_CHROME) 56 return store()->is_initialized(); 57 if (ComponentCloudPolicyService::SupportsDomain(domain) && 58 component_policy_service_) { 59 return component_policy_service_->is_initialized(); 60 } 61 return true; 62} 63 64void CloudPolicyManager::RefreshPolicies() { 65 if (service()) { 66 waiting_for_policy_refresh_ = true; 67 service()->RefreshPolicy( 68 base::Bind(&CloudPolicyManager::OnRefreshComplete, 69 base::Unretained(this))); 70 } else { 71 OnRefreshComplete(false); 72 } 73} 74 75void CloudPolicyManager::OnStoreLoaded(CloudPolicyStore* cloud_policy_store) { 76 DCHECK_EQ(store(), cloud_policy_store); 77 CheckAndPublishPolicy(); 78} 79 80void CloudPolicyManager::OnStoreError(CloudPolicyStore* cloud_policy_store) { 81 DCHECK_EQ(store(), cloud_policy_store); 82 // Publish policy (even though it hasn't changed) in order to signal load 83 // complete on the ConfigurationPolicyProvider interface. Technically, this 84 // is only required on the first load, but doesn't hurt in any case. 85 CheckAndPublishPolicy(); 86} 87 88void CloudPolicyManager::OnComponentCloudPolicyUpdated() { 89 CheckAndPublishPolicy(); 90} 91 92void CloudPolicyManager::CheckAndPublishPolicy() { 93 if (IsInitializationComplete(POLICY_DOMAIN_CHROME) && 94 !waiting_for_policy_refresh_) { 95 scoped_ptr<PolicyBundle> bundle(new PolicyBundle); 96 bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())) 97 .CopyFrom(store()->policy_map()); 98 if (component_policy_service_) 99 bundle->MergeFrom(component_policy_service_->policy()); 100 UpdatePolicy(bundle.Pass()); 101 } 102} 103 104void CloudPolicyManager::CreateComponentCloudPolicyService( 105 const base::FilePath& policy_cache_path, 106 const scoped_refptr<net::URLRequestContextGetter>& request_context) { 107#if !defined(OS_ANDROID) && !defined(OS_IOS) 108 // Init() must have been called. 109 DCHECK(schema_registry()); 110 // Called at most once. 111 DCHECK(!component_policy_service_); 112 113 if (!CommandLine::ForCurrentProcess()->HasSwitch( 114 switches::kEnableComponentCloudPolicy) || 115 policy_cache_path.empty()) { 116 return; 117 } 118 119 // TODO(joaodasilva): Move the |file_task_runner_| to the blocking pool. 120 // Currently it's not possible because the ComponentCloudPolicyStore is 121 // NonThreadSafe and doesn't support getting calls from different threads. 122 scoped_ptr<ResourceCache> resource_cache( 123 new ResourceCache(policy_cache_path, file_task_runner_)); 124 component_policy_service_.reset(new ComponentCloudPolicyService( 125 this, 126 schema_registry(), 127 core(), 128 resource_cache.Pass(), 129 request_context, 130 file_task_runner_, 131 io_task_runner_)); 132#endif // !defined(OS_ANDROID) && !defined(OS_IOS) 133} 134 135void CloudPolicyManager::ClearAndDestroyComponentCloudPolicyService() { 136#if !defined(OS_ANDROID) && !defined(OS_IOS) 137 if (component_policy_service_) { 138 component_policy_service_->ClearCache(); 139 component_policy_service_.reset(); 140 } 141#endif // !defined(OS_ANDROID) && !defined(OS_IOS) 142} 143 144void CloudPolicyManager::OnRefreshComplete(bool success) { 145 waiting_for_policy_refresh_ = false; 146 CheckAndPublishPolicy(); 147} 148 149} // namespace policy 150