| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/extensions/api/storage/managed_value_store_cache.h" | 5 #include "chrome/browser/extensions/api/storage/managed_value_store_cache.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/callback.h" | 9 #include "base/callback.h" |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 (*components)[(*it)->id()] = schema; | 214 (*components)[(*it)->id()] = schema; |
| 215 } | 215 } |
| 216 | 216 |
| 217 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 217 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 218 base::Bind(&ExtensionTracker::Register, self, | 218 base::Bind(&ExtensionTracker::Register, self, |
| 219 base::Owned(components.release()))); | 219 base::Owned(components.release()))); |
| 220 } | 220 } |
| 221 | 221 |
| 222 void ManagedValueStoreCache::ExtensionTracker::Register( | 222 void ManagedValueStoreCache::ExtensionTracker::Register( |
| 223 const policy::ComponentMap* components) { | 223 const policy::ComponentMap* components) { |
| 224 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 224 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 225 schema_registry_->RegisterComponents(policy::POLICY_DOMAIN_EXTENSIONS, | 225 schema_registry_->RegisterComponents(policy::POLICY_DOMAIN_EXTENSIONS, |
| 226 *components); | 226 *components); |
| 227 | 227 |
| 228 // The first SetReady() call is performed after the ExtensionSystem is ready, | 228 // The first SetReady() call is performed after the ExtensionSystem is ready, |
| 229 // even if there are no managed extensions. It will trigger a loading of the | 229 // even if there are no managed extensions. It will trigger a loading of the |
| 230 // initial policy for any managed extensions, and eventually the PolicyService | 230 // initial policy for any managed extensions, and eventually the PolicyService |
| 231 // will become ready for POLICY_DOMAIN_EXTENSIONS, and | 231 // will become ready for POLICY_DOMAIN_EXTENSIONS, and |
| 232 // OnPolicyServiceInitialized() will be invoked. | 232 // OnPolicyServiceInitialized() will be invoked. |
| 233 // Subsequent calls to SetReady() are ignored. | 233 // Subsequent calls to SetReady() are ignored. |
| 234 schema_registry_->SetReady(policy::POLICY_DOMAIN_EXTENSIONS); | 234 schema_registry_->SetReady(policy::POLICY_DOMAIN_EXTENSIONS); |
| 235 } | 235 } |
| 236 | 236 |
| 237 ManagedValueStoreCache::ManagedValueStoreCache( | 237 ManagedValueStoreCache::ManagedValueStoreCache( |
| 238 BrowserContext* context, | 238 BrowserContext* context, |
| 239 const scoped_refptr<SettingsStorageFactory>& factory, | 239 const scoped_refptr<SettingsStorageFactory>& factory, |
| 240 const scoped_refptr<SettingsObserverList>& observers) | 240 const scoped_refptr<SettingsObserverList>& observers) |
| 241 : profile_(Profile::FromBrowserContext(context)), | 241 : profile_(Profile::FromBrowserContext(context)), |
| 242 policy_service_(policy::ProfilePolicyConnectorFactory::GetForProfile( | 242 policy_service_(policy::ProfilePolicyConnectorFactory::GetForProfile( |
| 243 profile_)->policy_service()), | 243 profile_)->policy_service()), |
| 244 storage_factory_(factory), | 244 storage_factory_(factory), |
| 245 observers_(observers), | 245 observers_(observers), |
| 246 base_path_(profile_->GetPath().AppendASCII( | 246 base_path_(profile_->GetPath().AppendASCII( |
| 247 extensions::kManagedSettingsDirectoryName)) { | 247 extensions::kManagedSettingsDirectoryName)) { |
| 248 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 248 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 249 | 249 |
| 250 policy_service_->AddObserver(policy::POLICY_DOMAIN_EXTENSIONS, this); | 250 policy_service_->AddObserver(policy::POLICY_DOMAIN_EXTENSIONS, this); |
| 251 | 251 |
| 252 extension_tracker_.reset(new ExtensionTracker(profile_)); | 252 extension_tracker_.reset(new ExtensionTracker(profile_)); |
| 253 | 253 |
| 254 if (policy_service_->IsInitializationComplete( | 254 if (policy_service_->IsInitializationComplete( |
| 255 policy::POLICY_DOMAIN_EXTENSIONS)) { | 255 policy::POLICY_DOMAIN_EXTENSIONS)) { |
| 256 OnPolicyServiceInitialized(policy::POLICY_DOMAIN_EXTENSIONS); | 256 OnPolicyServiceInitialized(policy::POLICY_DOMAIN_EXTENSIONS); |
| 257 } | 257 } |
| 258 } | 258 } |
| 259 | 259 |
| 260 ManagedValueStoreCache::~ManagedValueStoreCache() { | 260 ManagedValueStoreCache::~ManagedValueStoreCache() { |
| 261 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 261 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 262 // Delete the PolicyValueStores on FILE. | 262 // Delete the PolicyValueStores on FILE. |
| 263 store_map_.clear(); | 263 store_map_.clear(); |
| 264 } | 264 } |
| 265 | 265 |
| 266 void ManagedValueStoreCache::ShutdownOnUI() { | 266 void ManagedValueStoreCache::ShutdownOnUI() { |
| 267 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 267 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 268 policy_service_->RemoveObserver(policy::POLICY_DOMAIN_EXTENSIONS, this); | 268 policy_service_->RemoveObserver(policy::POLICY_DOMAIN_EXTENSIONS, this); |
| 269 extension_tracker_.reset(); | 269 extension_tracker_.reset(); |
| 270 } | 270 } |
| 271 | 271 |
| 272 void ManagedValueStoreCache::RunWithValueStoreForExtension( | 272 void ManagedValueStoreCache::RunWithValueStoreForExtension( |
| 273 const StorageCallback& callback, | 273 const StorageCallback& callback, |
| 274 scoped_refptr<const Extension> extension) { | 274 scoped_refptr<const Extension> extension) { |
| 275 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 275 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 276 callback.Run(GetStoreFor(extension->id())); | 276 callback.Run(GetStoreFor(extension->id())); |
| 277 } | 277 } |
| 278 | 278 |
| 279 void ManagedValueStoreCache::DeleteStorageSoon( | 279 void ManagedValueStoreCache::DeleteStorageSoon( |
| 280 const std::string& extension_id) { | 280 const std::string& extension_id) { |
| 281 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 281 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 282 // It's possible that the store exists, but hasn't been loaded yet | 282 // It's possible that the store exists, but hasn't been loaded yet |
| 283 // (because the extension is unloaded, for example). Open the database to | 283 // (because the extension is unloaded, for example). Open the database to |
| 284 // clear it if it exists. | 284 // clear it if it exists. |
| 285 if (!HasStore(extension_id)) | 285 if (!HasStore(extension_id)) |
| 286 return; | 286 return; |
| 287 GetStoreFor(extension_id)->DeleteStorage(); | 287 GetStoreFor(extension_id)->DeleteStorage(); |
| 288 store_map_.erase(extension_id); | 288 store_map_.erase(extension_id); |
| 289 } | 289 } |
| 290 | 290 |
| 291 void ManagedValueStoreCache::OnPolicyServiceInitialized( | 291 void ManagedValueStoreCache::OnPolicyServiceInitialized( |
| 292 policy::PolicyDomain domain) { | 292 policy::PolicyDomain domain) { |
| 293 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 293 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 294 | 294 |
| 295 if (domain != policy::POLICY_DOMAIN_EXTENSIONS) | 295 if (domain != policy::POLICY_DOMAIN_EXTENSIONS) |
| 296 return; | 296 return; |
| 297 | 297 |
| 298 // The PolicyService now has all the initial policies ready. Send policy | 298 // The PolicyService now has all the initial policies ready. Send policy |
| 299 // for all the managed extensions to their backing stores now. | 299 // for all the managed extensions to their backing stores now. |
| 300 policy::SchemaRegistry* registry = | 300 policy::SchemaRegistry* registry = |
| 301 policy::SchemaRegistryServiceFactory::GetForContext(profile_); | 301 policy::SchemaRegistryServiceFactory::GetForContext(profile_); |
| 302 const policy::ComponentMap* map = registry->schema_map()->GetComponents( | 302 const policy::ComponentMap* map = registry->schema_map()->GetComponents( |
| 303 policy::POLICY_DOMAIN_EXTENSIONS); | 303 policy::POLICY_DOMAIN_EXTENSIONS); |
| 304 if (!map) | 304 if (!map) |
| 305 return; | 305 return; |
| 306 | 306 |
| 307 const policy::PolicyMap empty_map; | 307 const policy::PolicyMap empty_map; |
| 308 for (policy::ComponentMap::const_iterator it = map->begin(); | 308 for (policy::ComponentMap::const_iterator it = map->begin(); |
| 309 it != map->end(); ++it) { | 309 it != map->end(); ++it) { |
| 310 const policy::PolicyNamespace ns(policy::POLICY_DOMAIN_EXTENSIONS, | 310 const policy::PolicyNamespace ns(policy::POLICY_DOMAIN_EXTENSIONS, |
| 311 it->first); | 311 it->first); |
| 312 // If there is no policy for |ns| then this will clear the previous store, | 312 // If there is no policy for |ns| then this will clear the previous store, |
| 313 // if there is one. | 313 // if there is one. |
| 314 OnPolicyUpdated(ns, empty_map, policy_service_->GetPolicies(ns)); | 314 OnPolicyUpdated(ns, empty_map, policy_service_->GetPolicies(ns)); |
| 315 } | 315 } |
| 316 } | 316 } |
| 317 | 317 |
| 318 void ManagedValueStoreCache::OnPolicyUpdated(const policy::PolicyNamespace& ns, | 318 void ManagedValueStoreCache::OnPolicyUpdated(const policy::PolicyNamespace& ns, |
| 319 const policy::PolicyMap& previous, | 319 const policy::PolicyMap& previous, |
| 320 const policy::PolicyMap& current) { | 320 const policy::PolicyMap& current) { |
| 321 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 321 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 322 | 322 |
| 323 if (!policy_service_->IsInitializationComplete( | 323 if (!policy_service_->IsInitializationComplete( |
| 324 policy::POLICY_DOMAIN_EXTENSIONS)) { | 324 policy::POLICY_DOMAIN_EXTENSIONS)) { |
| 325 // OnPolicyUpdated is called whenever a policy changes, but it doesn't | 325 // OnPolicyUpdated is called whenever a policy changes, but it doesn't |
| 326 // mean that all the policy providers are ready; wait until we get the | 326 // mean that all the policy providers are ready; wait until we get the |
| 327 // final policy values before passing them to the store. | 327 // final policy values before passing them to the store. |
| 328 return; | 328 return; |
| 329 } | 329 } |
| 330 | 330 |
| 331 BrowserThread::PostTask( | 331 BrowserThread::PostTask( |
| 332 BrowserThread::FILE, FROM_HERE, | 332 BrowserThread::FILE, FROM_HERE, |
| 333 base::Bind(&ManagedValueStoreCache::UpdatePolicyOnFILE, | 333 base::Bind(&ManagedValueStoreCache::UpdatePolicyOnFILE, |
| 334 base::Unretained(this), | 334 base::Unretained(this), |
| 335 ns.component_id, | 335 ns.component_id, |
| 336 base::Passed(current.DeepCopy()))); | 336 base::Passed(current.DeepCopy()))); |
| 337 } | 337 } |
| 338 | 338 |
| 339 void ManagedValueStoreCache::UpdatePolicyOnFILE( | 339 void ManagedValueStoreCache::UpdatePolicyOnFILE( |
| 340 const std::string& extension_id, | 340 const std::string& extension_id, |
| 341 scoped_ptr<policy::PolicyMap> current_policy) { | 341 scoped_ptr<policy::PolicyMap> current_policy) { |
| 342 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 342 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 343 | 343 |
| 344 if (!HasStore(extension_id) && current_policy->empty()) { | 344 if (!HasStore(extension_id) && current_policy->empty()) { |
| 345 // Don't create the store now if there are no policies configured for this | 345 // Don't create the store now if there are no policies configured for this |
| 346 // extension. If the extension uses the storage.managed API then the store | 346 // extension. If the extension uses the storage.managed API then the store |
| 347 // will be created at RunWithValueStoreForExtension(). | 347 // will be created at RunWithValueStoreForExtension(). |
| 348 return; | 348 return; |
| 349 } | 349 } |
| 350 | 350 |
| 351 GetStoreFor(extension_id)->SetCurrentPolicy(*current_policy); | 351 GetStoreFor(extension_id)->SetCurrentPolicy(*current_policy); |
| 352 } | 352 } |
| 353 | 353 |
| 354 PolicyValueStore* ManagedValueStoreCache::GetStoreFor( | 354 PolicyValueStore* ManagedValueStoreCache::GetStoreFor( |
| 355 const std::string& extension_id) { | 355 const std::string& extension_id) { |
| 356 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 356 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 357 | 357 |
| 358 PolicyValueStoreMap::iterator it = store_map_.find(extension_id); | 358 PolicyValueStoreMap::iterator it = store_map_.find(extension_id); |
| 359 if (it != store_map_.end()) | 359 if (it != store_map_.end()) |
| 360 return it->second.get(); | 360 return it->second.get(); |
| 361 | 361 |
| 362 // Create the store now, and serve the cached policy until the PolicyService | 362 // Create the store now, and serve the cached policy until the PolicyService |
| 363 // sends updated values. | 363 // sends updated values. |
| 364 PolicyValueStore* store = new PolicyValueStore( | 364 PolicyValueStore* store = new PolicyValueStore( |
| 365 extension_id, | 365 extension_id, |
| 366 observers_, | 366 observers_, |
| 367 make_scoped_ptr(storage_factory_->Create(base_path_, extension_id))); | 367 make_scoped_ptr(storage_factory_->Create(base_path_, extension_id))); |
| 368 store_map_[extension_id] = make_linked_ptr(store); | 368 store_map_[extension_id] = make_linked_ptr(store); |
| 369 | 369 |
| 370 return store; | 370 return store; |
| 371 } | 371 } |
| 372 | 372 |
| 373 bool ManagedValueStoreCache::HasStore(const std::string& extension_id) const { | 373 bool ManagedValueStoreCache::HasStore(const std::string& extension_id) const { |
| 374 // TODO(joaodasilva): move this check to a ValueStore method. | 374 // TODO(joaodasilva): move this check to a ValueStore method. |
| 375 return base::DirectoryExists(base_path_.AppendASCII(extension_id)); | 375 return base::DirectoryExists(base_path_.AppendASCII(extension_id)); |
| 376 } | 376 } |
| 377 | 377 |
| 378 } // namespace extensions | 378 } // namespace extensions |
| OLD | NEW |