Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / storage / managed_value_store_cache.cc
index b60b773..814d949 100644 (file)
@@ -9,48 +9,60 @@
 #include "base/callback.h"
 #include "base/file_util.h"
 #include "base/logging.h"
-#include "base/memory/ref_counted.h"
-#include "base/message_loop/message_loop_proxy.h"
+#include "base/memory/weak_ptr.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/storage/policy_value_store.h"
-#include "chrome/browser/extensions/api/storage/settings_storage_factory.h"
-#include "chrome/browser/extensions/extension_prefs.h"
-#include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/extensions/extension_system.h"
-#include "chrome/browser/policy/policy_domain_descriptor.h"
 #include "chrome/browser/policy/profile_policy_connector.h"
 #include "chrome/browser/policy/profile_policy_connector_factory.h"
+#include "chrome/browser/policy/schema_registry_service.h"
+#include "chrome/browser/policy/schema_registry_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/value_store/value_store_change.h"
-#include "chrome/common/extensions/api/storage.h"
 #include "chrome/common/extensions/api/storage/storage_schema_manifest_handler.h"
-#include "chrome/common/extensions/extension.h"
-#include "chrome/common/extensions/extension_set.h"
+#include "components/policy/core/common/policy_namespace.h"
 #include "components/policy/core/common/schema.h"
+#include "components/policy/core/common/schema_map.h"
+#include "components/policy/core/common/schema_registry.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/notification_source.h"
+#include "extensions/browser/api/storage/settings_storage_factory.h"
+#include "extensions/browser/extension_prefs.h"
+#include "extensions/browser/extension_registry.h"
+#include "extensions/browser/extension_system.h"
+#include "extensions/browser/value_store/value_store_change.h"
+#include "extensions/common/api/storage.h"
 #include "extensions/common/constants.h"
+#include "extensions/common/extension.h"
+#include "extensions/common/extension_set.h"
 #include "extensions/common/manifest.h"
 #include "extensions/common/manifest_constants.h"
-#include "extensions/common/permissions/api_permission.h"
+#include "extensions/common/one_shot_event.h"
 
+using content::BrowserContext;
 using content::BrowserThread;
 
 namespace extensions {
 
-namespace storage = api::storage;
+namespace storage = core_api::storage;
 
 namespace {
 
 const char kLoadSchemasBackgroundTaskTokenName[] =
     "load_managed_storage_schemas_token";
 
+// The Legacy Browser Support was the first user of the policy-for-extensions
+// API, and relied on behavior that will be phased out. If this extension is
+// present then its policies will be loaded in a special way.
+// TODO(joaodasilva): remove this for M35. http://crbug.com/325349
+const char kLegacyBrowserSupportExtensionId[] =
+    "heildphpnddilhkemkielfhnkaagiabh";
+
 }  // namespace
 
 // This helper observes initialization of all the installed extensions and
-// subsequent loads and unloads, and keeps the PolicyService of the Profile
+// subsequent loads and unloads, and keeps the SchemaRegistry of the Profile
 // in sync with the current list of extensions. This allows the PolicyService
 // to fetch cloud policy for those extensions, and allows its providers to
 // selectively load only extension policy that has users.
@@ -66,15 +78,23 @@ class ManagedValueStoreCache::ExtensionTracker
                        const content::NotificationDetails& details) OVERRIDE;
 
  private:
-  // Loads the schemas of the |extensions| and passes a PolicyDomainDescriptor
-  // to RegisterDomain().
-  static void LoadSchemas(scoped_ptr<ExtensionSet> extensions,
-                          base::WeakPtr<ExtensionTracker> self);
-  void RegisterDomain(
-      scoped_refptr<const policy::PolicyDomainDescriptor> descriptor);
+  // Handler for the signal from ExtensionSystem::ready().
+  void OnExtensionsReady();
+
+  // Starts a schema load for all extensions that use managed storage.
+  void LoadSchemas(scoped_ptr<ExtensionSet> added);
+
+  bool UsesManagedStorage(const Extension* extension) const;
+
+  // Loads the schemas of the |extensions| and passes a ComponentMap to
+  // Register().
+  static void LoadSchemasOnBlockingPool(scoped_ptr<ExtensionSet> extensions,
+                                        base::WeakPtr<ExtensionTracker> self);
+  void Register(const policy::ComponentMap* components);
 
   Profile* profile_;
   content::NotificationRegistrar registrar_;
+  policy::SchemaRegistry* schema_registry_;
   base::WeakPtrFactory<ExtensionTracker> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(ExtensionTracker);
@@ -82,179 +102,232 @@ class ManagedValueStoreCache::ExtensionTracker
 
 ManagedValueStoreCache::ExtensionTracker::ExtensionTracker(Profile* profile)
     : profile_(profile),
+      schema_registry_(
+          policy::SchemaRegistryServiceFactory::GetForContext(profile)),
       weak_factory_(this) {
   registrar_.Add(this,
-                 chrome::NOTIFICATION_EXTENSIONS_READY,
+                 chrome::NOTIFICATION_EXTENSION_INSTALLED,
                  content::Source<Profile>(profile_));
   registrar_.Add(this,
-                 chrome::NOTIFICATION_EXTENSION_LOADED,
-                 content::Source<Profile>(profile_));
-  registrar_.Add(this,
-                 chrome::NOTIFICATION_EXTENSION_UNLOADED,
+                 chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
                  content::Source<Profile>(profile_));
+
+  // Load schemas when the extension system is ready. It might be ready now.
+  ExtensionSystem::Get(profile_)->ready().Post(
+      FROM_HERE,
+      base::Bind(&ExtensionTracker::OnExtensionsReady,
+                 weak_factory_.GetWeakPtr()));
 }
 
 void ManagedValueStoreCache::ExtensionTracker::Observe(
     int type,
     const content::NotificationSource& source,
     const content::NotificationDetails& details) {
+  // Some extensions are installed on the first run before the ExtensionSystem
+  // becomes ready. Wait until all of them are ready before registering the
+  // schemas of managed extensions, so that the policy loaders are reloaded at
+  // most once.
   if (!ExtensionSystem::Get(profile_)->ready().is_signaled())
     return;
 
-  scoped_refptr<policy::PolicyDomainDescriptor> descriptor(
-      new policy::PolicyDomainDescriptor(policy::POLICY_DOMAIN_EXTENSIONS));
-  const ExtensionSet* set =
-      ExtensionSystem::Get(profile_)->extension_service()->extensions();
-  scoped_ptr<ExtensionSet> managed_extensions(new ExtensionSet());
-  for (ExtensionSet::const_iterator it = set->begin(); it != set->end(); ++it) {
-    if ((*it)->manifest()->HasPath(manifest_keys::kStorageManagedSchema)) {
-      managed_extensions->Insert(*it);
+  switch (type) {
+    case chrome::NOTIFICATION_EXTENSION_INSTALLED: {
+      scoped_ptr<ExtensionSet> added(new ExtensionSet);
+      added->Insert(
+          content::Details<InstalledExtensionInfo>(details)->extension);
+      LoadSchemas(added.Pass());
+      break;
     }
+    case chrome::NOTIFICATION_EXTENSION_UNINSTALLED: {
+      const Extension* removed =
+          content::Details<const Extension>(details).ptr();
+      if (removed && UsesManagedStorage(removed)) {
+        schema_registry_->UnregisterComponent(policy::PolicyNamespace(
+            policy::POLICY_DOMAIN_EXTENSIONS, removed->id()));
+      }
+      break;
+    }
+    default:
+      NOTREACHED();
+      return;
+  }
+}
+
+void ManagedValueStoreCache::ExtensionTracker::OnExtensionsReady() {
+  // Load schemas for all installed extensions.
+  LoadSchemas(
+      ExtensionRegistry::Get(profile_)->GenerateInstalledExtensionsSet());
+}
 
-    // TODO(joaodasilva): also load extensions that use the storage API for now,
-    // to support the Legacy Browser Support extension. Remove this for M30.
-    // http://crbug.com/240704
-    if ((*it)->HasAPIPermission(APIPermission::kStorage))
-      managed_extensions->Insert(*it);
+void ManagedValueStoreCache::ExtensionTracker::LoadSchemas(
+    scoped_ptr<ExtensionSet> added) {
+  // Filter out extensions that don't use managed storage.
+  ExtensionSet::const_iterator it = added->begin();
+  while (it != added->end()) {
+    std::string to_remove;
+    if (!UsesManagedStorage(*it))
+      to_remove = (*it)->id();
+    ++it;
+    if (!to_remove.empty())
+      added->Remove(to_remove);
   }
 
   // Load the schema files in a background thread.
   BrowserThread::PostBlockingPoolSequencedTask(
       kLoadSchemasBackgroundTaskTokenName, FROM_HERE,
-      base::Bind(&ExtensionTracker::LoadSchemas,
-                 base::Passed(&managed_extensions),
+      base::Bind(&ExtensionTracker::LoadSchemasOnBlockingPool,
+                 base::Passed(&added),
                  weak_factory_.GetWeakPtr()));
 }
 
+bool ManagedValueStoreCache::ExtensionTracker::UsesManagedStorage(
+    const Extension* extension) const {
+  if (extension->manifest()->HasPath(manifest_keys::kStorageManagedSchema))
+    return true;
+
+  // TODO(joaodasilva): remove this by M35.
+  return extension->id() == kLegacyBrowserSupportExtensionId;
+}
+
 // static
-void ManagedValueStoreCache::ExtensionTracker::LoadSchemas(
+void ManagedValueStoreCache::ExtensionTracker::LoadSchemasOnBlockingPool(
     scoped_ptr<ExtensionSet> extensions,
     base::WeakPtr<ExtensionTracker> self) {
-  scoped_refptr<policy::PolicyDomainDescriptor> descriptor =
-      new policy::PolicyDomainDescriptor(policy::POLICY_DOMAIN_EXTENSIONS);
+  DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
+  scoped_ptr<policy::ComponentMap> components(new policy::ComponentMap);
 
   for (ExtensionSet::const_iterator it = extensions->begin();
        it != extensions->end(); ++it) {
     std::string schema_file;
     if (!(*it)->manifest()->GetString(
             manifest_keys::kStorageManagedSchema, &schema_file)) {
-      // TODO(joaodasilva): Remove this for M32. http://crbug.com/240704
-      if ((*it)->HasAPIPermission(APIPermission::kStorage)) {
-        descriptor->RegisterComponent((*it)->id(),
-                                      scoped_ptr<policy::SchemaOwner>());
-      } else {
-        NOTREACHED();
-      }
+      // TODO(joaodasilva): Remove this. http://crbug.com/325349
+      (*components)[(*it)->id()] = policy::Schema();
       continue;
     }
     // The extension should have been validated, so assume the schema exists
     // and is valid.
     std::string error;
-    scoped_ptr<policy::SchemaOwner> schema =
+    policy::Schema schema =
         StorageSchemaManifestHandler::GetSchema(it->get(), &error);
-    CHECK(schema) << error;
-    descriptor->RegisterComponent((*it)->id(), schema.Pass());
+    CHECK(schema.valid()) << error;
+    (*components)[(*it)->id()] = schema;
   }
 
-  BrowserThread::PostTask(
-      BrowserThread::UI, FROM_HERE,
-      base::Bind(&ExtensionTracker::RegisterDomain, self, descriptor));
+  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+                          base::Bind(&ExtensionTracker::Register, self,
+                                     base::Owned(components.release())));
 }
 
-void ManagedValueStoreCache::ExtensionTracker::RegisterDomain(
-    scoped_refptr<const policy::PolicyDomainDescriptor> descriptor) {
-  policy::ProfilePolicyConnector* connector =
-      policy::ProfilePolicyConnectorFactory::GetForProfile(profile_);
-  connector->policy_service()->RegisterPolicyDomain(descriptor);
+void ManagedValueStoreCache::ExtensionTracker::Register(
+    const policy::ComponentMap* components) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  schema_registry_->RegisterComponents(policy::POLICY_DOMAIN_EXTENSIONS,
+                                       *components);
+
+  // The first SetReady() call is performed after the ExtensionSystem is ready,
+  // even if there are no managed extensions. It will trigger a loading of the
+  // initial policy for any managed extensions, and eventually the PolicyService
+  // will become ready for POLICY_DOMAIN_EXTENSIONS, and
+  // OnPolicyServiceInitialized() will be invoked.
+  // Subsequent calls to SetReady() are ignored.
+  schema_registry_->SetReady(policy::POLICY_DOMAIN_EXTENSIONS);
 }
 
 ManagedValueStoreCache::ManagedValueStoreCache(
-    Profile* profile,
+    BrowserContext* context,
     const scoped_refptr<SettingsStorageFactory>& factory,
     const scoped_refptr<SettingsObserverList>& observers)
-    : weak_factory_(this),
-      weak_this_on_ui_(weak_factory_.GetWeakPtr()),
-      profile_(profile),
-      event_router_(ExtensionSystem::Get(profile)->event_router()),
+    : profile_(Profile::FromBrowserContext(context)),
+      policy_service_(policy::ProfilePolicyConnectorFactory::GetForProfile(
+                          profile_)->policy_service()),
       storage_factory_(factory),
       observers_(observers),
-      base_path_(profile->GetPath().AppendASCII(
+      base_path_(profile_->GetPath().AppendASCII(
           extensions::kManagedSettingsDirectoryName)) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  // |event_router_| can be NULL on unit_tests.
-  if (event_router_)
-    event_router_->RegisterObserver(this, storage::OnChanged::kEventName);
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
-  GetPolicyService()->AddObserver(policy::POLICY_DOMAIN_EXTENSIONS, this);
+  policy_service_->AddObserver(policy::POLICY_DOMAIN_EXTENSIONS, this);
 
   extension_tracker_.reset(new ExtensionTracker(profile_));
+
+  if (policy_service_->IsInitializationComplete(
+          policy::POLICY_DOMAIN_EXTENSIONS)) {
+    OnPolicyServiceInitialized(policy::POLICY_DOMAIN_EXTENSIONS);
+  }
 }
 
 ManagedValueStoreCache::~ManagedValueStoreCache() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
-  DCHECK(!event_router_);
+  DCHECK_CURRENTLY_ON(BrowserThread::FILE);
   // Delete the PolicyValueStores on FILE.
   store_map_.clear();
 }
 
 void ManagedValueStoreCache::ShutdownOnUI() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  GetPolicyService()->RemoveObserver(policy::POLICY_DOMAIN_EXTENSIONS, this);
-  if (event_router_)
-    event_router_->UnregisterObserver(this);
-  event_router_ = NULL;
-  weak_factory_.InvalidateWeakPtrs();
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  policy_service_->RemoveObserver(policy::POLICY_DOMAIN_EXTENSIONS, this);
   extension_tracker_.reset();
 }
 
 void ManagedValueStoreCache::RunWithValueStoreForExtension(
     const StorageCallback& callback,
     scoped_refptr<const Extension> extension) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
-  PolicyValueStore* store = GetStoreFor(extension->id());
-  if (store) {
-    callback.Run(store);
-  } else {
-    // First time that an extension calls storage.managed.get(). Create the
-    // store and load it with the current policy, and don't send event
-    // notifications.
-    CreateStoreFor(
-        extension->id(),
-        false,
-        base::Bind(&ManagedValueStoreCache::RunWithValueStoreForExtension,
-                   base::Unretained(this),
-                   callback,
-                   extension));
-  }
+  DCHECK_CURRENTLY_ON(BrowserThread::FILE);
+  callback.Run(GetStoreFor(extension->id()));
 }
 
 void ManagedValueStoreCache::DeleteStorageSoon(
     const std::string& extension_id) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
-  PolicyValueStore* store = GetStoreFor(extension_id);
-  if (!store) {
-    // It's possible that the store exists, but hasn't been loaded yet
-    // (because the extension is unloaded, for example). Open the database to
-    // clear it if it exists.
-    // TODO(joaodasilva): move this check to a ValueStore method.
-    if (base::DirectoryExists(base_path_.AppendASCII(extension_id))) {
-      CreateStoreFor(
-          extension_id,
-          false,
-          base::Bind(&ManagedValueStoreCache::DeleteStorageSoon,
-                     base::Unretained(this),
-                     extension_id));
-    }
-  } else {
-    store->DeleteStorage();
-    store_map_.erase(extension_id);
+  DCHECK_CURRENTLY_ON(BrowserThread::FILE);
+  // It's possible that the store exists, but hasn't been loaded yet
+  // (because the extension is unloaded, for example). Open the database to
+  // clear it if it exists.
+  if (!HasStore(extension_id))
+    return;
+  GetStoreFor(extension_id)->DeleteStorage();
+  store_map_.erase(extension_id);
+}
+
+void ManagedValueStoreCache::OnPolicyServiceInitialized(
+    policy::PolicyDomain domain) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+  if (domain != policy::POLICY_DOMAIN_EXTENSIONS)
+    return;
+
+  // The PolicyService now has all the initial policies ready. Send policy
+  // for all the managed extensions to their backing stores now.
+  policy::SchemaRegistry* registry =
+      policy::SchemaRegistryServiceFactory::GetForContext(profile_);
+  const policy::ComponentMap* map = registry->schema_map()->GetComponents(
+      policy::POLICY_DOMAIN_EXTENSIONS);
+  if (!map)
+    return;
+
+  const policy::PolicyMap empty_map;
+  for (policy::ComponentMap::const_iterator it = map->begin();
+       it != map->end(); ++it) {
+    const policy::PolicyNamespace ns(policy::POLICY_DOMAIN_EXTENSIONS,
+                                     it->first);
+    // If there is no policy for |ns| then this will clear the previous store,
+    // if there is one.
+    OnPolicyUpdated(ns, empty_map, policy_service_->GetPolicies(ns));
   }
 }
 
 void ManagedValueStoreCache::OnPolicyUpdated(const policy::PolicyNamespace& ns,
                                              const policy::PolicyMap& previous,
                                              const policy::PolicyMap& current) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+  if (!policy_service_->IsInitializationComplete(
+           policy::POLICY_DOMAIN_EXTENSIONS)) {
+    // OnPolicyUpdated is called whenever a policy changes, but it doesn't
+    // mean that all the policy providers are ready; wait until we get the
+    // final policy values before passing them to the store.
+    return;
+  }
+
   BrowserThread::PostTask(
       BrowserThread::FILE, FROM_HERE,
       base::Bind(&ManagedValueStoreCache::UpdatePolicyOnFILE,
@@ -266,148 +339,40 @@ void ManagedValueStoreCache::OnPolicyUpdated(const policy::PolicyNamespace& ns,
 void ManagedValueStoreCache::UpdatePolicyOnFILE(
     const std::string& extension_id,
     scoped_ptr<policy::PolicyMap> current_policy) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
-  PolicyValueStore* store = GetStoreFor(extension_id);
-  if (!store) {
-    // The extension hasn't executed any storage.managed.* calls, and isn't
-    // listening for onChanged() either. Ignore this notification in that case.
+  DCHECK_CURRENTLY_ON(BrowserThread::FILE);
+
+  if (!HasStore(extension_id) && current_policy->empty()) {
+    // Don't create the store now if there are no policies configured for this
+    // extension. If the extension uses the storage.managed API then the store
+    // will be created at RunWithValueStoreForExtension().
     return;
   }
-  // Update the policy on the backing store, and fire notifications if it
-  // changed.
-  store->SetCurrentPolicy(*current_policy, true);
-}
 
-void ManagedValueStoreCache::OnListenerAdded(
-    const EventListenerInfo& details) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK_EQ(std::string(storage::OnChanged::kEventName), details.event_name);
-  // This is invoked on several occasions:
-  //
-  // 1. when an extension first registers to observe storage.onChanged; in this
-  //    case the backend doesn't have any previous data persisted, and it won't
-  //    trigger a notification.
-  //
-  // 2. when the browser starts up and all existing extensions re-register for
-  //    the onChanged event. In this case, if the current policy differs from
-  //    the persisted version then a notification will be sent.
-  //
-  // 3. a policy update just occurred and sent a notification, and an extension
-  //    with EventPages that is observing onChanged just woke up and registed
-  //    again. In this case the policy update already persisted the current
-  //    policy version, and |store| already exists.
-  BrowserThread::PostTask(
-      BrowserThread::FILE, FROM_HERE,
-      base::Bind(&ManagedValueStoreCache::CreateForExtensionOnFILE,
-                 base::Unretained(this),
-                 details.extension_id));
-}
-
-void ManagedValueStoreCache::CreateForExtensionOnFILE(
-    const std::string& extension_id) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
-  PolicyValueStore* store = GetStoreFor(extension_id);
-  if (!store)
-    CreateStoreFor(extension_id, true, base::Closure());
+  GetStoreFor(extension_id)->SetCurrentPolicy(*current_policy);
 }
 
 PolicyValueStore* ManagedValueStoreCache::GetStoreFor(
     const std::string& extension_id) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
-  PolicyValueStoreMap::iterator it = store_map_.find(extension_id);
-  if (it == store_map_.end())
-    return NULL;
-  return it->second.get();
-}
+  DCHECK_CURRENTLY_ON(BrowserThread::FILE);
 
-void ManagedValueStoreCache::CreateStoreFor(
-    const std::string& extension_id,
-    bool notify_if_changed,
-    const base::Closure& continuation) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
-  DCHECK(!GetStoreFor(extension_id));
-  // Creating or loading an existing database requires an immediate update
-  // with the current policy for the corresponding extension, which must be
-  // retrieved on UI.
-  BrowserThread::PostTask(
-      BrowserThread::UI, FROM_HERE,
-      base::Bind(&ManagedValueStoreCache::GetInitialPolicy,
-                 weak_this_on_ui_,
-                 extension_id,
-                 notify_if_changed,
-                 continuation));
-}
-
-void ManagedValueStoreCache::GetInitialPolicy(
-    const std::string& extension_id,
-    bool notify_if_changed,
-    const base::Closure& continuation) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
-  policy::PolicyService* policy_service = GetPolicyService();
-
-  // If initialization of POLICY_DOMAIN_EXTENSIONS isn't complete then all the
-  // policies served are empty; let the extension see what's cached in LevelDB
-  // in that case. The PolicyService will issue notifications once new policies
-  // are ready.
-  scoped_ptr<policy::PolicyMap> policy;
-  if (policy_service->IsInitializationComplete(
-          policy::POLICY_DOMAIN_EXTENSIONS)) {
-    policy::PolicyNamespace ns(policy::POLICY_DOMAIN_EXTENSIONS, extension_id);
-    policy = policy_service->GetPolicies(ns).DeepCopy();
-  }
-
-  // Now post back to FILE to create the database.
-  BrowserThread::PostTask(
-      BrowserThread::FILE, FROM_HERE,
-      base::Bind(&ManagedValueStoreCache::CreateStoreWithInitialPolicy,
-                 base::Unretained(this),
-                 extension_id,
-                 notify_if_changed,
-                 base::Passed(&policy),
-                 continuation));
-}
-
-void ManagedValueStoreCache::CreateStoreWithInitialPolicy(
-    const std::string& extension_id,
-    bool notify_if_changed,
-    scoped_ptr<policy::PolicyMap> initial_policy,
-    const base::Closure& continuation) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
-  // If a 2nd call to CreateStoreFor() is issued before the 1st gets to execute
-  // its UI task, then the 2nd will enter this function but the store has
-  // already been created. Check for that.
-  PolicyValueStore* store = GetStoreFor(extension_id);
-
-  if (!store) {
-    // Create it now.
-
-    // If the database doesn't exist yet then this is the initial install,
-    // and no notifications should be issued in that case.
-    // TODO(joaodasilva): move this check to a ValueStore method.
-    if (!base::DirectoryExists(base_path_.AppendASCII(extension_id)))
-      notify_if_changed = false;
-
-    store = new PolicyValueStore(
-        extension_id,
-        observers_,
-        make_scoped_ptr(storage_factory_->Create(base_path_, extension_id)));
-    store_map_[extension_id] = make_linked_ptr(store);
-  }
-
-  // Send the latest policy to the store, if it's already available.
-  if (initial_policy)
-    store->SetCurrentPolicy(*initial_policy, notify_if_changed);
-
-  // And finally resume from where this process started.
-  if (!continuation.is_null())
-    continuation.Run();
+  PolicyValueStoreMap::iterator it = store_map_.find(extension_id);
+  if (it != store_map_.end())
+    return it->second.get();
+
+  // Create the store now, and serve the cached policy until the PolicyService
+  // sends updated values.
+  PolicyValueStore* store = new PolicyValueStore(
+      extension_id,
+      observers_,
+      make_scoped_ptr(storage_factory_->Create(base_path_, extension_id)));
+  store_map_[extension_id] = make_linked_ptr(store);
+
+  return store;
 }
 
-policy::PolicyService* ManagedValueStoreCache::GetPolicyService() {
-  policy::ProfilePolicyConnector* connector =
-      policy::ProfilePolicyConnectorFactory::GetForProfile(profile_);
-  return connector->policy_service();
+bool ManagedValueStoreCache::HasStore(const std::string& extension_id) const {
+  // TODO(joaodasilva): move this check to a ValueStore method.
+  return base::DirectoryExists(base_path_.AppendASCII(extension_id));
 }
 
 }  // namespace extensions