summaryrefslogtreecommitdiff
path: root/chromium/extensions/browser/api/storage/storage_frontend.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/extensions/browser/api/storage/storage_frontend.cc')
-rw-r--r--chromium/extensions/browser/api/storage/storage_frontend.cc186
1 files changed, 186 insertions, 0 deletions
diff --git a/chromium/extensions/browser/api/storage/storage_frontend.cc b/chromium/extensions/browser/api/storage/storage_frontend.cc
new file mode 100644
index 00000000000..911a49290bf
--- /dev/null
+++ b/chromium/extensions/browser/api/storage/storage_frontend.cc
@@ -0,0 +1,186 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "extensions/browser/api/storage/storage_frontend.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/files/file_path.h"
+#include "base/json/json_reader.h"
+#include "base/lazy_instance.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/trace_event/trace_event.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_thread.h"
+#include "extensions/browser/api/extensions_api_client.h"
+#include "extensions/browser/api/storage/local_value_store_cache.h"
+#include "extensions/browser/event_router.h"
+#include "extensions/browser/extension_registry.h"
+#include "extensions/browser/extension_system.h"
+#include "extensions/browser/value_store/value_store_factory.h"
+#include "extensions/common/api/storage.h"
+
+using content::BrowserContext;
+using content::BrowserThread;
+
+namespace extensions {
+
+namespace {
+
+base::LazyInstance<BrowserContextKeyedAPIFactory<StorageFrontend> > g_factory =
+ LAZY_INSTANCE_INITIALIZER;
+
+// Settings change Observer which forwards changes on to the extension
+// processes for |context| and its incognito partner if it exists.
+class DefaultObserver : public SettingsObserver {
+ public:
+ explicit DefaultObserver(BrowserContext* context)
+ : browser_context_(context) {}
+
+ // SettingsObserver implementation.
+ void OnSettingsChanged(const std::string& extension_id,
+ settings_namespace::Namespace settings_namespace,
+ const std::string& change_json) override {
+ // TODO(gdk): This is a temporary hack while the refactoring for
+ // string-based event payloads is removed. http://crbug.com/136045
+ scoped_ptr<base::ListValue> args(new base::ListValue());
+ args->Append(base::JSONReader::Read(change_json));
+ args->Append(new base::StringValue(settings_namespace::ToString(
+ settings_namespace)));
+ scoped_ptr<Event> event(new Event(events::STORAGE_ON_CHANGED,
+ api::storage::OnChanged::kEventName,
+ std::move(args)));
+ EventRouter::Get(browser_context_)
+ ->DispatchEventToExtension(extension_id, std::move(event));
+ }
+
+ private:
+ BrowserContext* const browser_context_;
+};
+
+} // namespace
+
+// static
+StorageFrontend* StorageFrontend::Get(BrowserContext* context) {
+ return BrowserContextKeyedAPIFactory<StorageFrontend>::Get(context);
+}
+
+// static
+scoped_ptr<StorageFrontend> StorageFrontend::CreateForTesting(
+ const scoped_refptr<ValueStoreFactory>& storage_factory,
+ BrowserContext* context) {
+ return make_scoped_ptr(new StorageFrontend(storage_factory, context));
+}
+
+StorageFrontend::StorageFrontend(BrowserContext* context)
+ : StorageFrontend(ExtensionSystem::Get(context)->store_factory(), context) {
+}
+
+StorageFrontend::StorageFrontend(
+ const scoped_refptr<ValueStoreFactory>& factory,
+ BrowserContext* context)
+ : browser_context_(context) {
+ Init(factory);
+}
+
+void StorageFrontend::Init(const scoped_refptr<ValueStoreFactory>& factory) {
+ TRACE_EVENT0("browser,startup", "StorageFrontend::Init")
+ SCOPED_UMA_HISTOGRAM_TIMER("Extensions.StorageFrontendInitTime");
+
+ observers_ = new SettingsObserverList();
+ browser_context_observer_.reset(new DefaultObserver(browser_context_));
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK(!browser_context_->IsOffTheRecord());
+
+ observers_->AddObserver(browser_context_observer_.get());
+
+ caches_[settings_namespace::LOCAL] = new LocalValueStoreCache(factory);
+
+ // Add any additional caches the embedder supports (for example, caches
+ // for chrome.storage.managed and chrome.storage.sync).
+ ExtensionsAPIClient::Get()->AddAdditionalValueStoreCaches(
+ browser_context_, factory, observers_, &caches_);
+}
+
+StorageFrontend::~StorageFrontend() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ observers_->RemoveObserver(browser_context_observer_.get());
+ for (CacheMap::iterator it = caches_.begin(); it != caches_.end(); ++it) {
+ ValueStoreCache* cache = it->second;
+ cache->ShutdownOnUI();
+ BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, cache);
+ }
+}
+
+ValueStoreCache* StorageFrontend::GetValueStoreCache(
+ settings_namespace::Namespace settings_namespace) const {
+ CacheMap::const_iterator it = caches_.find(settings_namespace);
+ if (it != caches_.end())
+ return it->second;
+ return NULL;
+}
+
+bool StorageFrontend::IsStorageEnabled(
+ settings_namespace::Namespace settings_namespace) const {
+ return caches_.find(settings_namespace) != caches_.end();
+}
+
+void StorageFrontend::RunWithStorage(
+ scoped_refptr<const Extension> extension,
+ settings_namespace::Namespace settings_namespace,
+ const ValueStoreCache::StorageCallback& callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ CHECK(extension.get());
+
+ ValueStoreCache* cache = caches_[settings_namespace];
+ CHECK(cache);
+
+ BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ base::Bind(&ValueStoreCache::RunWithValueStoreForExtension,
+ base::Unretained(cache), callback, extension));
+}
+
+void StorageFrontend::DeleteStorageSoon(const std::string& extension_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ for (CacheMap::iterator it = caches_.begin(); it != caches_.end(); ++it) {
+ ValueStoreCache* cache = it->second;
+ BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ base::Bind(&ValueStoreCache::DeleteStorageSoon,
+ base::Unretained(cache),
+ extension_id));
+ }
+}
+
+scoped_refptr<SettingsObserverList> StorageFrontend::GetObservers() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ return observers_;
+}
+
+void StorageFrontend::DisableStorageForTesting(
+ settings_namespace::Namespace settings_namespace) {
+ CacheMap::iterator it = caches_.find(settings_namespace);
+ if (it != caches_.end()) {
+ ValueStoreCache* cache = it->second;
+ cache->ShutdownOnUI();
+ BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, cache);
+ caches_.erase(it);
+ }
+}
+
+// BrowserContextKeyedAPI implementation.
+
+// static
+BrowserContextKeyedAPIFactory<StorageFrontend>*
+StorageFrontend::GetFactoryInstance() {
+ return g_factory.Pointer();
+}
+
+// static
+const char* StorageFrontend::service_name() { return "StorageFrontend"; }
+
+} // namespace extensions