summaryrefslogtreecommitdiffstats
path: root/chrome/browser/in_process_webkit
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/in_process_webkit')
-rw-r--r--chrome/browser/in_process_webkit/dom_storage_context.cc84
-rw-r--r--chrome/browser/in_process_webkit/dom_storage_context.h72
-rw-r--r--chrome/browser/in_process_webkit/dom_storage_dispatcher_host.cc143
-rw-r--r--chrome/browser/in_process_webkit/dom_storage_dispatcher_host.h45
-rw-r--r--chrome/browser/in_process_webkit/storage_area.cc46
-rw-r--r--chrome/browser/in_process_webkit/storage_area.h59
-rw-r--r--chrome/browser/in_process_webkit/storage_namespace.cc95
-rw-r--r--chrome/browser/in_process_webkit/storage_namespace.h60
-rw-r--r--chrome/browser/in_process_webkit/webkit_context.cc19
-rw-r--r--chrome/browser/in_process_webkit/webkit_context.h14
-rw-r--r--chrome/browser/in_process_webkit/webkit_thread.cc19
-rw-r--r--chrome/browser/in_process_webkit/webkit_thread.h5
12 files changed, 511 insertions, 150 deletions
diff --git a/chrome/browser/in_process_webkit/dom_storage_context.cc b/chrome/browser/in_process_webkit/dom_storage_context.cc
new file mode 100644
index 0000000..b22d976
--- /dev/null
+++ b/chrome/browser/in_process_webkit/dom_storage_context.cc
@@ -0,0 +1,84 @@
+// Copyright (c) 2009 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 "chrome/browser/in_process_webkit/dom_storage_context.h"
+
+#include "base/file_path.h"
+#include "chrome/browser/chrome_thread.h"
+#include "chrome/browser/in_process_webkit/storage_area.h"
+#include "chrome/browser/in_process_webkit/storage_namespace.h"
+#include "chrome/browser/in_process_webkit/webkit_context.h"
+
+DOMStorageContext::DOMStorageContext(WebKitContext* webkit_context)
+ : last_storage_area_id_(kFirstStorageAreaId),
+ last_storage_namespace_id_(kFirstStorageNamespaceId),
+ webkit_context_(webkit_context) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
+}
+
+DOMStorageContext::~DOMStorageContext() {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
+ // The storage namespace destructor unregisters the storage namespace, so
+ // our iterator becomes invalid. Thus we just keep deleting the first item
+ // until there are none left.
+ while (!storage_namespace_map_.empty())
+ delete storage_namespace_map_.begin()->second;
+}
+
+StorageNamespace* DOMStorageContext::LocalStorage() {
+ StorageNamespace* storage_namespace = GetStorageNamespace(
+ kLocalStorageNamespaceId);
+ if (storage_namespace)
+ return storage_namespace;
+
+ FilePath data_path = webkit_context_->data_path();
+ FilePath dir_path;
+ if (!data_path.empty())
+ dir_path = data_path.AppendASCII("localStorage");
+ return StorageNamespace::CreateLocalStorageNamespace(this, dir_path);
+}
+
+StorageNamespace* DOMStorageContext::NewSessionStorage() {
+ return StorageNamespace::CreateSessionStorageNamespace(this);
+}
+
+void DOMStorageContext::RegisterStorageArea(StorageArea* storage_area) {
+ int64 id = storage_area->id();
+ DCHECK(!GetStorageArea(id));
+ storage_area_map_[id] = storage_area;
+}
+
+void DOMStorageContext::UnregisterStorageArea(StorageArea* storage_area) {
+ int64 id = storage_area->id();
+ DCHECK(GetStorageArea(id));
+ storage_area_map_.erase(id);
+}
+
+StorageArea* DOMStorageContext::GetStorageArea(int64 id) {
+ StorageAreaMap::iterator iter = storage_area_map_.find(id);
+ if (iter == storage_area_map_.end())
+ return NULL;
+ return iter->second;
+}
+
+void DOMStorageContext::RegisterStorageNamespace(
+ StorageNamespace* storage_namespace) {
+ int64 id = storage_namespace->id();
+ DCHECK(!GetStorageNamespace(id));
+ storage_namespace_map_[id] = storage_namespace;
+}
+
+void DOMStorageContext::UnregisterStorageNamespace(
+ StorageNamespace* storage_namespace) {
+ int64 id = storage_namespace->id();
+ DCHECK(GetStorageNamespace(id));
+ storage_namespace_map_.erase(id);
+}
+
+StorageNamespace* DOMStorageContext::GetStorageNamespace(int64 id) {
+ StorageNamespaceMap::iterator iter = storage_namespace_map_.find(id);
+ if (iter == storage_namespace_map_.end())
+ return NULL;
+ return iter->second;
+}
diff --git a/chrome/browser/in_process_webkit/dom_storage_context.h b/chrome/browser/in_process_webkit/dom_storage_context.h
new file mode 100644
index 0000000..ba26ac2
--- /dev/null
+++ b/chrome/browser/in_process_webkit/dom_storage_context.h
@@ -0,0 +1,72 @@
+// Copyright (c) 2009 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 CHROME_BROWSER_IN_PROCESS_WEBKIT_DOM_STORAGE_CONTEXT_H_
+#define CHROME_BROWSER_IN_PROCESS_WEBKIT_DOM_STORAGE_CONTEXT_H_
+
+#include "base/file_path.h"
+#include "base/hash_tables.h"
+
+class StorageArea;
+class StorageNamespace;
+class WebKitContext;
+
+// This is owned by WebKitContext and is all the dom storage information that's
+// shared by all the ResourceMessageFilter/DOMStorageDispatcherHosts that share
+// the same profile. The specifics of responsibilities are fairly well
+// documented here and in StorageNamespace and StorageArea.
+class DOMStorageContext {
+ public:
+ explicit DOMStorageContext(WebKitContext* webkit_context);
+ ~DOMStorageContext();
+
+ // Get the local storage instance. The pointer is owned by this class.
+ StorageNamespace* LocalStorage();
+
+ // Get a new session storage namespace (but it's still owned by this class).
+ StorageNamespace* NewSessionStorage();
+
+ // Allocate a new storage ___ id.
+ int64 AllocateStorageAreaId() { return ++last_storage_area_id_; }
+ int64 AllocateStorageNamespaceId() { return ++last_storage_namespace_id_; }
+
+ // Various storage area methods. The storage area is owned by one of the
+ // namespaces that's owned by this class.
+ void RegisterStorageArea(StorageArea* storage_area);
+ void UnregisterStorageArea(StorageArea* storage_area);
+ StorageArea* GetStorageArea(int64 id);
+
+ // Get a namespace from an id. What's returned is owned by this class. The
+ // caller of GetStorageNamespace must immediately register itself with the
+ // returned StorageNamespace.
+ void RegisterStorageNamespace(StorageNamespace* storage_namespace);
+ void UnregisterStorageNamespace(StorageNamespace* storage_namespace);
+ StorageNamespace* GetStorageNamespace(int64 id);
+
+ // The special ID used for local storage.
+ static const int64 kLocalStorageNamespaceId = 0;
+
+ private:
+ // The last used storage_area_id and storage_namespace_id's.
+ static const int64 kFirstStorageAreaId = 1;
+ int64 last_storage_area_id_;
+ static const int64 kFirstStorageNamespaceId = 1;
+ int64 last_storage_namespace_id_;
+
+ // We're owned by this WebKit context. Used while instantiating LocalStorage.
+ WebKitContext* webkit_context_;
+
+ // Maps ids to StorageAreas. We do NOT own these objects. StorageNamespace
+ // (which does own them) will notify us when we should remove the entries.
+ typedef base::hash_map<int64, StorageArea*> StorageAreaMap;
+ StorageAreaMap storage_area_map_;
+
+ // Maps ids to StorageNamespaces. We own these objects.
+ typedef base::hash_map<int64, StorageNamespace*> StorageNamespaceMap;
+ StorageNamespaceMap storage_namespace_map_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(DOMStorageContext);
+};
+
+#endif // CHROME_BROWSER_IN_PROCESS_WEBKIT_DOM_STORAGE_CONTEXT_H_
diff --git a/chrome/browser/in_process_webkit/dom_storage_dispatcher_host.cc b/chrome/browser/in_process_webkit/dom_storage_dispatcher_host.cc
index abded7c..bd1ba65 100644
--- a/chrome/browser/in_process_webkit/dom_storage_dispatcher_host.cc
+++ b/chrome/browser/in_process_webkit/dom_storage_dispatcher_host.cc
@@ -5,20 +5,12 @@
#include "chrome/browser/in_process_webkit/dom_storage_dispatcher_host.h"
#include "base/nullable_string16.h"
-#include "base/stl_util-inl.h"
#include "chrome/browser/chrome_thread.h"
-#include "chrome/browser/in_process_webkit/webkit_context.h"
+#include "chrome/browser/in_process_webkit/dom_storage_context.h"
+#include "chrome/browser/in_process_webkit/storage_area.h"
+#include "chrome/browser/in_process_webkit/storage_namespace.h"
#include "chrome/browser/in_process_webkit/webkit_thread.h"
#include "chrome/common/render_messages.h"
-#include "webkit/api/public/WebKit.h"
-#include "webkit/api/public/WebStorageArea.h"
-#include "webkit/api/public/WebStorageNamespace.h"
-#include "webkit/api/public/WebString.h"
-#include "webkit/glue/webkit_glue.h"
-
-using WebKit::WebStorageArea;
-using WebKit::WebStorageNamespace;
-using WebKit::WebString;
DOMStorageDispatcherHost::DOMStorageDispatcherHost(
IPC::Message::Sender* message_sender,
@@ -27,8 +19,6 @@ DOMStorageDispatcherHost::DOMStorageDispatcherHost(
: webkit_context_(webkit_context),
webkit_thread_(webkit_thread),
message_sender_(message_sender),
- last_storage_area_id_(0),
- last_storage_namespace_id_(0),
ever_used_(false),
shutdown_(false) {
DCHECK(webkit_context_.get());
@@ -38,14 +28,13 @@ DOMStorageDispatcherHost::DOMStorageDispatcherHost(
DOMStorageDispatcherHost::~DOMStorageDispatcherHost() {
DCHECK(shutdown_);
- // TODO(jorlow): This sometimes fails on the bots. Why??
- //DCHECK(!ever_used_ || ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
}
void DOMStorageDispatcherHost::Shutdown() {
if (ChromeThread::CurrentlyOn(ChromeThread::IO)) {
message_sender_ = NULL;
if (!ever_used_) {
+ // No need to (possibly) spin up the WebKit thread for a no-op.
shutdown_ = true;
return;
}
@@ -60,12 +49,10 @@ void DOMStorageDispatcherHost::Shutdown() {
DCHECK(ever_used_);
DCHECK(!message_sender_);
DCHECK(!shutdown_);
-
- STLDeleteContainerPairSecondPointers(storage_area_map_.begin(),
- storage_area_map_.end());
- STLDeleteContainerPairSecondPointers(storage_namespace_map_.begin(),
- storage_namespace_map_.end());
shutdown_ = true;
+
+ // TODO(jorlow): If we have any locks, release them here. (Must be on the
+ // WebKit thread.)
}
bool DOMStorageDispatcherHost::OnMessageReceived(const IPC::Message& message,
@@ -127,16 +114,13 @@ void DOMStorageDispatcherHost::OnNamespaceId(bool is_local_storage,
}
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
- WebStorageNamespace* new_namespace;
- if (is_local_storage) {
- new_namespace = WebStorageNamespace::createLocalStorageNamespace(
- GetLocalStoragePath());
- } else {
- new_namespace = WebStorageNamespace::createSessionStorageNamespace();
- }
- int64 new_namespace_id = AddStorageNamespace(new_namespace);
+ StorageNamespace* new_namespace;
+ if (is_local_storage)
+ new_namespace = Context()->LocalStorage();
+ else
+ new_namespace = Context()->NewSessionStorage();
ViewHostMsg_DOMStorageNamespaceId::WriteReplyParams(reply_msg,
- new_namespace_id);
+ new_namespace->id());
Send(reply_msg);
}
@@ -152,12 +136,12 @@ void DOMStorageDispatcherHost::OnCloneNamespaceId(int64 namespace_id,
}
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
- WebStorageNamespace* existing_namespace = GetStorageNamespace(namespace_id);
+ StorageNamespace* existing_namespace =
+ Context()->GetStorageNamespace(namespace_id);
CHECK(existing_namespace); // TODO(jorlow): Do better than this.
- WebStorageNamespace* new_namespace = existing_namespace->copy();
- int64 new_namespace_id = AddStorageNamespace(new_namespace);
+ StorageNamespace* new_namespace = existing_namespace->Copy();
ViewHostMsg_DOMStorageCloneNamespaceId::WriteReplyParams(reply_msg,
- new_namespace_id);
+ new_namespace->id());
Send(reply_msg);
}
@@ -171,7 +155,11 @@ void DOMStorageDispatcherHost::OnDerefNamespaceId(int64 namespace_id) {
}
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
- // TODO(jorlow): We need to track resources so we can free them.
+ StorageNamespace* storage_namespace =
+ Context()->GetStorageNamespace(namespace_id);
+ CHECK(storage_namespace); // TODO(jorlow): Do better than this.
+ // TODO(jorlow): Track resources here so we can free them (even beyond just
+ // when the renderer process dies).
}
void DOMStorageDispatcherHost::OnStorageAreaId(int64 namespace_id,
@@ -187,12 +175,12 @@ void DOMStorageDispatcherHost::OnStorageAreaId(int64 namespace_id,
}
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
- WebStorageNamespace* storage_namespace = GetStorageNamespace(namespace_id);
+ StorageNamespace* storage_namespace =
+ Context()->GetStorageNamespace(namespace_id);
CHECK(storage_namespace); // TODO(jorlow): Do better than this.
- WebStorageArea* storage_area = storage_namespace->createStorageArea(origin);
- int64 storage_area_id = AddStorageArea(storage_area);
+ StorageArea* storage_area = storage_namespace->GetStorageArea(origin);
ViewHostMsg_DOMStorageCloneNamespaceId::WriteReplyParams(reply_msg,
- storage_area_id);
+ storage_area->id());
Send(reply_msg);
}
@@ -206,12 +194,11 @@ void DOMStorageDispatcherHost::OnLock(int64 storage_area_id,
return;
}
- DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
- bool invalidate_cache;
- size_t bytes_left_in_quota;
- WebStorageArea* storage_area = GetStorageArea(storage_area_id);
+ StorageArea* storage_area = Context()->GetStorageArea(storage_area_id);
CHECK(storage_area); // TODO(jorlow): Do better than this.
- storage_area->lock(invalidate_cache, bytes_left_in_quota);
+ // TODO(jorlow): Implement locking, quotas, etc...
+ bool invalidate_cache = true;
+ size_t bytes_left_in_quota = 9999999;
ViewHostMsg_DOMStorageLock::WriteReplyParams(reply_msg, invalidate_cache,
bytes_left_in_quota);
Send(reply_msg);
@@ -227,9 +214,9 @@ void DOMStorageDispatcherHost::OnUnlock(int64 storage_area_id) {
}
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
- WebStorageArea* storage_area = GetStorageArea(storage_area_id);
+ StorageArea* storage_area = Context()->GetStorageArea(storage_area_id);
CHECK(storage_area); // TODO(jorlow): Do better than this.
- storage_area->unlock();
+ // TODO(jorlow): Do something.
}
void DOMStorageDispatcherHost::OnLength(int64 storage_area_id,
@@ -243,9 +230,9 @@ void DOMStorageDispatcherHost::OnLength(int64 storage_area_id,
}
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
- WebStorageArea* storage_area = GetStorageArea(storage_area_id);
+ StorageArea* storage_area = Context()->GetStorageArea(storage_area_id);
CHECK(storage_area); // TODO(jorlow): Do better than this.
- unsigned length = storage_area->length();
+ unsigned length = storage_area->Length();
ViewHostMsg_DOMStorageLength::WriteReplyParams(reply_msg, length);
Send(reply_msg);
}
@@ -261,9 +248,9 @@ void DOMStorageDispatcherHost::OnKey(int64 storage_area_id, unsigned index,
}
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
- WebStorageArea* storage_area = GetStorageArea(storage_area_id);
+ StorageArea* storage_area = Context()->GetStorageArea(storage_area_id);
CHECK(storage_area); // TODO(jorlow): Do better than this.
- const NullableString16& key = storage_area->key(index);
+ const NullableString16& key = storage_area->Key(index);
ViewHostMsg_DOMStorageKey::WriteReplyParams(reply_msg, key);
Send(reply_msg);
}
@@ -281,9 +268,9 @@ void DOMStorageDispatcherHost::OnGetItem(int64 storage_area_id,
}
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
- WebStorageArea* storage_area = GetStorageArea(storage_area_id);
+ StorageArea* storage_area = Context()->GetStorageArea(storage_area_id);
CHECK(storage_area); // TODO(jorlow): Do better than this.
- const NullableString16& value = storage_area->getItem(key);
+ const NullableString16& value = storage_area->GetItem(key);
ViewHostMsg_DOMStorageGetItem::WriteReplyParams(reply_msg, value);
Send(reply_msg);
}
@@ -301,9 +288,9 @@ void DOMStorageDispatcherHost::OnSetItem(int64 storage_area_id,
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
bool quota_exception = false;
- WebStorageArea* storage_area = GetStorageArea(storage_area_id);
+ StorageArea* storage_area = Context()->GetStorageArea(storage_area_id);
CHECK(storage_area); // TODO(jorlow): Do better than this.
- storage_area->setItem(key, value, quota_exception);
+ storage_area->SetItem(key, value, &quota_exception);
DCHECK(!quota_exception); // This is tracked by the renderer.
}
@@ -318,9 +305,9 @@ void DOMStorageDispatcherHost::OnRemoveItem(int64 storage_area_id,
}
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
- WebStorageArea* storage_area = GetStorageArea(storage_area_id);
+ StorageArea* storage_area = Context()->GetStorageArea(storage_area_id);
CHECK(storage_area); // TODO(jorlow): Do better than this.
- storage_area->removeItem(key);
+ storage_area->RemoveItem(key);
}
void DOMStorageDispatcherHost::OnClear(int64 storage_area_id,
@@ -335,51 +322,11 @@ void DOMStorageDispatcherHost::OnClear(int64 storage_area_id,
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
// TODO(jorlow): Return the total quota for this domain.
- size_t bytes_left_in_quota = 0;
- WebStorageArea* storage_area = GetStorageArea(storage_area_id);
+ size_t bytes_left_in_quota = 9999999;
+ StorageArea* storage_area = Context()->GetStorageArea(storage_area_id);
CHECK(storage_area); // TODO(jorlow): Do better than this.
- storage_area->clear();
+ storage_area->Clear();
ViewHostMsg_DOMStorageClear::WriteReplyParams(reply_msg,
bytes_left_in_quota);
Send(reply_msg);
}
-
-WebStorageArea* DOMStorageDispatcherHost::GetStorageArea(int64 id) {
- StorageAreaMap::iterator iterator = storage_area_map_.find(id);
- if (iterator == storage_area_map_.end())
- return NULL;
- return iterator->second;
-}
-
-WebStorageNamespace* DOMStorageDispatcherHost::GetStorageNamespace(int64 id) {
- StorageNamespaceMap::iterator iterator = storage_namespace_map_.find(id);
- if (iterator == storage_namespace_map_.end())
- return NULL;
- return iterator->second;
-}
-
-int64 DOMStorageDispatcherHost::AddStorageArea(
- WebStorageArea* new_storage_area) {
- // Create a new ID and insert it into our map.
- int64 new_storage_area_id = ++last_storage_area_id_;
- DCHECK(!GetStorageArea(new_storage_area_id));
- storage_area_map_[new_storage_area_id] = new_storage_area;
- return new_storage_area_id;
-}
-
-int64 DOMStorageDispatcherHost::AddStorageNamespace(
- WebStorageNamespace* new_namespace) {
- // Create a new ID and insert it into our map.
- int64 new_namespace_id = ++last_storage_namespace_id_;
- DCHECK(!GetStorageNamespace(new_namespace_id));
- storage_namespace_map_[new_namespace_id] = new_namespace;
- return new_namespace_id;
-}
-
-WebString DOMStorageDispatcherHost::GetLocalStoragePath() {
- const FilePath& path = webkit_context_->data_path();
- if (path.empty())
- return WebString();
- FilePath::StringType path_string = path.AppendASCII("localStorage").value();
- return webkit_glue::FilePathStringToWebString(path_string);
-}
diff --git a/chrome/browser/in_process_webkit/dom_storage_dispatcher_host.h b/chrome/browser/in_process_webkit/dom_storage_dispatcher_host.h
index c9a6039..72b061f 100644
--- a/chrome/browser/in_process_webkit/dom_storage_dispatcher_host.h
+++ b/chrome/browser/in_process_webkit/dom_storage_dispatcher_host.h
@@ -7,18 +7,13 @@
#include "base/hash_tables.h"
#include "base/ref_counted.h"
-#include "base/scoped_ptr.h"
+#include "chrome/browser/in_process_webkit/storage_area.h"
+#include "chrome/browser/in_process_webkit/webkit_context.h"
#include "ipc/ipc_message.h"
-class WebKitContext;
+class DOMStorageContext;
class WebKitThread;
-namespace WebKit {
-class WebStorageArea;
-class WebStorageNamespace;
-class WebString;
-}
-
// This class handles the logistics of DOM Storage within the browser process.
// It mostly ferries information between IPCs and the WebKit implementations,
// but it also handles some special cases like when renderer processes die.
@@ -58,19 +53,11 @@ class DOMStorageDispatcherHost :
void OnRemoveItem(int64 storage_area_id, const string16& key);
void OnClear(int64 storage_area_id, IPC::Message* reply_msg);
- // Get a WebStorageNamespace or WebStorageArea based from its ID. Only call
- // on the WebKit thread.
- WebKit::WebStorageArea* GetStorageArea(int64 id);
- WebKit::WebStorageNamespace* GetStorageNamespace(int64 id);
-
- // Add a WebStorageNamespace or WebStorageArea and get a new unique ID for
- // it. Only call on the WebKit thread.
- int64 AddStorageArea(WebKit::WebStorageArea* new_storage_area);
- int64 AddStorageNamespace(WebKit::WebStorageNamespace* new_namespace);
-
- // Get the path to the LocalStorage directory. Calculate it if we haven't
- // already. Only call on the WebKit thread.
- WebKit::WebString GetLocalStoragePath();
+ // A shortcut for accessing our context.
+ DOMStorageContext* Context() {
+ DCHECK(!shutdown_);
+ return webkit_context_->GetDOMStorageContext();
+ }
// Data shared between renderer processes with the same profile.
scoped_refptr<WebKitContext> webkit_context_;
@@ -81,22 +68,6 @@ class DOMStorageDispatcherHost :
// Only set on the IO thread.
IPC::Message::Sender* message_sender_;
- // The last used storage_area_id and storage_namespace_id's. Only use on the
- // WebKit thread.
- int64 last_storage_area_id_;
- int64 last_storage_namespace_id_;
-
- // Used to maintain a mapping between storage_area_id's used in IPC messages
- // and the actual WebStorageArea instances. Only use on the WebKit thread.
- typedef base::hash_map<int64, WebKit::WebStorageArea*> StorageAreaMap;
- StorageAreaMap storage_area_map_;
-
- // Mapping between storage_namespace_id's used in IPC messages and the
- // WebStorageNamespace instances. Only use on the WebKit thread.
- typedef base::hash_map<int64, WebKit::WebStorageNamespace*>
- StorageNamespaceMap;
- StorageNamespaceMap storage_namespace_map_;
-
// Has this dispatcher ever handled a message. If not, then we can skip
// the entire shutdown procedure. This is only set to true on the IO thread
// and must be true if we're reading it on the WebKit thread.
diff --git a/chrome/browser/in_process_webkit/storage_area.cc b/chrome/browser/in_process_webkit/storage_area.cc
new file mode 100644
index 0000000..11369c5
--- /dev/null
+++ b/chrome/browser/in_process_webkit/storage_area.cc
@@ -0,0 +1,46 @@
+// Copyright (c) 2009 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 "chrome/browser/in_process_webkit/storage_area.h"
+
+#include "chrome/browser/in_process_webkit/dom_storage_dispatcher_host.h"
+#include "webkit/api/public/WebStorageArea.h"
+#include "webkit/api/public/WebString.h"
+
+using WebKit::WebStorageArea;
+
+StorageArea::StorageArea(const string16& origin, WebStorageArea* storage_area,
+ int64 id)
+ : origin_(origin),
+ storage_area_(storage_area),
+ id_(id) {
+}
+
+StorageArea::~StorageArea() {
+}
+
+unsigned StorageArea::Length() {
+ return storage_area_->length();
+}
+
+NullableString16 StorageArea::Key(unsigned index) {
+ return storage_area_->key(index);
+}
+
+NullableString16 StorageArea::GetItem(const string16& key) {
+ return storage_area_->getItem(key);
+}
+
+void StorageArea::SetItem(const string16& key, const string16& value,
+ bool* quota_exception) {
+ storage_area_->setItem(key, value, *quota_exception);
+}
+
+void StorageArea::RemoveItem(const string16& key) {
+ storage_area_->removeItem(key);
+}
+
+void StorageArea::Clear() {
+ storage_area_->clear();
+}
diff --git a/chrome/browser/in_process_webkit/storage_area.h b/chrome/browser/in_process_webkit/storage_area.h
new file mode 100644
index 0000000..d6c6615
--- /dev/null
+++ b/chrome/browser/in_process_webkit/storage_area.h
@@ -0,0 +1,59 @@
+// Copyright (c) 2009 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 CHROME_BROWSER_IN_PROCESS_WEBKIT_STORAGE_AREA_H_
+#define CHROME_BROWSER_IN_PROCESS_WEBKIT_STORAGE_AREA_H_
+
+#include "base/hash_tables.h"
+#include "base/nullable_string16.h"
+
+namespace WebKit {
+class WebStorageArea;
+}
+
+// Only use on the WebKit thread. StorageNamespace manages our registration
+// with DOMStorageContext.
+class StorageArea {
+ public:
+ StorageArea(const string16& origin, WebKit::WebStorageArea* storage_area,
+ int64 id);
+ ~StorageArea();
+
+ unsigned Length();
+ NullableString16 Key(unsigned index);
+ NullableString16 GetItem(const string16& key);
+ void SetItem(const string16& key, const string16& value,
+ bool* quota_xception);
+ void RemoveItem(const string16& key);
+ void Clear();
+
+ int64 id() const { return id_; }
+
+ private:
+ // The origin this storage area represents.
+ string16 origin_;
+
+ // The storage area we wrap.
+ WebKit::WebStorageArea* storage_area_;
+
+ // Our storage area id. Unique to our parent WebKitContext.
+ int64 id_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(StorageArea);
+};
+
+#if defined(COMPILER_GCC)
+namespace __gnu_cxx {
+
+template<>
+struct hash<StorageArea*> {
+ std::size_t operator()(StorageArea* const& p) const {
+ return reinterpret_cast<std::size_t>(p);
+ }
+};
+
+} // namespace __gnu_cxx
+#endif
+
+#endif // CHROME_BROWSER_IN_PROCESS_WEBKIT_STORAGE_AREA_H_
diff --git a/chrome/browser/in_process_webkit/storage_namespace.cc b/chrome/browser/in_process_webkit/storage_namespace.cc
new file mode 100644
index 0000000..25548c3
--- /dev/null
+++ b/chrome/browser/in_process_webkit/storage_namespace.cc
@@ -0,0 +1,95 @@
+// Copyright (c) 2009 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 "chrome/browser/in_process_webkit/storage_namespace.h"
+
+#include "base/file_path.h"
+#include "chrome/browser/in_process_webkit/dom_storage_context.h"
+#include "chrome/browser/in_process_webkit/dom_storage_dispatcher_host.h"
+#include "chrome/browser/in_process_webkit/storage_area.h"
+#include "webkit/api/public/WebStorageArea.h"
+#include "webkit/api/public/WebStorageNamespace.h"
+#include "webkit/api/public/WebString.h"
+#include "webkit/glue/webkit_glue.h"
+
+using WebKit::WebStorageArea;
+using WebKit::WebStorageNamespace;
+using WebKit::WebString;
+
+/* static */
+StorageNamespace* StorageNamespace::CreateLocalStorageNamespace(
+ DOMStorageContext* dom_storage_context, const FilePath& dir_path) {
+ int64 id = dom_storage_context->kLocalStorageNamespaceId;
+ DCHECK(!dom_storage_context->GetStorageNamespace(id));
+ WebString path = webkit_glue::FilePathToWebString(dir_path);
+ WebStorageNamespace* web_storage_namespace =
+ WebStorageNamespace::createLocalStorageNamespace(path);
+ return new StorageNamespace(dom_storage_context, web_storage_namespace, id,
+ true);
+}
+
+/* static */
+StorageNamespace* StorageNamespace::CreateSessionStorageNamespace(
+ DOMStorageContext* dom_storage_context) {
+ int64 id = dom_storage_context->AllocateStorageNamespaceId();
+ DCHECK(!dom_storage_context->GetStorageNamespace(id));
+ WebStorageNamespace* web_storage_namespace =
+ WebStorageNamespace::createSessionStorageNamespace();
+ return new StorageNamespace(dom_storage_context, web_storage_namespace, id,
+ false);
+}
+
+StorageNamespace::StorageNamespace(DOMStorageContext* dom_storage_context,
+ WebStorageNamespace* storage_namespace,
+ int64 id, bool is_local_storage)
+ : dom_storage_context_(dom_storage_context),
+ storage_namespace_(storage_namespace),
+ id_(id),
+ is_local_storage_(is_local_storage) {
+ DCHECK(dom_storage_context_);
+ DCHECK(storage_namespace_);
+ dom_storage_context_->RegisterStorageNamespace(this);
+}
+
+StorageNamespace::~StorageNamespace() {
+ dom_storage_context_->UnregisterStorageNamespace(this);
+
+ OriginToStorageAreaMap::iterator iter = origin_to_storage_area_.begin();
+ OriginToStorageAreaMap::iterator end = origin_to_storage_area_.end();
+ while (iter != end) {
+ dom_storage_context_->UnregisterStorageArea(iter->second);
+ delete iter->second;
+ ++iter;
+ }
+}
+
+StorageArea* StorageNamespace::GetStorageArea(const string16& origin) {
+ // We may have already created it for another dispatcher host.
+ OriginToStorageAreaMap::iterator iter = origin_to_storage_area_.find(origin);
+ if (iter != origin_to_storage_area_.end())
+ return iter->second;
+
+ // We need to create a new one.
+ int64 id = dom_storage_context_->AllocateStorageAreaId();
+ DCHECK(!dom_storage_context_->GetStorageArea(id));
+ WebStorageArea* web_storage_area =
+ storage_namespace_->createStorageArea(origin);
+ StorageArea* storage_area = new StorageArea(origin, web_storage_area, id);
+ origin_to_storage_area_[origin] = storage_area;
+ dom_storage_context_->RegisterStorageArea(storage_area);
+ return storage_area;
+}
+
+StorageNamespace* StorageNamespace::Copy() {
+ DCHECK(!is_local_storage_);
+ int64 id = dom_storage_context_->AllocateStorageNamespaceId();
+ DCHECK(!dom_storage_context_->GetStorageNamespace(id));
+ WebStorageNamespace* new_storage_namespace = storage_namespace_->copy();
+ return new StorageNamespace(dom_storage_context_, new_storage_namespace, id,
+ is_local_storage_);
+}
+
+void StorageNamespace::Close() {
+ storage_namespace_->close();
+}
diff --git a/chrome/browser/in_process_webkit/storage_namespace.h b/chrome/browser/in_process_webkit/storage_namespace.h
new file mode 100644
index 0000000..4018f8f
--- /dev/null
+++ b/chrome/browser/in_process_webkit/storage_namespace.h
@@ -0,0 +1,60 @@
+// Copyright (c) 2009 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 CHROME_BROWSER_IN_PROCESS_WEBKIT_STORAGE_NAMESPACE_H_
+#define CHROME_BROWSER_IN_PROCESS_WEBKIT_STORAGE_NAMESPACE_H_
+
+#include "base/string16.h"
+#include "base/hash_tables.h"
+
+class DOMStorageContext;
+class FilePath;
+class StorageArea;
+
+namespace WebKit {
+class WebStorageNamespace;
+}
+
+// Only to be used on the WebKit thread.
+class StorageNamespace {
+ public:
+ static StorageNamespace* CreateLocalStorageNamespace(
+ DOMStorageContext* dom_storage_context, const FilePath& data_dir_path);
+ static StorageNamespace* CreateSessionStorageNamespace(
+ DOMStorageContext* dom_storage_context);
+
+ ~StorageNamespace();
+
+ StorageArea* GetStorageArea(const string16& origin);
+ StorageNamespace* Copy();
+ void Close();
+
+ int64 id() const { return id_; }
+
+ private:
+ // Called by the static factory methods above.
+ StorageNamespace(DOMStorageContext* dom_storage_context,
+ WebKit::WebStorageNamespace* web_storage_namespace,
+ int64 id, bool is_local_storage);
+
+ // All the storage areas we own.
+ typedef base::hash_map<string16, StorageArea*> OriginToStorageAreaMap;
+ OriginToStorageAreaMap origin_to_storage_area_;
+
+ // The DOMStorageContext that owns us.
+ DOMStorageContext* dom_storage_context_;
+
+ // The WebKit storage namespace we manage.
+ WebKit::WebStorageNamespace* storage_namespace_;
+
+ // Our id. Unique to our parent WebKitContext class.
+ int64 id_;
+
+ // Is this a local storage namespace.
+ bool is_local_storage_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(StorageNamespace);
+};
+
+#endif // CHROME_BROWSER_IN_PROCESS_WEBKIT_STORAGE_NAMESPACE_H_
diff --git a/chrome/browser/in_process_webkit/webkit_context.cc b/chrome/browser/in_process_webkit/webkit_context.cc
index e7d7d1a..ae647d6 100644
--- a/chrome/browser/in_process_webkit/webkit_context.cc
+++ b/chrome/browser/in_process_webkit/webkit_context.cc
@@ -4,10 +4,29 @@
#include "chrome/browser/in_process_webkit/webkit_context.h"
+#include "chrome/browser/chrome_thread.h"
+#include "chrome/browser/in_process_webkit/dom_storage_context.h"
+
WebKitContext::WebKitContext(const FilePath& data_path, bool is_incognito)
: data_path_(data_path),
is_incognito_(is_incognito) {
}
WebKitContext::~WebKitContext() {
+ // If a dom storage context was ever created, we need to destroy it on the
+ // WebKit thread. Luckily we're guaranteed that the WebKit thread is still
+ // alive since the ResourceDispatcherHost (which owns the WebKit thread) goes
+ // away after all the ResourceMessageFilters and the profiles (i.e. all the
+ // objects with a reference to us).
+ if (dom_storage_context_.get()) {
+ MessageLoop* loop = ChromeThread::GetMessageLoop(ChromeThread::WEBKIT);
+ loop->DeleteSoon(FROM_HERE, dom_storage_context_.release());
+ }
+}
+
+DOMStorageContext* WebKitContext::GetDOMStorageContext() {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
+ if (!dom_storage_context_.get())
+ dom_storage_context_.reset(new DOMStorageContext(this));
+ return dom_storage_context_.get();
}
diff --git a/chrome/browser/in_process_webkit/webkit_context.h b/chrome/browser/in_process_webkit/webkit_context.h
index 2b84224..ee4c61b 100644
--- a/chrome/browser/in_process_webkit/webkit_context.h
+++ b/chrome/browser/in_process_webkit/webkit_context.h
@@ -7,6 +7,9 @@
#include "base/file_path.h"
#include "base/ref_counted.h"
+#include "base/scoped_ptr.h"
+
+class DOMStorageContext;
// There's one WebKitContext per profile. Various DispatcherHost classes
// have a pointer to the Context to store shared state.
@@ -17,12 +20,19 @@ class WebKitContext : public base::RefCountedThreadSafe<WebKitContext> {
const FilePath& data_path() const { return data_path_; }
bool is_incognito() const { return is_incognito_; }
+ // Initialized lazily. Pointer is valid for the lifetime of this instance.
+ DOMStorageContext* GetDOMStorageContext();
+
private:
friend class base::RefCountedThreadSafe<WebKitContext>;
~WebKitContext();
- FilePath data_path_;
- bool is_incognito_;
+ // Copies of profile data that can be accessed on any thread.
+ const FilePath data_path_;
+ const bool is_incognito_;
+
+ // The state for DOM Storage.
+ scoped_ptr<DOMStorageContext> dom_storage_context_;
DISALLOW_IMPLICIT_CONSTRUCTORS(WebKitContext);
};
diff --git a/chrome/browser/in_process_webkit/webkit_thread.cc b/chrome/browser/in_process_webkit/webkit_thread.cc
index 96384e9..46b62f4 100644
--- a/chrome/browser/in_process_webkit/webkit_thread.cc
+++ b/chrome/browser/in_process_webkit/webkit_thread.cc
@@ -27,8 +27,6 @@ void WebKitThread::Shutdown() {
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
DCHECK(io_message_loop_);
- // TODO(jorlow): Start flushing LocalStorage?
-
AutoLock lock(io_message_loop_lock_);
io_message_loop_ = NULL;
}
@@ -48,24 +46,23 @@ bool WebKitThread::PostIOThreadTask(
}
WebKitThread::InternalWebKitThread::InternalWebKitThread()
- : ChromeThread(ChromeThread::WEBKIT),
- webkit_client_(NULL) {
+ : ChromeThread(ChromeThread::WEBKIT) {
+}
+
+WebKitThread::InternalWebKitThread::~InternalWebKitThread() {
}
void WebKitThread::InternalWebKitThread::Init() {
- DCHECK(!webkit_client_);
- webkit_client_ = new BrowserWebKitClientImpl;
- DCHECK(webkit_client_);
- WebKit::initialize(webkit_client_);
+ DCHECK(!webkit_client_.get());
+ webkit_client_.reset(new BrowserWebKitClientImpl);
+ WebKit::initialize(webkit_client_.get());
// If possible, post initialization tasks to this thread (rather than doing
// them now) so we don't block the IO thread any longer than we have to.
}
void WebKitThread::InternalWebKitThread::CleanUp() {
- // TODO(jorlow): Block on LocalStorage being 100% shut down.
- DCHECK(webkit_client_);
+ DCHECK(webkit_client_.get());
WebKit::shutdown();
- delete webkit_client_;
}
MessageLoop* WebKitThread::InitializeThread() {
diff --git a/chrome/browser/in_process_webkit/webkit_thread.h b/chrome/browser/in_process_webkit/webkit_thread.h
index 8ab1113..828277c 100644
--- a/chrome/browser/in_process_webkit/webkit_thread.h
+++ b/chrome/browser/in_process_webkit/webkit_thread.h
@@ -49,14 +49,15 @@ class WebKitThread {
class InternalWebKitThread : public ChromeThread {
public:
InternalWebKitThread();
- virtual ~InternalWebKitThread() { }
+ virtual ~InternalWebKitThread();
// Does the actual initialization and shutdown of WebKit. Called at the
// beginning and end of the thread's lifetime.
virtual void Init();
virtual void CleanUp();
private:
- BrowserWebKitClientImpl* webkit_client_;
+ // The WebKitClient implementation. Only access on WebKit thread.
+ scoped_ptr<BrowserWebKitClientImpl> webkit_client_;
};
// Returns the WebKit thread's message loop or NULL if we're in