Home | History | Annotate | Download | only in cloud
      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 
     21 namespace policy {
     22 
     23 namespace {
     24 
     25 // Directory inside the profile directory where policy-related resources are
     26 // stored.
     27 const 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.
     31 const base::FilePath::CharType kComponentsDir[] =
     32     FILE_PATH_LITERAL("Components");
     33 
     34 }  // namespace
     35 
     36 // A KeyedService that wraps a UserCloudPolicyManager.
     37 class 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
     58 UserCloudPolicyManagerFactory* UserCloudPolicyManagerFactory::GetInstance() {
     59   return Singleton<UserCloudPolicyManagerFactory>::get();
     60 }
     61 
     62 // static
     63 UserCloudPolicyManager* UserCloudPolicyManagerFactory::GetForBrowserContext(
     64     content::BrowserContext* context) {
     65   return GetInstance()->GetManagerForBrowserContext(context);
     66 }
     67 
     68 // static
     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(
     81       context,
     82       force_immediate_load,
     83       background_task_runner,
     84       file_task_runner,
     85       io_task_runner);
     86 }
     87 
     88 // static
     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);
     95 }
     96 
     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_);
    102   DCHECK(factory);
    103   DCHECK(manager_wrappers_.empty());
    104   testing_factory_ = factory;
    105 }
    106 
    107 void UserCloudPolicyManagerFactory::ClearTestingFactory() {
    108   testing_factory_ = NULL;
    109 }
    110 
    111 UserCloudPolicyManagerFactory::UserCloudPolicyManagerFactory()
    112     : BrowserContextKeyedBaseFactory(
    113         "UserCloudPolicyManager",
    114         BrowserContextDependencyManager::GetInstance()),
    115       testing_factory_(NULL) {
    116   DependsOn(SchemaRegistryServiceFactory::GetInstance());
    117 }
    118 
    119 UserCloudPolicyManagerFactory::~UserCloudPolicyManagerFactory() {
    120   DCHECK(manager_wrappers_.empty());
    121 }
    122 
    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;
    130 }
    131 
    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());
    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 
    169 UserCloudPolicyManager*
    170 UserCloudPolicyManagerFactory::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 
    181 void 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 
    191 void 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 
    201 void UserCloudPolicyManagerFactory::SetEmptyTestingFactory(
    202     content::BrowserContext* context) {}
    203 
    204 bool 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.
    211 bool UserCloudPolicyManagerFactory::ServiceIsCreatedWithBrowserContext() const {
    212   return testing_factory_ != NULL;
    213 }
    214 
    215 void 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