OLD | NEW |
| (Empty) |
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 "chrome/browser/policy/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 "chrome/browser/policy/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 "chrome/browser/policy/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 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 | |
104 void 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 | |
135 void 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 | |
144 void CloudPolicyManager::OnRefreshComplete(bool success) { | |
145 waiting_for_policy_refresh_ = false; | |
146 CheckAndPublishPolicy(); | |
147 } | |
148 | |
149 } // namespace policy | |
OLD | NEW |