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 23 namespace policy { 24 25 CloudPolicyManager::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 45 CloudPolicyManager::~CloudPolicyManager() {} 46 47 void CloudPolicyManager::Shutdown() { 48 component_policy_service_.reset(); 49 core_.Disconnect(); 50 store()->RemoveObserver(this); 51 ConfigurationPolicyProvider::Shutdown(); 52 } 53 54 bool 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 64 void 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 75 void CloudPolicyManager::OnStoreLoaded(CloudPolicyStore* cloud_policy_store) { 76 DCHECK_EQ(store(), cloud_policy_store); 77 CheckAndPublishPolicy(); 78 } 79 80 void 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 88 void CloudPolicyManager::OnComponentCloudPolicyUpdated() { 89 CheckAndPublishPolicy(); 90 } 91 92 void CloudPolicyManager::CheckAndPublishPolicy() { 93 if (IsInitializationComplete(POLICY_DOMAIN_CHROME) && 94 !waiting_for_policy_refresh_) { 95 scoped_ptr<PolicyBundle> bundle(new PolicyBundle); 96 GetChromePolicy( 97 &bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))); 98 if (component_policy_service_) 99 bundle->MergeFrom(component_policy_service_->policy()); 100 UpdatePolicy(bundle.Pass()); 101 } 102 } 103 104 void CloudPolicyManager::GetChromePolicy(PolicyMap* policy_map) { 105 policy_map->CopyFrom(store()->policy_map()); 106 } 107 108 void CloudPolicyManager::CreateComponentCloudPolicyService( 109 const base::FilePath& policy_cache_path, 110 const scoped_refptr<net::URLRequestContextGetter>& request_context) { 111 #if !defined(OS_ANDROID) && !defined(OS_IOS) 112 // Init() must have been called. 113 DCHECK(schema_registry()); 114 // Called at most once. 115 DCHECK(!component_policy_service_); 116 117 if (CommandLine::ForCurrentProcess()->HasSwitch( 118 switches::kDisableComponentCloudPolicy) || 119 policy_cache_path.empty()) { 120 return; 121 } 122 123 // TODO(joaodasilva): Move the |file_task_runner_| to the blocking pool. 124 // Currently it's not possible because the ComponentCloudPolicyStore is 125 // NonThreadSafe and doesn't support getting calls from different threads. 126 scoped_ptr<ResourceCache> resource_cache( 127 new ResourceCache(policy_cache_path, file_task_runner_)); 128 component_policy_service_.reset(new ComponentCloudPolicyService( 129 this, 130 schema_registry(), 131 core(), 132 resource_cache.Pass(), 133 request_context, 134 file_task_runner_, 135 io_task_runner_)); 136 #endif // !defined(OS_ANDROID) && !defined(OS_IOS) 137 } 138 139 void CloudPolicyManager::ClearAndDestroyComponentCloudPolicyService() { 140 #if !defined(OS_ANDROID) && !defined(OS_IOS) 141 if (component_policy_service_) { 142 component_policy_service_->ClearCache(); 143 component_policy_service_.reset(); 144 } 145 #endif // !defined(OS_ANDROID) && !defined(OS_IOS) 146 } 147 148 void CloudPolicyManager::OnRefreshComplete(bool success) { 149 waiting_for_policy_refresh_ = false; 150 CheckAndPublishPolicy(); 151 } 152 153 } // namespace policy 154