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.
5 #include "chrome/browser/policy/cloud/user_cloud_policy_manager_factory.h"
7 #include "base/files/file_path.h"
8 #include "base/logging.h"
9 #include "base/message_loop/message_loop_proxy.h"
10 #include "base/sequenced_task_runner.h"
11 #include "chrome/browser/policy/schema_registry_service.h"
12 #include "chrome/browser/policy/schema_registry_service_factory.h"
13 #include "components/browser_context_keyed_service/browser_context_dependency_manager.h"
14 #include "components/browser_context_keyed_service/browser_context_keyed_service.h"
15 #include "components/policy/core/common/cloud/cloud_external_data_manager.h"
16 #include "components/policy/core/common/cloud/user_cloud_policy_manager.h"
17 #include "components/policy/core/common/cloud/user_cloud_policy_store.h"
18 #include "content/public/browser/browser_context.h"
24 // Directory inside the profile directory where policy-related resources are
26 const base::FilePath::CharType kPolicy
[] = FILE_PATH_LITERAL("Policy");
28 // Directory under kPolicy, in the user's profile dir, where policy for
29 // components is cached.
30 const base::FilePath::CharType kComponentsDir
[] =
31 FILE_PATH_LITERAL("Components");
35 // A BrowserContextKeyedService that wraps a UserCloudPolicyManager.
36 class UserCloudPolicyManagerFactory::ManagerWrapper
37 : public BrowserContextKeyedService
{
39 explicit ManagerWrapper(UserCloudPolicyManager
* manager
)
43 virtual ~ManagerWrapper() {}
45 virtual void Shutdown() OVERRIDE
{
49 UserCloudPolicyManager
* manager() { return manager_
; }
52 UserCloudPolicyManager
* manager_
;
54 DISALLOW_COPY_AND_ASSIGN(ManagerWrapper
);
58 UserCloudPolicyManagerFactory
* UserCloudPolicyManagerFactory::GetInstance() {
59 return Singleton
<UserCloudPolicyManagerFactory
>::get();
63 UserCloudPolicyManager
* UserCloudPolicyManagerFactory::GetForBrowserContext(
64 content::BrowserContext
* context
) {
65 return GetInstance()->GetManagerForBrowserContext(context
);
69 scoped_ptr
<UserCloudPolicyManager
>
70 UserCloudPolicyManagerFactory::CreateForOriginalBrowserContext(
71 content::BrowserContext
* context
,
72 bool force_immediate_load
,
73 const scoped_refptr
<base::SequencedTaskRunner
>& background_task_runner
,
74 const scoped_refptr
<base::SequencedTaskRunner
>& file_task_runner
,
75 const scoped_refptr
<base::SequencedTaskRunner
>& io_task_runner
) {
76 UserCloudPolicyManagerFactory
* factory
= GetInstance();
77 // If there's a testing factory set, don't bother creating a new one.
78 if (factory
->testing_factory_
!= NULL
)
79 return scoped_ptr
<UserCloudPolicyManager
>();
80 return factory
->CreateManagerForOriginalBrowserContext(
83 background_task_runner
,
89 UserCloudPolicyManager
*
90 UserCloudPolicyManagerFactory::RegisterForOffTheRecordBrowserContext(
91 content::BrowserContext
* original_context
,
92 content::BrowserContext
* off_the_record_context
) {
93 return GetInstance()->RegisterManagerForOffTheRecordBrowserContext(
94 original_context
, off_the_record_context
);
97 void UserCloudPolicyManagerFactory::RegisterTestingFactory(
98 TestingFactoryFunction factory
) {
99 // Can't set a testing factory when a testing factory has already been
100 // created, or after UCPMs have already been built.
101 DCHECK(!testing_factory_
);
103 DCHECK(manager_wrappers_
.empty());
104 testing_factory_
= factory
;
107 void UserCloudPolicyManagerFactory::ClearTestingFactory() {
108 testing_factory_
= NULL
;
111 UserCloudPolicyManagerFactory::UserCloudPolicyManagerFactory()
112 : BrowserContextKeyedBaseFactory(
113 "UserCloudPolicyManager",
114 BrowserContextDependencyManager::GetInstance()),
115 testing_factory_(NULL
) {
116 DependsOn(SchemaRegistryServiceFactory::GetInstance());
119 UserCloudPolicyManagerFactory::~UserCloudPolicyManagerFactory() {
120 DCHECK(manager_wrappers_
.empty());
123 UserCloudPolicyManager
*
124 UserCloudPolicyManagerFactory::GetManagerForBrowserContext(
125 content::BrowserContext
* context
) {
126 // In case |context| is an incognito Profile/Context, |manager_wrappers_|
127 // will have a matching entry pointing to the manager of the original context.
128 ManagerWrapperMap::const_iterator it
= manager_wrappers_
.find(context
);
129 return it
!= manager_wrappers_
.end() ? it
->second
->manager() : NULL
;
132 scoped_ptr
<UserCloudPolicyManager
>
133 UserCloudPolicyManagerFactory::CreateManagerForOriginalBrowserContext(
134 content::BrowserContext
* context
,
135 bool force_immediate_load
,
136 const scoped_refptr
<base::SequencedTaskRunner
>& background_task_runner
,
137 const scoped_refptr
<base::SequencedTaskRunner
>& file_task_runner
,
138 const scoped_refptr
<base::SequencedTaskRunner
>& io_task_runner
) {
139 DCHECK(!context
->IsOffTheRecord());
141 // This should never be called if we're using a testing factory.
142 // Instead, instances are instantiated via CreateServiceNow().
143 DCHECK(!testing_factory_
);
145 scoped_ptr
<UserCloudPolicyStore
> store(
146 UserCloudPolicyStore::Create(context
->GetPath(), background_task_runner
));
147 if (force_immediate_load
)
148 store
->LoadImmediately();
150 const base::FilePath component_policy_cache_dir
=
151 context
->GetPath().Append(kPolicy
).Append(kComponentsDir
);
153 scoped_ptr
<UserCloudPolicyManager
> manager
;
154 manager
.reset(new UserCloudPolicyManager(
156 component_policy_cache_dir
,
157 scoped_ptr
<CloudExternalDataManager
>(),
158 base::MessageLoopProxy::current(),
161 manager
->Init(SchemaRegistryServiceFactory::GetForContext(context
));
162 manager_wrappers_
[context
] = new ManagerWrapper(manager
.get());
163 return manager
.Pass();
166 UserCloudPolicyManager
*
167 UserCloudPolicyManagerFactory::RegisterManagerForOffTheRecordBrowserContext(
168 content::BrowserContext
* original_context
,
169 content::BrowserContext
* off_the_record_context
) {
170 // Register the UserCloudPolicyManager of the original context for the
171 // respective incognito context. See also GetManagerForBrowserContext.
172 UserCloudPolicyManager
* manager
=
173 GetManagerForBrowserContext(original_context
);
174 manager_wrappers_
[off_the_record_context
] = new ManagerWrapper(manager
);
178 void UserCloudPolicyManagerFactory::BrowserContextShutdown(
179 content::BrowserContext
* context
) {
180 if (context
->IsOffTheRecord())
182 ManagerWrapperMap::iterator it
= manager_wrappers_
.find(context
);
183 // E.g. for a TestingProfile there might not be a manager created.
184 if (it
!= manager_wrappers_
.end())
185 it
->second
->Shutdown();
188 void UserCloudPolicyManagerFactory::BrowserContextDestroyed(
189 content::BrowserContext
* context
) {
190 ManagerWrapperMap::iterator it
= manager_wrappers_
.find(context
);
191 if (it
!= manager_wrappers_
.end()) {
192 // The manager is not owned by the factory, so it's not deleted here.
194 manager_wrappers_
.erase(it
);
198 void UserCloudPolicyManagerFactory::SetEmptyTestingFactory(
199 content::BrowserContext
* context
) {}
201 // If there's a TestingFactory set, then create a service during BrowserContext
203 bool UserCloudPolicyManagerFactory::ServiceIsCreatedWithBrowserContext() const {
204 return testing_factory_
!= NULL
;
207 void UserCloudPolicyManagerFactory::CreateServiceNow(
208 content::BrowserContext
* context
) {
209 DCHECK(testing_factory_
);
210 manager_wrappers_
[context
] = new ManagerWrapper(testing_factory_(context
));
213 } // namespace policy