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