Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1840)

Unified Diff: chrome/browser/in_process_webkit/dom_storage_dispatcher_host.cc

Issue 155845: DOM Storage: Add browser-process IPC code + tweak the WebKit Thread. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/in_process_webkit/dom_storage_dispatcher_host.cc
===================================================================
--- chrome/browser/in_process_webkit/dom_storage_dispatcher_host.cc (revision 21342)
+++ chrome/browser/in_process_webkit/dom_storage_dispatcher_host.cc (working copy)
@@ -4,34 +4,98 @@
#include "chrome/browser/in_process_webkit/dom_storage_dispatcher_host.h"
+#include "base/stl_util-inl.h"
+#include "base/string16.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/in_process_webkit/webkit_context.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"
+using WebKit::WebStorageArea;
+using WebKit::WebStorageNamespace;
+
DOMStorageDispatcherHost::DOMStorageDispatcherHost(
IPC::Message::Sender* message_sender,
WebKitContext* webkit_context,
WebKitThread* webkit_thread)
: webkit_context_(webkit_context),
webkit_thread_(webkit_thread),
- message_sender_(message_sender) {
+ message_sender_(message_sender),
+ last_storage_area_id_(0),
+ last_storage_namespace_id_(0),
+ ever_used_(false),
+ shutdown_(false) {
DCHECK(webkit_context_.get());
DCHECK(webkit_thread_);
DCHECK(message_sender_);
}
DOMStorageDispatcherHost::~DOMStorageDispatcherHost() {
- DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
- message_sender_ = NULL;
+ DCHECK(!ever_used_ || ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
+ DCHECK(shutdown_);
}
-bool DOMStorageDispatcherHost::OnMessageReceived(const IPC::Message& msg) {
- // TODO(jorlow): Implement DOM Storage's message handler...and the rest
- // of DOM Storage. :-)
- return false;
+void DOMStorageDispatcherHost::Shutdown() {
+ if (ChromeThread::CurrentlyOn(ChromeThread::IO)) {
+ message_sender_ = NULL;
+ if (!ever_used_) {
+ shutdown_ = true;
+ return;
+ }
+
+ MessageLoop* webkit_loop = webkit_thread_->GetMessageLoop();
+ webkit_loop->PostTask(FROM_HERE, NewRunnableMethod(this,
+ &DOMStorageDispatcherHost::Shutdown));
+ return;
+ }
+
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
+ 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;
}
+bool DOMStorageDispatcherHost::OnMessageReceived(const IPC::Message& message,
+ bool *msg_is_ok) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
+ DCHECK(!shutdown_);
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP_EX(DOMStorageDispatcherHost, message, *msg_is_ok)
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_DOMStorageNamespaceId,
+ OnNamespaceId)
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_DOMStorageCloneNamespaceId,
+ OnCloneNamespaceId)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_DOMStorageDerefNamespaceId,
+ OnDerefNamespaceId)
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_DOMStorageStorageAreaId,
+ OnStorageAreaId)
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_DOMStorageLock, OnLock)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_DOMStorageUnlock, OnUnlock)
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_DOMStorageLength, OnLength)
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_DOMStorageKey, OnKey)
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_DOMStorageGetItem, OnGetItem)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_DOMStorageSetItem, OnSetItem)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_DOMStorageRemoveItem, OnRemoveItem)
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_DOMStorageClear, OnClear)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ if (handled)
+ ever_used_ = true;
+ return handled;
+}
+
void DOMStorageDispatcherHost::Send(IPC::Message* message) {
+ DCHECK(!shutdown_);
if (!message_sender_) {
delete message;
return;
@@ -42,11 +106,277 @@
return;
}
- // The IO thread can't dissapear while the WebKit thread is still running.
+ // The IO thread can't go away while the WebKit thread is still running.
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
- MessageLoop* io_loop = ChromeThread::GetMessageLoop(ChromeThread::IO);
- CancelableTask* task = NewRunnableMethod(this,
- &DOMStorageDispatcherHost::Send,
- message);
- io_loop->PostTask(FROM_HERE, task);
+ webkit_thread_->PostIOThreadTask(FROM_HERE, NewRunnableMethod(this,
+ &DOMStorageDispatcherHost::Send, message));
}
+
+void DOMStorageDispatcherHost::OnNamespaceId(bool is_local_storage,
+ IPC::Message* reply_msg) {
+ DCHECK(!shutdown_);
+ if (ChromeThread::CurrentlyOn(ChromeThread::IO)) {
+ MessageLoop* webkit_loop = webkit_thread_->GetMessageLoop();
+ webkit_loop->PostTask(FROM_HERE, NewRunnableMethod(this,
+ &DOMStorageDispatcherHost::OnNamespaceId,
+ is_local_storage, reply_msg));
+ return;
+ }
+
+ 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);
+ ViewHostMsg_DOMStorageNamespaceId::WriteReplyParams(reply_msg,
+ new_namespace_id);
+ Send(reply_msg);
+}
+
+void DOMStorageDispatcherHost::OnCloneNamespaceId(int64 namespace_id,
+ IPC::Message* reply_msg) {
+ DCHECK(!shutdown_);
+ if (ChromeThread::CurrentlyOn(ChromeThread::IO)) {
+ MessageLoop* webkit_loop = webkit_thread_->GetMessageLoop();
+ webkit_loop->PostTask(FROM_HERE, NewRunnableMethod(this,
+ &DOMStorageDispatcherHost::OnCloneNamespaceId,
+ namespace_id, reply_msg));
+ return;
+ }
+
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
+ WebStorageNamespace* existing_namespace = 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);
+ ViewHostMsg_DOMStorageCloneNamespaceId::WriteReplyParams(reply_msg,
+ new_namespace_id);
+ Send(reply_msg);
+}
+
+void DOMStorageDispatcherHost::OnDerefNamespaceId(int64 namespace_id) {
+ DCHECK(!shutdown_);
+ if (ChromeThread::CurrentlyOn(ChromeThread::IO)) {
+ MessageLoop* webkit_loop = webkit_thread_->GetMessageLoop();
+ webkit_loop->PostTask(FROM_HERE, NewRunnableMethod(this,
+ &DOMStorageDispatcherHost::OnDerefNamespaceId, namespace_id));
+ return;
+ }
+
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
+ // TODO(jorlow): We need to track resources so we can free them.
+}
+
+void DOMStorageDispatcherHost::OnStorageAreaId(int64 namespace_id,
+ const string16& origin,
+ IPC::Message* reply_msg) {
+ DCHECK(!shutdown_);
+ if (ChromeThread::CurrentlyOn(ChromeThread::IO)) {
+ MessageLoop* webkit_loop = webkit_thread_->GetMessageLoop();
+ webkit_loop->PostTask(FROM_HERE, NewRunnableMethod(this,
+ &DOMStorageDispatcherHost::OnStorageAreaId,
+ namespace_id, origin, reply_msg));
+ return;
+ }
+
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
+ WebStorageNamespace* storage_namespace = 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);
+ ViewHostMsg_DOMStorageCloneNamespaceId::WriteReplyParams(reply_msg,
+ storage_area_id);
+ Send(reply_msg);
+}
+
+void DOMStorageDispatcherHost::OnLock(int64 storage_area_id,
+ IPC::Message* reply_msg) {
+ DCHECK(!shutdown_);
+ if (ChromeThread::CurrentlyOn(ChromeThread::IO)) {
+ MessageLoop* webkit_loop = webkit_thread_->GetMessageLoop();
+ webkit_loop->PostTask(FROM_HERE, NewRunnableMethod(this,
+ &DOMStorageDispatcherHost::OnLock, storage_area_id, reply_msg));
+ return;
+ }
+
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
+ bool invalidate_cache;
+ size_t bytes_left_in_quota;
+ WebStorageArea* storage_area = GetStorageArea(storage_area_id);
+ CHECK(storage_area); // TODO(jorlow): Do better than this.
+ storage_area->lock(invalidate_cache, bytes_left_in_quota);
+ ViewHostMsg_DOMStorageLock::WriteReplyParams(reply_msg, invalidate_cache,
+ bytes_left_in_quota);
+ Send(reply_msg);
+}
+
+void DOMStorageDispatcherHost::OnUnlock(int64 storage_area_id) {
+ DCHECK(!shutdown_);
+ if (ChromeThread::CurrentlyOn(ChromeThread::IO)) {
+ MessageLoop* webkit_loop = webkit_thread_->GetMessageLoop();
+ webkit_loop->PostTask(FROM_HERE, NewRunnableMethod(this,
+ &DOMStorageDispatcherHost::OnUnlock, storage_area_id));
+ return;
+ }
+
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
+ WebStorageArea* storage_area = GetStorageArea(storage_area_id);
+ CHECK(storage_area); // TODO(jorlow): Do better than this.
+ storage_area->unlock();
+}
+
+void DOMStorageDispatcherHost::OnLength(int64 storage_area_id,
+ IPC::Message* reply_msg) {
+ DCHECK(!shutdown_);
+ if (ChromeThread::CurrentlyOn(ChromeThread::IO)) {
+ MessageLoop* webkit_loop = webkit_thread_->GetMessageLoop();
+ webkit_loop->PostTask(FROM_HERE, NewRunnableMethod(this,
+ &DOMStorageDispatcherHost::OnLength, storage_area_id, reply_msg));
+ return;
+ }
+
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
+ WebStorageArea* storage_area = GetStorageArea(storage_area_id);
+ CHECK(storage_area); // TODO(jorlow): Do better than this.
+ unsigned length = storage_area->length();
+ ViewHostMsg_DOMStorageLength::WriteReplyParams(reply_msg, length);
+ Send(reply_msg);
+}
+
+void DOMStorageDispatcherHost::OnKey(int64 storage_area_id, unsigned index,
+ IPC::Message* reply_msg) {
+ DCHECK(!shutdown_);
+ if (ChromeThread::CurrentlyOn(ChromeThread::IO)) {
+ MessageLoop* webkit_loop = webkit_thread_->GetMessageLoop();
+ webkit_loop->PostTask(FROM_HERE, NewRunnableMethod(this,
+ &DOMStorageDispatcherHost::OnKey, storage_area_id, index, reply_msg));
+ return;
+ }
+
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
+ bool key_exception = false;
+ WebStorageArea* storage_area = GetStorageArea(storage_area_id);
+ CHECK(storage_area); // TODO(jorlow): Do better than this.
+ string16 key = storage_area->key(index, key_exception);
+ ViewHostMsg_DOMStorageKey::WriteReplyParams(reply_msg, key_exception, key);
+ Send(reply_msg);
+}
+
+void DOMStorageDispatcherHost::OnGetItem(int64 storage_area_id,
+ const string16& key,
+ IPC::Message* reply_msg) {
+ DCHECK(!shutdown_);
+ if (ChromeThread::CurrentlyOn(ChromeThread::IO)) {
+ MessageLoop* webkit_loop = webkit_thread_->GetMessageLoop();
+ webkit_loop->PostTask(FROM_HERE, NewRunnableMethod(this,
+ &DOMStorageDispatcherHost::OnGetItem,
+ storage_area_id, key, reply_msg));
+ return;
+ }
+
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
+ WebStorageArea* storage_area = GetStorageArea(storage_area_id);
+ CHECK(storage_area); // TODO(jorlow): Do better than this.
+ WebKit::WebString value = storage_area->getItem(key);
+ ViewHostMsg_DOMStorageGetItem::WriteReplyParams(reply_msg, (string16)value,
+ value.isNull());
+ Send(reply_msg);
+}
+
+void DOMStorageDispatcherHost::OnSetItem(int64 storage_area_id,
+ const string16& key,
+ const string16& value) {
+ DCHECK(!shutdown_);
+ if (ChromeThread::CurrentlyOn(ChromeThread::IO)) {
+ MessageLoop* webkit_loop = webkit_thread_->GetMessageLoop();
+ webkit_loop->PostTask(FROM_HERE, NewRunnableMethod(this,
+ &DOMStorageDispatcherHost::OnSetItem, storage_area_id, key, value));
+ return;
+ }
+
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
+ bool quota_exception = false;
+ WebStorageArea* storage_area = GetStorageArea(storage_area_id);
+ CHECK(storage_area); // TODO(jorlow): Do better than this.
+ storage_area->setItem(key, value, quota_exception);
+ DCHECK(!quota_exception); // This is tracked by the renderer.
+}
+
+void DOMStorageDispatcherHost::OnRemoveItem(int64 storage_area_id,
+ const string16& key) {
+ DCHECK(!shutdown_);
+ if (ChromeThread::CurrentlyOn(ChromeThread::IO)) {
+ MessageLoop* webkit_loop = webkit_thread_->GetMessageLoop();
+ webkit_loop->PostTask(FROM_HERE, NewRunnableMethod(this,
+ &DOMStorageDispatcherHost::OnRemoveItem, storage_area_id, key));
+ return;
+ }
+
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
+ WebStorageArea* storage_area = GetStorageArea(storage_area_id);
+ CHECK(storage_area); // TODO(jorlow): Do better than this.
+ storage_area->removeItem(key);
+}
+
+void DOMStorageDispatcherHost::OnClear(int64 storage_area_id,
+ IPC::Message* reply_msg) {
+ DCHECK(!shutdown_);
+ if (ChromeThread::CurrentlyOn(ChromeThread::IO)) {
+ MessageLoop* webkit_loop = webkit_thread_->GetMessageLoop();
+ webkit_loop->PostTask(FROM_HERE, NewRunnableMethod(this,
+ &DOMStorageDispatcherHost::OnClear, storage_area_id, reply_msg));
+ return;
+ }
+
+ 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);
+ CHECK(storage_area); // TODO(jorlow): Do better than this.
+ 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;
+}
+
+string16 DOMStorageDispatcherHost::GetLocalStoragePath() {
+ // TODO(jorlow): Create a path based on the WebKitContext.
+ string16 path;
+ return path;
+}
« no previous file with comments | « chrome/browser/in_process_webkit/dom_storage_dispatcher_host.h ('k') | chrome/browser/in_process_webkit/webkit_thread.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698