user_cloud_policy_manager_factory.cc revision 116680a4aac90f2aa7413d9095a592090648e557
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/user_cloud_policy_manager_factory.h"
6
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/keyed_service/content/browser_context_dependency_manager.h"
14#include "components/keyed_service/core/keyed_service.h"
15#include "components/policy/core/common/cloud/cloud_external_data_manager.h"
16#include "components/policy/core/common/cloud/cloud_policy_constants.h"
17#include "components/policy/core/common/cloud/user_cloud_policy_manager.h"
18#include "components/policy/core/common/cloud/user_cloud_policy_store.h"
19#include "content/public/browser/browser_context.h"
20
21namespace policy {
22
23namespace {
24
25// Directory inside the profile directory where policy-related resources are
26// stored.
27const base::FilePath::CharType kPolicy[] = FILE_PATH_LITERAL("Policy");
28
29// Directory under kPolicy, in the user's profile dir, where policy for
30// components is cached.
31const base::FilePath::CharType kComponentsDir[] =
32    FILE_PATH_LITERAL("Components");
33
34}  // namespace
35
36// A KeyedService that wraps a UserCloudPolicyManager.
37class UserCloudPolicyManagerFactory::ManagerWrapper : public KeyedService {
38 public:
39  explicit ManagerWrapper(UserCloudPolicyManager* manager)
40      : manager_(manager) {
41    DCHECK(manager);
42  }
43  virtual ~ManagerWrapper() {}
44
45  virtual void Shutdown() OVERRIDE {
46    manager_->Shutdown();
47  }
48
49  UserCloudPolicyManager* manager() { return manager_; }
50
51 private:
52  UserCloudPolicyManager* manager_;
53
54  DISALLOW_COPY_AND_ASSIGN(ManagerWrapper);
55};
56
57// static
58UserCloudPolicyManagerFactory* UserCloudPolicyManagerFactory::GetInstance() {
59  return Singleton<UserCloudPolicyManagerFactory>::get();
60}
61
62// static
63UserCloudPolicyManager* UserCloudPolicyManagerFactory::GetForBrowserContext(
64    content::BrowserContext* context) {
65  return GetInstance()->GetManagerForBrowserContext(context);
66}
67
68// static
69scoped_ptr<UserCloudPolicyManager>
70UserCloudPolicyManagerFactory::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(
81      context,
82      force_immediate_load,
83      background_task_runner,
84      file_task_runner,
85      io_task_runner);
86}
87
88// static
89UserCloudPolicyManager*
90UserCloudPolicyManagerFactory::RegisterForOffTheRecordBrowserContext(
91    content::BrowserContext* original_context,
92    content::BrowserContext* off_the_record_context) {
93  return GetInstance()->RegisterManagerForOffTheRecordBrowserContext(
94      original_context, off_the_record_context);
95}
96
97void 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_);
102  DCHECK(factory);
103  DCHECK(manager_wrappers_.empty());
104  testing_factory_ = factory;
105}
106
107void UserCloudPolicyManagerFactory::ClearTestingFactory() {
108  testing_factory_ = NULL;
109}
110
111UserCloudPolicyManagerFactory::UserCloudPolicyManagerFactory()
112    : BrowserContextKeyedBaseFactory(
113        "UserCloudPolicyManager",
114        BrowserContextDependencyManager::GetInstance()),
115      testing_factory_(NULL) {
116  DependsOn(SchemaRegistryServiceFactory::GetInstance());
117}
118
119UserCloudPolicyManagerFactory::~UserCloudPolicyManagerFactory() {
120  DCHECK(manager_wrappers_.empty());
121}
122
123UserCloudPolicyManager*
124UserCloudPolicyManagerFactory::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;
130}
131
132scoped_ptr<UserCloudPolicyManager>
133UserCloudPolicyManagerFactory::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());
140
141  // This should never be called if we're using a testing factory.
142  // Instead, instances are instantiated via CreateServiceNow().
143  DCHECK(!testing_factory_);
144
145  scoped_ptr<UserCloudPolicyStore> store(
146      UserCloudPolicyStore::Create(context->GetPath(),
147                                   GetPolicyVerificationKey(),
148                                   background_task_runner));
149  if (force_immediate_load)
150    store->LoadImmediately();
151
152  const base::FilePath component_policy_cache_dir =
153      context->GetPath().Append(kPolicy).Append(kComponentsDir);
154
155  scoped_ptr<UserCloudPolicyManager> manager;
156  manager.reset(new UserCloudPolicyManager(
157      store.Pass(),
158      component_policy_cache_dir,
159      scoped_ptr<CloudExternalDataManager>(),
160      base::MessageLoopProxy::current(),
161      file_task_runner,
162      io_task_runner));
163  manager->Init(
164      SchemaRegistryServiceFactory::GetForContext(context)->registry());
165  manager_wrappers_[context] = new ManagerWrapper(manager.get());
166  return manager.Pass();
167}
168
169UserCloudPolicyManager*
170UserCloudPolicyManagerFactory::RegisterManagerForOffTheRecordBrowserContext(
171    content::BrowserContext* original_context,
172    content::BrowserContext* off_the_record_context) {
173  // Register the UserCloudPolicyManager of the original context for the
174  // respective incognito context. See also GetManagerForBrowserContext.
175  UserCloudPolicyManager* manager =
176      GetManagerForBrowserContext(original_context);
177  manager_wrappers_[off_the_record_context] = new ManagerWrapper(manager);
178  return manager;
179}
180
181void UserCloudPolicyManagerFactory::BrowserContextShutdown(
182    content::BrowserContext* context) {
183  if (context->IsOffTheRecord())
184    return;
185  ManagerWrapperMap::iterator it = manager_wrappers_.find(context);
186  // E.g. for a TestingProfile there might not be a manager created.
187  if (it != manager_wrappers_.end())
188    it->second->Shutdown();
189}
190
191void UserCloudPolicyManagerFactory::BrowserContextDestroyed(
192    content::BrowserContext* context) {
193  ManagerWrapperMap::iterator it = manager_wrappers_.find(context);
194  if (it != manager_wrappers_.end()) {
195    // The manager is not owned by the factory, so it's not deleted here.
196    delete it->second;
197    manager_wrappers_.erase(it);
198  }
199}
200
201void UserCloudPolicyManagerFactory::SetEmptyTestingFactory(
202    content::BrowserContext* context) {}
203
204bool UserCloudPolicyManagerFactory::HasTestingFactory(
205    content::BrowserContext* context) {
206  return testing_factory_ != NULL;
207}
208
209// If there's a TestingFactory set, then create a service during BrowserContext
210// initialization.
211bool UserCloudPolicyManagerFactory::ServiceIsCreatedWithBrowserContext() const {
212  return testing_factory_ != NULL;
213}
214
215void UserCloudPolicyManagerFactory::CreateServiceNow(
216    content::BrowserContext* context) {
217  DCHECK(testing_factory_);
218  manager_wrappers_[context] = new ManagerWrapper(testing_factory_(context));
219}
220
221}  // namespace policy
222