summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjam <jam@chromium.org>2016-03-02 12:34:57 -0800
committerCommit bot <commit-bot@chromium.org>2016-03-02 20:36:00 +0000
commit5af3c81e40aebf43387314e2bc7f18aca80eb178 (patch)
tree7d95fe436cf51873e2b3e4a2ec6bfcdc3781357d
parent6a0ff4c6ae833a8ffdf1aa5f6d3bfe4b31a810c7 (diff)
downloadchromium_src-5af3c81e40aebf43387314e2bc7f18aca80eb178.zip
chromium_src-5af3c81e40aebf43387314e2bc7f18aca80eb178.tar.gz
chromium_src-5af3c81e40aebf43387314e2bc7f18aca80eb178.tar.bz2
Switch LevelDBWrapper::GetAll to use the new Mojo sync IPC mechanism.
Also create LocalStorageCachedArea to mirror the (non-mojo) DOMStorageCachedArea, since there could be several LocalStorageArea objects in a renderer for the same origin and we want just one cache. LocalStorageCachedAreas is a container for all the live LocalStorageCachedArea objects in the renderer. BUG=586194 Review URL: https://codereview.chromium.org/1745603002 Cr-Commit-Position: refs/heads/master@{#378818}
-rw-r--r--content/browser/dom_storage/dom_storage_context_wrapper.cc5
-rw-r--r--content/browser/dom_storage/dom_storage_context_wrapper.h1
-rw-r--r--content/browser/leveldb_wrapper_impl.cc (renamed from content/browser/level_db_wrapper_impl.cc)15
-rw-r--r--content/browser/leveldb_wrapper_impl.h (renamed from content/browser/level_db_wrapper_impl.h)15
-rw-r--r--content/browser/storage_partition_impl.cc4
-rw-r--r--content/browser/storage_partition_impl.h1
-rw-r--r--content/common/leveldb_wrapper.mojom27
-rw-r--r--content/common/storage_partition_service.mojom3
-rw-r--r--content/content_browser.gypi4
-rw-r--r--content/content_renderer.gypi4
-rw-r--r--content/renderer/dom_storage/DEPS2
-rw-r--r--content/renderer/dom_storage/local_storage_area.cc34
-rw-r--r--content/renderer/dom_storage/local_storage_area.h36
-rw-r--r--content/renderer/dom_storage/local_storage_cached_area.cc85
-rw-r--r--content/renderer/dom_storage/local_storage_cached_area.h73
-rw-r--r--content/renderer/dom_storage/local_storage_cached_areas.cc36
-rw-r--r--content/renderer/dom_storage/local_storage_cached_areas.h46
-rw-r--r--content/renderer/dom_storage/local_storage_namespace.cc9
-rw-r--r--content/renderer/dom_storage/local_storage_namespace.h8
-rw-r--r--content/renderer/renderer_blink_platform_impl.cc9
-rw-r--r--content/renderer/renderer_blink_platform_impl.h3
21 files changed, 326 insertions, 94 deletions
diff --git a/content/browser/dom_storage/dom_storage_context_wrapper.cc b/content/browser/dom_storage/dom_storage_context_wrapper.cc
index e58187f..d028d6f 100644
--- a/content/browser/dom_storage/dom_storage_context_wrapper.cc
+++ b/content/browser/dom_storage/dom_storage_context_wrapper.cc
@@ -17,7 +17,7 @@
#include "content/browser/dom_storage/dom_storage_context_impl.h"
#include "content/browser/dom_storage/dom_storage_task_runner.h"
#include "content/browser/dom_storage/session_storage_namespace_impl.h"
-#include "content/browser/level_db_wrapper_impl.h"
+#include "content/browser/leveldb_wrapper_impl.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/local_storage_usage_info.h"
#include "content/public/browser/session_storage_usage_info.h"
@@ -169,7 +169,6 @@ void DOMStorageContextWrapper::Flush() {
void DOMStorageContextWrapper::OpenLocalStorage(
const mojo::String& origin,
- LevelDBObserverPtr observer,
mojo::InterfaceRequest<LevelDBWrapper> request) {
if (level_db_wrappers_.find(origin) == level_db_wrappers_.end()) {
level_db_wrappers_[origin] = make_scoped_ptr(new LevelDBWrapperImpl(
@@ -183,7 +182,7 @@ void DOMStorageContextWrapper::OpenLocalStorage(
// from origins to LevelDBWrapper object. Each call here for the same origin
// should use the same LevelDBWrapper object.
- level_db_wrappers_[origin]->Bind(std::move(request), std::move(observer));
+ level_db_wrappers_[origin]->Bind(std::move(request));
}
void DOMStorageContextWrapper::LevelDBWrapperImplHasNoBindings(
diff --git a/content/browser/dom_storage/dom_storage_context_wrapper.h b/content/browser/dom_storage/dom_storage_context_wrapper.h
index b1aaa8b4..b16b723 100644
--- a/content/browser/dom_storage/dom_storage_context_wrapper.h
+++ b/content/browser/dom_storage/dom_storage_context_wrapper.h
@@ -64,7 +64,6 @@ class CONTENT_EXPORT DOMStorageContextWrapper :
// See StoragePartitionService interface.
void OpenLocalStorage(
const mojo::String& origin,
- LevelDBObserverPtr observer,
mojo::InterfaceRequest<LevelDBWrapper> request);
private:
diff --git a/content/browser/level_db_wrapper_impl.cc b/content/browser/leveldb_wrapper_impl.cc
index d2f1b3e..137e5c4 100644
--- a/content/browser/level_db_wrapper_impl.cc
+++ b/content/browser/leveldb_wrapper_impl.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/browser/level_db_wrapper_impl.h"
+#include "content/browser/leveldb_wrapper_impl.h"
#include "base/bind.h"
@@ -15,14 +15,11 @@ LevelDBWrapperImpl::LevelDBWrapperImpl(
&LevelDBWrapperImpl::OnConnectionError, base::Unretained(this)));
}
-void LevelDBWrapperImpl::Bind(mojo::InterfaceRequest<LevelDBWrapper> request,
- LevelDBObserverPtr observer) {
- // TODO(jam): store observer and call it when changes occur.
+void LevelDBWrapperImpl::Bind(mojo::InterfaceRequest<LevelDBWrapper> request) {
bindings_.AddBinding(this, std::move(request));
}
LevelDBWrapperImpl::~LevelDBWrapperImpl() {
- no_bindings_callback_.Run();
}
void LevelDBWrapperImpl::Put(mojo::Array<uint8_t> key,
@@ -36,15 +33,19 @@ void LevelDBWrapperImpl::Delete(mojo::Array<uint8_t> key,
const DeleteCallback& callback) {
}
-void LevelDBWrapperImpl::DeleteAll(const mojo::String& source,
+void LevelDBWrapperImpl::DeleteAll(LevelDBObserverPtr observer,
+ const mojo::String& source,
const DeleteAllCallback& callback) {
+ // TODO(jam): store observer and call it when changes occur.
}
void LevelDBWrapperImpl::Get(mojo::Array<uint8_t> key,
const GetCallback& callback) {
}
-void LevelDBWrapperImpl::GetAll(const GetAllCallback& callback) {
+void LevelDBWrapperImpl::GetAll(LevelDBObserverPtr observer,
+ const GetAllCallback& callback) {
+ // TODO(jam): store observer and call it when changes occur.
}
void LevelDBWrapperImpl::OnConnectionError() {
diff --git a/content/browser/level_db_wrapper_impl.h b/content/browser/leveldb_wrapper_impl.h
index 06ed348..445fcaa 100644
--- a/content/browser/level_db_wrapper_impl.h
+++ b/content/browser/leveldb_wrapper_impl.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_BROWSER_LEVEL_DB_WRAPPER_IMPL_H_
-#define CONTENT_BROWSER_LEVEL_DB_WRAPPER_IMPL_H_
+#ifndef CONTENT_BROWSER_LEVELDB_WRAPPER_IMPL_H_
+#define CONTENT_BROWSER_LEVELDB_WRAPPER_IMPL_H_
#include "base/callback.h"
#include "base/macros.h"
@@ -28,8 +28,7 @@ class LevelDBWrapperImpl : public LevelDBWrapper {
const base::Closure& no_bindings_callback);
~LevelDBWrapperImpl() override;
- void Bind(mojo::InterfaceRequest<LevelDBWrapper> request,
- LevelDBObserverPtr observer);
+ void Bind(mojo::InterfaceRequest<LevelDBWrapper> request);
private:
// LevelDBWrapperImpl:
@@ -40,10 +39,12 @@ class LevelDBWrapperImpl : public LevelDBWrapper {
void Delete(mojo::Array<uint8_t> key,
const mojo::String& source,
const DeleteCallback& callback) override;
- void DeleteAll(const mojo::String& source,
+ void DeleteAll(LevelDBObserverPtr observer,
+ const mojo::String& source,
const DeleteAllCallback& callback) override;
void Get(mojo::Array<uint8_t> key, const GetCallback& callback) override;
- void GetAll(const GetAllCallback& callback) override;
+ void GetAll(LevelDBObserverPtr observer,
+ const GetAllCallback& callback) override;
void OnConnectionError();
@@ -56,4 +57,4 @@ class LevelDBWrapperImpl : public LevelDBWrapper {
} // namespace content
-#endif // CONTENT_BROWSER_LEVEL_DB_WRAPPER_IMPL_H_
+#endif // CONTENT_BROWSER_LEVELDB_WRAPPER_IMPL_H_
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc
index bf4c1f5..571df26 100644
--- a/content/browser/storage_partition_impl.cc
+++ b/content/browser/storage_partition_impl.cc
@@ -593,10 +593,8 @@ BackgroundSyncContextImpl* StoragePartitionImpl::GetBackgroundSyncContext() {
void StoragePartitionImpl::OpenLocalStorage(
const mojo::String& origin,
- LevelDBObserverPtr observer,
mojo::InterfaceRequest<LevelDBWrapper> request) {
- dom_storage_context_->OpenLocalStorage(origin, std::move(observer),
- std::move(request));
+ dom_storage_context_->OpenLocalStorage(origin, std::move(request));
}
void StoragePartitionImpl::ClearDataImpl(
diff --git a/content/browser/storage_partition_impl.h b/content/browser/storage_partition_impl.h
index fa6904d..de27bc8 100644
--- a/content/browser/storage_partition_impl.h
+++ b/content/browser/storage_partition_impl.h
@@ -67,7 +67,6 @@ class StoragePartitionImpl : public StoragePartition,
// StoragePartitionService interface.
void OpenLocalStorage(
const mojo::String& origin,
- LevelDBObserverPtr observer,
mojo::InterfaceRequest<LevelDBWrapper> request) override;
void ClearDataForOrigin(uint32_t remove_mask,
diff --git a/content/common/leveldb_wrapper.mojom b/content/common/leveldb_wrapper.mojom
index 045b858..32edb09 100644
--- a/content/common/leveldb_wrapper.mojom
+++ b/content/common/leveldb_wrapper.mojom
@@ -6,6 +6,18 @@ module content;
import "components/leveldb/public/interfaces/leveldb.mojom";
+// Gives information about changes to a LevelDB database.
+// The reason this is a parameter to DeleteAll and GetAll below, instead of
+// being specified when opening a LevelDBWrapper, is to avoid the client getting
+// callbacks for changes that have already been applied to its database that
+// it's fetching via GetAll or it's clearing via DeleteAll.
+interface LevelDBObserver {
+ KeyChanged(array<uint8> key, array<uint8> new_value, array<uint8> old_value,
+ string source);
+ KeyDeleted(array<uint8> key, string source);
+ AllDeleted(string source);
+};
+
struct KeyValue {
array<uint8> key;
array<uint8> value;
@@ -24,19 +36,14 @@ interface LevelDBWrapper {
Delete(array<uint8> key, string source) => (leveldb.DatabaseError status);
// Removes all the entries.
- DeleteAll(string source) => (leveldb.DatabaseError status);
+ DeleteAll(LevelDBObserver observer, string source)
+ => (leveldb.DatabaseError status);
// Returns the value of the given key.
Get(array<uint8> key) => (leveldb.DatabaseError status, array<uint8> value);
// Only used with small databases. Returns all key/value pairs.
- GetAll() => (leveldb.DatabaseError status, array<KeyValue> data);
-};
-
-// Gives information about changes to a LevelDB database.
-interface LevelDBObserver {
- KeyChanged(array<uint8> key, array<uint8> new_value, array<uint8> old_value,
- string source);
- KeyDeleted(array<uint8> key, string source);
- AllDeleted(string source);
+ [Sync]
+ GetAll(LevelDBObserver observer)
+ => (leveldb.DatabaseError status, array<KeyValue> data);
};
diff --git a/content/common/storage_partition_service.mojom b/content/common/storage_partition_service.mojom
index 8676114..02c7283 100644
--- a/content/common/storage_partition_service.mojom
+++ b/content/common/storage_partition_service.mojom
@@ -8,6 +8,5 @@ import "content/common/leveldb_wrapper.mojom";
// Returns services related to the current storage partition.
interface StoragePartitionService {
- OpenLocalStorage(string origin, LevelDBObserver observer,
- LevelDBWrapper& database);
+ OpenLocalStorage(string origin, LevelDBWrapper& database);
};
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index ea9b9f8..87cda02 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -947,8 +947,8 @@
'browser/indexed_db/leveldb/leveldb_transaction.h',
'browser/indexed_db/leveldb/leveldb_write_batch.cc',
'browser/indexed_db/leveldb/leveldb_write_batch.h',
- 'browser/level_db_wrapper_impl.cc',
- 'browser/level_db_wrapper_impl.h',
+ 'browser/leveldb_wrapper_impl.cc',
+ 'browser/leveldb_wrapper_impl.h',
'browser/loader/async_resource_handler.cc',
'browser/loader/async_resource_handler.h',
'browser/loader/async_revalidation_driver.cc',
diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi
index 4b6cf8d..11078c4 100644
--- a/content/content_renderer.gypi
+++ b/content/content_renderer.gypi
@@ -186,6 +186,10 @@
'renderer/dom_storage/local_storage_namespace.h',
'renderer/dom_storage/local_storage_area.cc',
'renderer/dom_storage/local_storage_area.h',
+ 'renderer/dom_storage/local_storage_cached_area.cc',
+ 'renderer/dom_storage/local_storage_cached_area.h',
+ 'renderer/dom_storage/local_storage_cached_areas.cc',
+ 'renderer/dom_storage/local_storage_cached_areas.h',
'renderer/dom_storage/webstoragearea_impl.cc',
'renderer/dom_storage/webstoragearea_impl.h',
'renderer/dom_storage/webstoragenamespace_impl.cc',
diff --git a/content/renderer/dom_storage/DEPS b/content/renderer/dom_storage/DEPS
index 4e583a9..b6cda12 100644
--- a/content/renderer/dom_storage/DEPS
+++ b/content/renderer/dom_storage/DEPS
@@ -2,6 +2,8 @@ specific_include_rules = {
'local_storage\.*': [
"-content/renderer",
"+components/leveldb/public/interfaces",
+ "+content/renderer/dom_storage/local_storage_cached_area.h",
+ "+content/renderer/dom_storage/local_storage_cached_areas.h",
"+content/renderer/dom_storage/local_storage_area.h",
"+content/renderer/dom_storage/local_storage_namespace.h",
],
diff --git a/content/renderer/dom_storage/local_storage_area.cc b/content/renderer/dom_storage/local_storage_area.cc
index 1de156f..37e2743 100644
--- a/content/renderer/dom_storage/local_storage_area.cc
+++ b/content/renderer/dom_storage/local_storage_area.cc
@@ -4,7 +4,7 @@
#include "content/renderer/dom_storage/local_storage_area.h"
-#include "content/common/storage_partition_service.mojom.h"
+#include "third_party/WebKit/public/platform/WebURL.h"
using blink::WebString;
using blink::WebURL;
@@ -12,52 +12,40 @@ using blink::WebURL;
namespace content {
LocalStorageArea::LocalStorageArea(
- const url::Origin& origin,
- StoragePartitionService* storage_partition_service)
- : origin_(origin), binding_(this) {
- storage_partition_service->OpenLocalStorage(
- origin_.Serialize(), binding_.CreateInterfacePtrAndBind(),
- mojo::GetProxy(&leveldb_));
+ scoped_refptr<LocalStorageCachedArea> cached_area)
+ : cached_area_(std::move(cached_area)) {
}
LocalStorageArea::~LocalStorageArea() {
}
unsigned LocalStorageArea::length() {
- return 0u;
+ return cached_area_->GetLength();
}
WebString LocalStorageArea::key(unsigned index) {
- return WebString();
+ return cached_area_->GetKey(index);
}
WebString LocalStorageArea::getItem(const WebString& key) {
- return WebString();
+ return cached_area_->GetItem(key);
}
void LocalStorageArea::setItem(
const WebString& key, const WebString& value, const WebURL& page_url,
WebStorageArea::Result& result) {
+ if (!cached_area_->SetItem(key, value, page_url))
+ result = ResultBlockedByQuota;
+ else
+ result = ResultOK;
}
void LocalStorageArea::removeItem(
const WebString& key, const WebURL& page_url) {
+ cached_area_->RemoveItem(key, page_url);
}
void LocalStorageArea::clear(const WebURL& page_url) {
}
-void LocalStorageArea::KeyChanged(mojo::Array<uint8_t> key,
- mojo::Array<uint8_t> new_value,
- mojo::Array<uint8_t> old_value,
- const mojo::String& source) {
-}
-
-void LocalStorageArea::KeyDeleted(mojo::Array<uint8_t> key,
- const mojo::String& source) {
-}
-
-void LocalStorageArea::AllDeleted(const mojo::String& source) {
-}
-
} // namespace content
diff --git a/content/renderer/dom_storage/local_storage_area.h b/content/renderer/dom_storage/local_storage_area.h
index b453315..1da7af0 100644
--- a/content/renderer/dom_storage/local_storage_area.h
+++ b/content/renderer/dom_storage/local_storage_area.h
@@ -6,26 +6,21 @@
#define CONTENT_RENDERER_DOM_STORAGE_LOCAL_STORAGE_AREA_H_
#include "base/macros.h"
-#include "content/common/leveldb_wrapper.mojom.h"
-#include "mojo/public/cpp/bindings/binding.h"
+#include "base/memory/ref_counted.h"
+#include "content/renderer/dom_storage/local_storage_cached_area.h"
#include "third_party/WebKit/public/platform/WebStorageArea.h"
-#include "url/origin.h"
namespace content {
-class StoragePartitionService;
-
-// Maintains a complete cache of the origin's Map of key/value pairs for fast
-// access. The cache is primed on first access and changes are written to the
-// backend through the level db interface pointer. Mutations originating in
-// other processes are applied to the cache via the ApplyMutation method.
-class LocalStorageArea : public blink::WebStorageArea,
- public LevelDBObserver {
+
+// There could be n instances of this class for the same origin in a renderer
+// process. It delegates to the one LocalStorageCachedArea instance in a process
+// for a given origin.
+class LocalStorageArea : public blink::WebStorageArea {
public:
- LocalStorageArea(const url::Origin& origin,
- StoragePartitionService* storage_partition_service);
+ explicit LocalStorageArea(scoped_refptr<LocalStorageCachedArea> cached_area);
~LocalStorageArea() override;
- // blink::WebStorageArea.h:
+ // blink::WebStorageArea:
unsigned length() override;
blink::WebString key(unsigned index) override;
blink::WebString getItem(const blink::WebString& key) override;
@@ -37,19 +32,8 @@ class LocalStorageArea : public blink::WebStorageArea,
const blink::WebURL& page_url) override;
void clear(const blink::WebURL& url) override;
- // LevelDBObserver:
- void KeyChanged(mojo::Array<uint8_t> key,
- mojo::Array<uint8_t> new_value,
- mojo::Array<uint8_t> old_value,
- const mojo::String& source) override;
- void KeyDeleted(mojo::Array<uint8_t> key,
- const mojo::String& source) override;
- void AllDeleted(const mojo::String& source) override;
-
private:
- url::Origin origin_;
- LevelDBWrapperPtr leveldb_;
- mojo::Binding<LevelDBObserver> binding_;
+ scoped_refptr<LocalStorageCachedArea> cached_area_;
DISALLOW_COPY_AND_ASSIGN(LocalStorageArea);
};
diff --git a/content/renderer/dom_storage/local_storage_cached_area.cc b/content/renderer/dom_storage/local_storage_cached_area.cc
new file mode 100644
index 0000000..1c3b2e2
--- /dev/null
+++ b/content/renderer/dom_storage/local_storage_cached_area.cc
@@ -0,0 +1,85 @@
+// Copyright 2016 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 "content/renderer/dom_storage/local_storage_cached_area.h"
+
+#include "content/common/storage_partition_service.mojom.h"
+#include "content/renderer/dom_storage/local_storage_cached_areas.h"
+
+namespace content {
+
+LocalStorageCachedArea::LocalStorageCachedArea(
+ const url::Origin& origin,
+ StoragePartitionService* storage_partition_service,
+ LocalStorageCachedAreas* cached_areas)
+ : loaded_(false), origin_(origin), binding_(this),
+ cached_areas_(cached_areas) {
+ storage_partition_service->OpenLocalStorage(
+ origin_.Serialize(), mojo::GetProxy(&leveldb_));
+}
+
+LocalStorageCachedArea::~LocalStorageCachedArea() {
+ cached_areas_->LocalStorageCacheAreaClosed(this);
+}
+
+unsigned LocalStorageCachedArea::GetLength() {
+ EnsureLoaded();
+ return 0u;
+}
+
+base::NullableString16 LocalStorageCachedArea::GetKey(unsigned index) {
+ EnsureLoaded();
+ return base::NullableString16();
+}
+
+base::NullableString16 LocalStorageCachedArea::GetItem(
+ const base::string16& key) {
+ EnsureLoaded();
+ return base::NullableString16();
+}
+
+bool LocalStorageCachedArea::SetItem(const base::string16& key,
+ const base::string16& value,
+ const GURL& page_url) {
+ EnsureLoaded();
+ return false;
+}
+
+void LocalStorageCachedArea::RemoveItem(const base::string16& key,
+ const GURL& page_url) {
+ EnsureLoaded();
+}
+
+void LocalStorageCachedArea::Clear(const GURL& page_url) {
+ // No need to prime the cache in this case.
+
+ binding_.Close();
+ // TODO:
+ // binding_.CreateInterfacePtrAndBind()
+}
+
+void LocalStorageCachedArea::KeyChanged(mojo::Array<uint8_t> key,
+ mojo::Array<uint8_t> new_value,
+ mojo::Array<uint8_t> old_value,
+ const mojo::String& source) {
+}
+
+void LocalStorageCachedArea::KeyDeleted(mojo::Array<uint8_t> key,
+ const mojo::String& source) {
+}
+
+void LocalStorageCachedArea::AllDeleted(const mojo::String& source) {
+}
+
+void LocalStorageCachedArea::EnsureLoaded() {
+ if (loaded_)
+ return;
+
+ loaded_ = true;
+ leveldb::DatabaseError status = leveldb::DatabaseError::OK;
+ mojo::Array<content::KeyValuePtr> data;
+ leveldb_->GetAll(binding_.CreateInterfacePtrAndBind(), &status, &data);
+}
+
+} // namespace content
diff --git a/content/renderer/dom_storage/local_storage_cached_area.h b/content/renderer/dom_storage/local_storage_cached_area.h
new file mode 100644
index 0000000..4d56bbe
--- /dev/null
+++ b/content/renderer/dom_storage/local_storage_cached_area.h
@@ -0,0 +1,73 @@
+// Copyright 2016 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.
+
+#ifndef CONTENT_RENDERER_DOM_STORAGE_LOCAL_STORAGE_CACHED_AREA_H_
+#define CONTENT_RENDERER_DOM_STORAGE_LOCAL_STORAGE_CACHED_AREA_H_
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/strings/nullable_string16.h"
+#include "content/common/leveldb_wrapper.mojom.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "url/gurl.h"
+#include "url/origin.h"
+
+namespace content {
+class LocalStorageCachedAreas;
+class StoragePartitionService;
+
+// An in-process implementation of LocalStorage using a LevelDB Mojo service.
+// Maintains a complete cache of the origin's Map of key/value pairs for fast
+// access. The cache is primed on first access and changes are written to the
+// backend through the level db interface pointer. Mutations originating in
+// other processes are applied to the cache via LevelDBObserver callbacks.
+class LocalStorageCachedArea : public LevelDBObserver,
+ public base::RefCounted<LocalStorageCachedArea> {
+ public:
+ LocalStorageCachedArea(const url::Origin& origin,
+ StoragePartitionService* storage_partition_service,
+ LocalStorageCachedAreas* cached_areas);
+
+ // These correspond to blink::WebStorageArea.
+ unsigned GetLength();
+ base::NullableString16 GetKey(unsigned index);
+ base::NullableString16 GetItem(const base::string16& key);
+ bool SetItem(const base::string16& key,
+ const base::string16& value,
+ const GURL& page_url);
+ void RemoveItem(const base::string16& key,
+ const GURL& page_url);
+ void Clear(const GURL& page_url);
+
+ const url::Origin& origin() { return origin_; }
+
+ private:
+ friend class base::RefCounted<LocalStorageCachedArea>;
+ ~LocalStorageCachedArea() override;
+
+ // LevelDBObserver:
+ void KeyChanged(mojo::Array<uint8_t> key,
+ mojo::Array<uint8_t> new_value,
+ mojo::Array<uint8_t> old_value,
+ const mojo::String& source) override;
+ void KeyDeleted(mojo::Array<uint8_t> key,
+ const mojo::String& source) override;
+ void AllDeleted(const mojo::String& source) override;
+
+ // Synchronously fetches the origin's local storage data if it hasn't been
+ // fetched already.
+ void EnsureLoaded();
+
+ bool loaded_;
+ url::Origin origin_;
+ LevelDBWrapperPtr leveldb_;
+ mojo::Binding<LevelDBObserver> binding_;
+ LocalStorageCachedAreas* cached_areas_;
+
+ DISALLOW_COPY_AND_ASSIGN(LocalStorageCachedArea);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_DOM_STORAGE_LOCAL_STORAGE_CACHED_AREA_H_
diff --git a/content/renderer/dom_storage/local_storage_cached_areas.cc b/content/renderer/dom_storage/local_storage_cached_areas.cc
new file mode 100644
index 0000000..5918e5a
--- /dev/null
+++ b/content/renderer/dom_storage/local_storage_cached_areas.cc
@@ -0,0 +1,36 @@
+// Copyright 2016 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 "content/renderer/dom_storage/local_storage_cached_areas.h"
+
+#include "content/renderer/dom_storage/local_storage_cached_area.h"
+
+namespace content {
+
+LocalStorageCachedAreas::LocalStorageCachedAreas(
+ StoragePartitionService* storage_partition_service)
+ : storage_partition_service_(storage_partition_service) {
+}
+
+LocalStorageCachedAreas::~LocalStorageCachedAreas() {
+}
+
+scoped_refptr<LocalStorageCachedArea>
+LocalStorageCachedAreas::GetLocalStorageCachedArea(
+ const url::Origin& origin) {
+ if (cached_areas_.find(origin) == cached_areas_.end()) {
+ cached_areas_[origin] = new LocalStorageCachedArea(
+ origin, storage_partition_service_, this);
+ }
+
+ return make_scoped_refptr(cached_areas_[origin]);
+}
+
+void LocalStorageCachedAreas::LocalStorageCacheAreaClosed(
+ LocalStorageCachedArea* cached_area) {
+ DCHECK(cached_areas_.find(cached_area->origin()) != cached_areas_.end());
+ cached_areas_.erase(cached_area->origin());
+}
+
+} // namespace content
diff --git a/content/renderer/dom_storage/local_storage_cached_areas.h b/content/renderer/dom_storage/local_storage_cached_areas.h
new file mode 100644
index 0000000..fba1daa
--- /dev/null
+++ b/content/renderer/dom_storage/local_storage_cached_areas.h
@@ -0,0 +1,46 @@
+// Copyright 2016 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.
+
+#ifndef CONTENT_RENDERER_DOM_STORAGE_LOCAL_STORAGE_CACHED_AREAS_H_
+#define CONTENT_RENDERER_DOM_STORAGE_LOCAL_STORAGE_CACHED_AREAS_H_
+
+#include <map>
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "url/origin.h"
+
+namespace content {
+class LocalStorageCachedArea;
+class StoragePartitionService;
+
+// Owns all the LocalStorageCachedArea objects in a renderer. This is needed
+// because we can have n LocalStorageArea objects for the same origin but we
+// want just one LocalStorageCachedArea to service them (no point in having
+// multiple caches of the same data in the same process).
+class LocalStorageCachedAreas {
+ public:
+ explicit LocalStorageCachedAreas(
+ StoragePartitionService* storage_partition_service);
+ ~LocalStorageCachedAreas();
+
+ scoped_refptr<LocalStorageCachedArea> GetLocalStorageCachedArea(
+ const url::Origin& origin);
+
+ // Called by LocalStorageCachedArea on destruction.
+ void LocalStorageCacheAreaClosed(LocalStorageCachedArea* cached_area);
+
+ private:
+ StoragePartitionService* const storage_partition_service_;
+
+ // Maps from an origin to its LocalStorageCachedArea object. The object owns
+ // itself.
+ std::map<url::Origin, LocalStorageCachedArea*> cached_areas_;
+
+ DISALLOW_COPY_AND_ASSIGN(LocalStorageCachedAreas);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_DOM_STORAGE_LOCAL_STORAGE_CACHED_AREAS_H_
diff --git a/content/renderer/dom_storage/local_storage_namespace.cc b/content/renderer/dom_storage/local_storage_namespace.cc
index 5dd50e4..933b621 100644
--- a/content/renderer/dom_storage/local_storage_namespace.cc
+++ b/content/renderer/dom_storage/local_storage_namespace.cc
@@ -5,7 +5,9 @@
#include "content/renderer/dom_storage/local_storage_namespace.h"
#include "content/renderer/dom_storage/local_storage_area.h"
+#include "content/renderer/dom_storage/local_storage_cached_areas.h"
#include "third_party/WebKit/public/platform/URLConversion.h"
+#include "third_party/WebKit/public/platform/WebURL.h"
#include "url/gurl.h"
#include "url/origin.h"
@@ -16,8 +18,8 @@ using blink::WebString;
namespace content {
LocalStorageNamespace::LocalStorageNamespace(
- StoragePartitionService* storage_partition_service)
- : storage_partition_service_(storage_partition_service) {
+ LocalStorageCachedAreas* local_storage_cached_areas)
+ : local_storage_cached_areas_(local_storage_cached_areas) {
}
LocalStorageNamespace::~LocalStorageNamespace() {
@@ -26,7 +28,8 @@ LocalStorageNamespace::~LocalStorageNamespace() {
WebStorageArea* LocalStorageNamespace::createStorageArea(
const WebString& origin) {
return new LocalStorageArea(
- url::Origin(blink::WebStringToGURL(origin)), storage_partition_service_);
+ local_storage_cached_areas_->GetLocalStorageCachedArea(
+ url::Origin(blink::WebStringToGURL(origin))));
}
bool LocalStorageNamespace::isSameNamespace(
diff --git a/content/renderer/dom_storage/local_storage_namespace.h b/content/renderer/dom_storage/local_storage_namespace.h
index 36b7bd8..08045c5 100644
--- a/content/renderer/dom_storage/local_storage_namespace.h
+++ b/content/renderer/dom_storage/local_storage_namespace.h
@@ -9,13 +9,13 @@
#include "third_party/WebKit/public/platform/WebStorageNamespace.h"
namespace content {
-class StoragePartitionService;
+class LocalStorageCachedAreas;
-// An in-process implementation of LocalStorage using a LevelDB Mojo service.
class LocalStorageNamespace : public blink::WebStorageNamespace {
public:
+ // |local_storage_cached_areas| is guaranteed to outlive this object.
explicit LocalStorageNamespace(
- StoragePartitionService* storage_partition_service);
+ LocalStorageCachedAreas* local_storage_cached_areas);
~LocalStorageNamespace() override;
// blink::WebStorageNamespace:
@@ -24,7 +24,7 @@ class LocalStorageNamespace : public blink::WebStorageNamespace {
bool isSameNamespace(const WebStorageNamespace&) const override;
private:
- StoragePartitionService* const storage_partition_service_;
+ LocalStorageCachedAreas* const local_storage_cached_areas_;
DISALLOW_COPY_AND_ASSIGN(LocalStorageNamespace);
};
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc
index 9389282..cc408ed 100644
--- a/content/renderer/renderer_blink_platform_impl.cc
+++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -57,6 +57,7 @@
#include "content/renderer/device_sensors/device_motion_event_pump.h"
#include "content/renderer/device_sensors/device_orientation_absolute_event_pump.h"
#include "content/renderer/device_sensors/device_orientation_event_pump.h"
+#include "content/renderer/dom_storage/local_storage_cached_areas.h"
#include "content/renderer/dom_storage/local_storage_namespace.h"
#include "content/renderer/dom_storage/webstoragenamespace_impl.h"
#include "content/renderer/gamepad_shared_memory_reader.h"
@@ -414,9 +415,13 @@ void RendererBlinkPlatformImpl::suddenTerminationChanged(bool enabled) {
WebStorageNamespace* RendererBlinkPlatformImpl::createLocalStorageNamespace() {
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kMojoLocalStorage)) {
- return new LocalStorageNamespace(
- RenderThreadImpl::current()->GetStoragePartitionService());
+ if (!local_storage_cached_areas_) {
+ local_storage_cached_areas_.reset(new LocalStorageCachedAreas(
+ RenderThreadImpl::current()->GetStoragePartitionService()));
+ }
+ return new LocalStorageNamespace(local_storage_cached_areas_.get());
}
+
return new WebStorageNamespaceImpl();
}
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h
index c054ee4..8b558d3 100644
--- a/content/renderer/renderer_blink_platform_impl.h
+++ b/content/renderer/renderer_blink_platform_impl.h
@@ -52,6 +52,7 @@ namespace content {
class DeviceLightEventPump;
class DeviceMotionEventPump;
class DeviceOrientationEventPump;
+class LocalStorageCachedAreas;
class PlatformEventObserverBase;
class QuotaMessageFilter;
class RendererClipboardDelegate;
@@ -295,6 +296,8 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
TrialTokenValidator trial_token_validator_;
+ scoped_ptr<LocalStorageCachedAreas> local_storage_cached_areas_;
+
DISALLOW_COPY_AND_ASSIGN(RendererBlinkPlatformImpl);
};