summaryrefslogtreecommitdiffstats
path: root/content/browser/in_process_webkit/indexed_db_dispatcher_host.cc
diff options
context:
space:
mode:
Diffstat (limited to 'content/browser/in_process_webkit/indexed_db_dispatcher_host.cc')
-rw-r--r--content/browser/in_process_webkit/indexed_db_dispatcher_host.cc1024
1 files changed, 1024 insertions, 0 deletions
diff --git a/content/browser/in_process_webkit/indexed_db_dispatcher_host.cc b/content/browser/in_process_webkit/indexed_db_dispatcher_host.cc
new file mode 100644
index 0000000..5e8020e
--- /dev/null
+++ b/content/browser/in_process_webkit/indexed_db_dispatcher_host.cc
@@ -0,0 +1,1024 @@
+// Copyright (c) 2010 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/browser/in_process_webkit/indexed_db_dispatcher_host.h"
+
+#include "base/command_line.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/browser/browser_thread.h"
+#include "chrome/browser/content_settings/host_content_settings_map.h"
+#include "chrome/browser/metrics/user_metrics.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/renderer_host/browser_render_process_host.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/indexed_db_messages.h"
+#include "content/browser/in_process_webkit/indexed_db_callbacks.h"
+#include "content/browser/renderer_host/render_message_filter.h"
+#include "content/browser/renderer_host/render_view_host_notification_task.h"
+#include "chrome/common/result_codes.h"
+#include "googleurl/src/gurl.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebDOMStringList.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBCursor.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBDatabase.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBDatabaseError.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBKeyRange.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBIndex.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBFactory.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBObjectStore.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBTransaction.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebVector.h"
+#include "webkit/glue/webkit_glue.h"
+
+using WebKit::WebDOMStringList;
+using WebKit::WebExceptionCode;
+using WebKit::WebIDBCallbacks;
+using WebKit::WebIDBCursor;
+using WebKit::WebIDBDatabase;
+using WebKit::WebIDBDatabaseError;
+using WebKit::WebIDBIndex;
+using WebKit::WebIDBKey;
+using WebKit::WebIDBKeyRange;
+using WebKit::WebIDBObjectStore;
+using WebKit::WebIDBTransaction;
+using WebKit::WebSecurityOrigin;
+using WebKit::WebSerializedScriptValue;
+using WebKit::WebVector;
+
+namespace {
+
+// FIXME: Replace this magic constant once we have a more sophisticated quota
+// system.
+static const uint64 kDefaultQuota = 5 * 1024 * 1024;
+
+template <class T>
+void DeleteOnWebKitThread(T* obj) {
+ if (!BrowserThread::DeleteSoon(BrowserThread::WEBKIT, FROM_HERE, obj))
+ delete obj;
+}
+
+}
+
+IndexedDBDispatcherHost::IndexedDBDispatcherHost(int process_id,
+ Profile* profile)
+ : webkit_context_(profile->GetWebKitContext()),
+ host_content_settings_map_(profile->GetHostContentSettingsMap()),
+ ALLOW_THIS_IN_INITIALIZER_LIST(database_dispatcher_host_(
+ new DatabaseDispatcherHost(this))),
+ ALLOW_THIS_IN_INITIALIZER_LIST(index_dispatcher_host_(
+ new IndexDispatcherHost(this))),
+ ALLOW_THIS_IN_INITIALIZER_LIST(object_store_dispatcher_host_(
+ new ObjectStoreDispatcherHost(this))),
+ ALLOW_THIS_IN_INITIALIZER_LIST(cursor_dispatcher_host_(
+ new CursorDispatcherHost(this))),
+ ALLOW_THIS_IN_INITIALIZER_LIST(transaction_dispatcher_host_(
+ new TransactionDispatcherHost(this))),
+ process_id_(process_id) {
+ DCHECK(webkit_context_.get());
+}
+
+IndexedDBDispatcherHost::~IndexedDBDispatcherHost() {
+}
+
+void IndexedDBDispatcherHost::OnChannelClosing() {
+ BrowserMessageFilter::OnChannelClosing();
+ BrowserThread::DeleteSoon(
+ BrowserThread::WEBKIT, FROM_HERE, database_dispatcher_host_.release());
+ BrowserThread::DeleteSoon(
+ BrowserThread::WEBKIT, FROM_HERE, index_dispatcher_host_.release());
+ BrowserThread::DeleteSoon(
+ BrowserThread::WEBKIT, FROM_HERE,
+ object_store_dispatcher_host_.release());
+ BrowserThread::DeleteSoon(
+ BrowserThread::WEBKIT, FROM_HERE, cursor_dispatcher_host_.release());
+ BrowserThread::DeleteSoon(
+ BrowserThread::WEBKIT, FROM_HERE,
+ transaction_dispatcher_host_.release());
+}
+
+void IndexedDBDispatcherHost::OverrideThreadForMessage(
+ const IPC::Message& message,
+ BrowserThread::ID* thread) {
+ if (IPC_MESSAGE_CLASS(message) == IndexedDBMsgStart)
+ *thread = BrowserThread::WEBKIT;
+}
+
+bool IndexedDBDispatcherHost::OnMessageReceived(const IPC::Message& message,
+ bool* message_was_ok) {
+ if (IPC_MESSAGE_CLASS(message) != IndexedDBMsgStart)
+ return false;
+
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
+
+ bool handled =
+ database_dispatcher_host_->OnMessageReceived(message, message_was_ok) ||
+ index_dispatcher_host_->OnMessageReceived(message, message_was_ok) ||
+ object_store_dispatcher_host_->OnMessageReceived(
+ message, message_was_ok) ||
+ cursor_dispatcher_host_->OnMessageReceived(message, message_was_ok) ||
+ transaction_dispatcher_host_->OnMessageReceived(message, message_was_ok);
+
+ if (!handled) {
+ handled = true;
+ IPC_BEGIN_MESSAGE_MAP_EX(IndexedDBDispatcherHost, message, *message_was_ok)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_FactoryOpen, OnIDBFactoryOpen)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_FactoryDeleteDatabase,
+ OnIDBFactoryDeleteDatabase)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ }
+
+ return handled;
+}
+
+int32 IndexedDBDispatcherHost::Add(WebIDBCursor* idb_cursor) {
+ if (!cursor_dispatcher_host_.get()) {
+ delete idb_cursor;
+ return 0;
+ }
+ return cursor_dispatcher_host_->map_.Add(idb_cursor);
+}
+
+int32 IndexedDBDispatcherHost::Add(WebIDBDatabase* idb_database) {
+ if (!database_dispatcher_host_.get()) {
+ delete idb_database;
+ return 0;
+ }
+ return database_dispatcher_host_->map_.Add(idb_database);
+}
+
+int32 IndexedDBDispatcherHost::Add(WebIDBIndex* idb_index) {
+ if (!index_dispatcher_host_.get()) {
+ delete idb_index;
+ return 0;
+ }
+ if (!idb_index)
+ return 0;
+ return index_dispatcher_host_->map_.Add(idb_index);
+}
+
+int32 IndexedDBDispatcherHost::Add(WebIDBObjectStore* idb_object_store) {
+ if (!object_store_dispatcher_host_.get()) {
+ delete idb_object_store;
+ return 0;
+ }
+ if (!idb_object_store)
+ return 0;
+ return object_store_dispatcher_host_->map_.Add(idb_object_store);
+}
+
+int32 IndexedDBDispatcherHost::Add(WebIDBTransaction* idb_transaction) {
+ if (!transaction_dispatcher_host_.get()) {
+ delete idb_transaction;
+ return 0;
+ }
+ int32 id = transaction_dispatcher_host_->map_.Add(idb_transaction);
+ idb_transaction->setCallbacks(new IndexedDBTransactionCallbacks(this, id));
+ return id;
+}
+
+bool IndexedDBDispatcherHost::CheckContentSetting(const string16& origin,
+ const string16& description,
+ int routing_id,
+ int response_id) {
+ GURL host(string16(WebSecurityOrigin::createFromDatabaseIdentifier(
+ origin).toString()));
+
+ ContentSetting content_setting =
+ host_content_settings_map_->GetContentSetting(
+ host, CONTENT_SETTINGS_TYPE_COOKIES, "");
+
+ CallRenderViewHostContentSettingsDelegate(
+ process_id_, routing_id,
+ &RenderViewHostDelegate::ContentSettings::OnIndexedDBAccessed,
+ host, description, content_setting == CONTENT_SETTING_BLOCK);
+
+ if (content_setting == CONTENT_SETTING_BLOCK) {
+ // TODO(jorlow): Change this to the proper error code once we figure out
+ // one.
+ int error_code = 0; // Defined by the IndexedDB spec.
+ static string16 error_message = ASCIIToUTF16(
+ "The user denied permission to access the database.");
+ Send(new IndexedDBMsg_CallbacksError(response_id, error_code,
+ error_message));
+ return false;
+ }
+ return true;
+}
+
+void IndexedDBDispatcherHost::OnIDBFactoryOpen(
+ const IndexedDBHostMsg_FactoryOpen_Params& params) {
+ FilePath base_path = webkit_context_->data_path();
+ FilePath indexed_db_path;
+ if (!base_path.empty()) {
+ indexed_db_path = base_path.Append(
+ IndexedDBContext::kIndexedDBDirectory);
+ }
+
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
+ if (!CheckContentSetting(params.origin, params.name, params.routing_id,
+ params.response_id)) {
+ return;
+ }
+
+ DCHECK(kDefaultQuota == params.maximum_size);
+
+ uint64 quota = kDefaultQuota;
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kUnlimitedQuotaForIndexedDB)) {
+ quota = 1024 * 1024 * 1024; // 1GB. More or less "unlimited".
+ }
+
+ Context()->GetIDBFactory()->open(
+ params.name,
+ new IndexedDBCallbacks<WebIDBDatabase>(this, params.response_id),
+ WebSecurityOrigin::createFromDatabaseIdentifier(params.origin), NULL,
+ webkit_glue::FilePathToWebString(indexed_db_path), quota);
+}
+
+void IndexedDBDispatcherHost::OnIDBFactoryDeleteDatabase(
+ const IndexedDBHostMsg_FactoryDeleteDatabase_Params& params) {
+ FilePath base_path = webkit_context_->data_path();
+ FilePath indexed_db_path;
+ if (!base_path.empty()) {
+ indexed_db_path = base_path.Append(
+ IndexedDBContext::kIndexedDBDirectory);
+ }
+
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
+ if (!CheckContentSetting(params.origin, params.name, params.routing_id,
+ params.response_id)) {
+ return;
+ }
+
+ Context()->GetIDBFactory()->deleteDatabase(
+ params.name,
+ new IndexedDBCallbacks<WebIDBDatabase>(this, params.response_id),
+ WebSecurityOrigin::createFromDatabaseIdentifier(params.origin), NULL,
+ webkit_glue::FilePathToWebString(indexed_db_path));
+}
+
+//////////////////////////////////////////////////////////////////////
+// Helper templates.
+//
+
+template <typename ObjectType>
+ObjectType* IndexedDBDispatcherHost::GetOrTerminateProcess(
+ IDMap<ObjectType, IDMapOwnPointer>* map, int32 return_object_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
+ ObjectType* return_object = map->Lookup(return_object_id);
+ if (!return_object) {
+ UserMetrics::RecordAction(UserMetricsAction("BadMessageTerminate_IDBMF"));
+ BadMessageReceived();
+ }
+ return return_object;
+}
+
+template <typename ReplyType, typename MapObjectType, typename Method>
+void IndexedDBDispatcherHost::SyncGetter(
+ IDMap<MapObjectType, IDMapOwnPointer>* map, int32 object_id,
+ ReplyType* reply, Method method) {
+ MapObjectType* object = GetOrTerminateProcess(map, object_id);
+ if (!object)
+ return;
+
+ *reply = (object->*method)();
+}
+
+template <typename ObjectType>
+void IndexedDBDispatcherHost::DestroyObject(
+ IDMap<ObjectType, IDMapOwnPointer>* map, int32 object_id) {
+ GetOrTerminateProcess(map, object_id);
+ map->Remove(object_id);
+}
+
+
+//////////////////////////////////////////////////////////////////////
+// IndexedDBDispatcherHost::DatabaseDispatcherHost
+//
+
+IndexedDBDispatcherHost::DatabaseDispatcherHost::DatabaseDispatcherHost(
+ IndexedDBDispatcherHost* parent)
+ : parent_(parent) {
+ map_.set_check_on_null_data(true);
+}
+
+IndexedDBDispatcherHost::DatabaseDispatcherHost::~DatabaseDispatcherHost() {
+}
+
+bool IndexedDBDispatcherHost::DatabaseDispatcherHost::OnMessageReceived(
+ const IPC::Message& message, bool* msg_is_ok) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP_EX(IndexedDBDispatcherHost::DatabaseDispatcherHost,
+ message, *msg_is_ok)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseName, OnName)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseVersion, OnVersion)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseObjectStoreNames,
+ OnObjectStoreNames)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseCreateObjectStore,
+ OnCreateObjectStore)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseDeleteObjectStore,
+ OnDeleteObjectStore)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseSetVersion, OnSetVersion)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseTransaction, OnTransaction)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseClose, OnClose)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseDestroyed, OnDestroyed)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void IndexedDBDispatcherHost::DatabaseDispatcherHost::Send(
+ IPC::Message* message) {
+ parent_->Send(message);
+}
+
+void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnName(
+ int32 object_id, string16* name) {
+ parent_->SyncGetter<string16>(&map_, object_id, name, &WebIDBDatabase::name);
+}
+
+void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnVersion(
+ int32 object_id, string16* version) {
+ parent_->SyncGetter<string16>(
+ &map_, object_id, version, &WebIDBDatabase::version);
+}
+
+void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnObjectStoreNames(
+ int32 idb_database_id, std::vector<string16>* object_stores) {
+ WebIDBDatabase* idb_database = parent_->GetOrTerminateProcess(
+ &map_, idb_database_id);
+ if (!idb_database)
+ return;
+
+ WebDOMStringList web_object_stores = idb_database->objectStoreNames();
+ object_stores->reserve(web_object_stores.length());
+ for (unsigned i = 0; i < web_object_stores.length(); ++i)
+ object_stores->push_back(web_object_stores.item(i));
+}
+
+void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnCreateObjectStore(
+ const IndexedDBHostMsg_DatabaseCreateObjectStore_Params& params,
+ int32* object_store_id, WebKit::WebExceptionCode* ec) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
+ WebIDBDatabase* idb_database = parent_->GetOrTerminateProcess(
+ &map_, params.idb_database_id);
+ WebIDBTransaction* idb_transaction = parent_->GetOrTerminateProcess(
+ &parent_->transaction_dispatcher_host_->map_, params.transaction_id);
+ if (!idb_database || !idb_transaction)
+ return;
+
+ *ec = 0;
+ WebIDBObjectStore* object_store = idb_database->createObjectStore(
+ params.name, params.key_path, params.auto_increment,
+ *idb_transaction, *ec);
+ *object_store_id = *ec ? 0 : parent_->Add(object_store);
+}
+
+void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnDeleteObjectStore(
+ int32 idb_database_id,
+ const string16& name,
+ int32 transaction_id,
+ WebKit::WebExceptionCode* ec) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
+ WebIDBDatabase* idb_database = parent_->GetOrTerminateProcess(
+ &map_, idb_database_id);
+ WebIDBTransaction* idb_transaction = parent_->GetOrTerminateProcess(
+ &parent_->transaction_dispatcher_host_->map_, transaction_id);
+ if (!idb_database || !idb_transaction)
+ return;
+
+ *ec = 0;
+ idb_database->deleteObjectStore(name, *idb_transaction, *ec);
+}
+
+void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnSetVersion(
+ int32 idb_database_id,
+ int32 response_id,
+ const string16& version,
+ WebKit::WebExceptionCode* ec) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
+ WebIDBDatabase* idb_database = parent_->GetOrTerminateProcess(
+ &map_, idb_database_id);
+ if (!idb_database)
+ return;
+
+ *ec = 0;
+ idb_database->setVersion(
+ version,
+ new IndexedDBCallbacks<WebIDBTransaction>(parent_, response_id),
+ *ec);
+}
+
+void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnTransaction(
+ int32 idb_database_id,
+ const std::vector<string16>& names,
+ int32 mode,
+ int32 timeout,
+ int32* idb_transaction_id,
+ WebKit::WebExceptionCode* ec) {
+ WebIDBDatabase* database = parent_->GetOrTerminateProcess(
+ &map_, idb_database_id);
+ if (!database)
+ return;
+
+ WebDOMStringList object_stores;
+ for (std::vector<string16>::const_iterator it = names.begin();
+ it != names.end(); ++it) {
+ object_stores.append(*it);
+ }
+
+ *ec = 0;
+ WebIDBTransaction* transaction = database->transaction(
+ object_stores, mode, timeout, *ec);
+ DCHECK(!transaction != !*ec);
+ *idb_transaction_id = *ec ? 0 : parent_->Add(transaction);
+}
+
+void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnClose(
+ int32 idb_database_id) {
+ WebIDBDatabase* database = parent_->GetOrTerminateProcess(
+ &map_, idb_database_id);
+ database->close();
+}
+
+ void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnDestroyed(
+ int32 object_id) {
+ parent_->DestroyObject(&map_, object_id);
+}
+
+
+//////////////////////////////////////////////////////////////////////
+// IndexedDBDispatcherHost::IndexDispatcherHost
+//
+
+IndexedDBDispatcherHost::IndexDispatcherHost::IndexDispatcherHost(
+ IndexedDBDispatcherHost* parent)
+ : parent_(parent) {
+ map_.set_check_on_null_data(true);
+}
+
+IndexedDBDispatcherHost::IndexDispatcherHost::~IndexDispatcherHost() {
+}
+
+bool IndexedDBDispatcherHost::IndexDispatcherHost::OnMessageReceived(
+ const IPC::Message& message, bool* msg_is_ok) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP_EX(IndexedDBDispatcherHost::IndexDispatcherHost,
+ message, *msg_is_ok)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_IndexName, OnName)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_IndexStoreName, OnStoreName)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_IndexKeyPath, OnKeyPath)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_IndexUnique, OnUnique)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_IndexOpenObjectCursor,
+ OnOpenObjectCursor)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_IndexOpenKeyCursor, OnOpenKeyCursor)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_IndexGetObject, OnGetObject)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_IndexGetKey, OnGetKey)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_IndexDestroyed, OnDestroyed)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void IndexedDBDispatcherHost::IndexDispatcherHost::Send(
+ IPC::Message* message) {
+ parent_->Send(message);
+}
+
+void IndexedDBDispatcherHost::IndexDispatcherHost::OnName(
+ int32 object_id, string16* name) {
+ parent_->SyncGetter<string16>(&map_, object_id, name, &WebIDBIndex::name);
+}
+
+void IndexedDBDispatcherHost::IndexDispatcherHost::OnStoreName(
+ int32 object_id, string16* store_name) {
+ parent_->SyncGetter<string16>(
+ &map_, object_id, store_name, &WebIDBIndex::storeName);
+}
+
+void IndexedDBDispatcherHost::IndexDispatcherHost::OnKeyPath(
+ int32 object_id, NullableString16* key_path) {
+ parent_->SyncGetter<NullableString16>(
+ &map_, object_id, key_path, &WebIDBIndex::keyPath);
+}
+
+void IndexedDBDispatcherHost::IndexDispatcherHost::OnUnique(
+ int32 object_id, bool* unique) {
+ parent_->SyncGetter<bool>(&map_, object_id, unique, &WebIDBIndex::unique);
+}
+
+void IndexedDBDispatcherHost::IndexDispatcherHost::OnOpenObjectCursor(
+ const IndexedDBHostMsg_IndexOpenCursor_Params& params,
+ WebKit::WebExceptionCode* ec) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
+ WebIDBIndex* idb_index = parent_->GetOrTerminateProcess(
+ &map_, params.idb_index_id);
+ WebIDBTransaction* idb_transaction = parent_->GetOrTerminateProcess(
+ &parent_->transaction_dispatcher_host_->map_, params.transaction_id);
+ if (!idb_transaction || !idb_index)
+ return;
+
+ *ec = 0;
+ scoped_ptr<WebIDBCallbacks> callbacks(
+ new IndexedDBCallbacks<WebIDBCursor>(parent_, params.response_id));
+ idb_index->openObjectCursor(
+ WebIDBKeyRange(params.lower_key, params.upper_key, params.lower_open,
+ params.upper_open),
+ params.direction, callbacks.release(), *idb_transaction, *ec);
+}
+
+void IndexedDBDispatcherHost::IndexDispatcherHost::OnOpenKeyCursor(
+ const IndexedDBHostMsg_IndexOpenCursor_Params& params,
+ WebKit::WebExceptionCode* ec) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
+ WebIDBIndex* idb_index = parent_->GetOrTerminateProcess(
+ &map_, params.idb_index_id);
+ WebIDBTransaction* idb_transaction = parent_->GetOrTerminateProcess(
+ &parent_->transaction_dispatcher_host_->map_, params.transaction_id);
+ if (!idb_transaction || !idb_index)
+ return;
+
+ *ec = 0;
+ scoped_ptr<WebIDBCallbacks> callbacks(
+ new IndexedDBCallbacks<WebIDBCursor>(parent_, params.response_id));
+ idb_index->openKeyCursor(
+ WebIDBKeyRange(params.lower_key, params.upper_key, params.lower_open,
+ params.upper_open),
+ params.direction, callbacks.release(), *idb_transaction, *ec);
+}
+
+void IndexedDBDispatcherHost::IndexDispatcherHost::OnGetObject(
+ int idb_index_id,
+ int32 response_id,
+ const IndexedDBKey& key,
+ int32 transaction_id,
+ WebKit::WebExceptionCode* ec) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
+ WebIDBIndex* idb_index = parent_->GetOrTerminateProcess(
+ &map_, idb_index_id);
+ WebIDBTransaction* idb_transaction = parent_->GetOrTerminateProcess(
+ &parent_->transaction_dispatcher_host_->map_, transaction_id);
+ if (!idb_transaction || !idb_index)
+ return;
+
+ *ec = 0;
+ scoped_ptr<WebIDBCallbacks> callbacks(
+ new IndexedDBCallbacks<WebSerializedScriptValue>(parent_, response_id));
+ idb_index->getObject(key, callbacks.release(), *idb_transaction, *ec);
+}
+
+void IndexedDBDispatcherHost::IndexDispatcherHost::OnGetKey(
+ int idb_index_id,
+ int32 response_id,
+ const IndexedDBKey& key,
+ int32 transaction_id,
+ WebKit::WebExceptionCode* ec) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
+ WebIDBIndex* idb_index = parent_->GetOrTerminateProcess(
+ &map_, idb_index_id);
+ WebIDBTransaction* idb_transaction = parent_->GetOrTerminateProcess(
+ &parent_->transaction_dispatcher_host_->map_, transaction_id);
+ if (!idb_transaction || !idb_index)
+ return;
+
+ *ec = 0;
+ scoped_ptr<WebIDBCallbacks> callbacks(
+ new IndexedDBCallbacks<WebIDBKey>(parent_, response_id));
+ idb_index->getKey(key, callbacks.release(), *idb_transaction, *ec);
+}
+
+void IndexedDBDispatcherHost::IndexDispatcherHost::OnDestroyed(
+ int32 object_id) {
+ parent_->DestroyObject(&map_, object_id);
+}
+
+//////////////////////////////////////////////////////////////////////
+// IndexedDBDispatcherHost::ObjectStoreDispatcherHost
+//
+
+IndexedDBDispatcherHost::ObjectStoreDispatcherHost::ObjectStoreDispatcherHost(
+ IndexedDBDispatcherHost* parent)
+ : parent_(parent) {
+ map_.set_check_on_null_data(true);
+}
+
+IndexedDBDispatcherHost::
+ObjectStoreDispatcherHost::~ObjectStoreDispatcherHost() {
+}
+
+bool IndexedDBDispatcherHost::ObjectStoreDispatcherHost::OnMessageReceived(
+ const IPC::Message& message, bool* msg_is_ok) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP_EX(IndexedDBDispatcherHost::ObjectStoreDispatcherHost,
+ message, *msg_is_ok)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_ObjectStoreName, OnName)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_ObjectStoreKeyPath, OnKeyPath)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_ObjectStoreIndexNames, OnIndexNames)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_ObjectStoreGet, OnGet)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_ObjectStorePut, OnPut)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_ObjectStoreDelete, OnDelete)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_ObjectStoreClear, OnClear)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_ObjectStoreCreateIndex, OnCreateIndex)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_ObjectStoreIndex, OnIndex)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_ObjectStoreDeleteIndex, OnDeleteIndex)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_ObjectStoreOpenCursor, OnOpenCursor)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_ObjectStoreDestroyed, OnDestroyed)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void IndexedDBDispatcherHost::ObjectStoreDispatcherHost::Send(
+ IPC::Message* message) {
+ parent_->Send(message);
+}
+
+void IndexedDBDispatcherHost::ObjectStoreDispatcherHost::OnName(
+ int32 object_id, string16* name) {
+ parent_->SyncGetter<string16>(
+ &map_, object_id, name, &WebIDBObjectStore::name);
+}
+
+void IndexedDBDispatcherHost::ObjectStoreDispatcherHost::OnKeyPath(
+ int32 object_id, NullableString16* keyPath) {
+ parent_->SyncGetter<NullableString16>(
+ &map_, object_id, keyPath, &WebIDBObjectStore::keyPath);
+}
+
+void IndexedDBDispatcherHost::ObjectStoreDispatcherHost::OnIndexNames(
+ int32 idb_object_store_id, std::vector<string16>* index_names) {
+ WebIDBObjectStore* idb_object_store = parent_->GetOrTerminateProcess(
+ &map_, idb_object_store_id);
+ if (!idb_object_store)
+ return;
+
+ WebDOMStringList web_index_names = idb_object_store->indexNames();
+ index_names->reserve(web_index_names.length());
+ for (unsigned i = 0; i < web_index_names.length(); ++i)
+ index_names->push_back(web_index_names.item(i));
+}
+
+void IndexedDBDispatcherHost::ObjectStoreDispatcherHost::OnGet(
+ int idb_object_store_id,
+ int32 response_id,
+ const IndexedDBKey& key,
+ int32 transaction_id,
+ WebKit::WebExceptionCode* ec) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
+ WebIDBObjectStore* idb_object_store = parent_->GetOrTerminateProcess(
+ &map_, idb_object_store_id);
+ WebIDBTransaction* idb_transaction = parent_->GetOrTerminateProcess(
+ &parent_->transaction_dispatcher_host_->map_, transaction_id);
+ if (!idb_transaction || !idb_object_store)
+ return;
+
+ *ec = 0;
+ scoped_ptr<WebIDBCallbacks> callbacks(
+ new IndexedDBCallbacks<WebSerializedScriptValue>(parent_, response_id));
+ idb_object_store->get(key, callbacks.release(), *idb_transaction, *ec);
+}
+
+void IndexedDBDispatcherHost::ObjectStoreDispatcherHost::OnPut(
+ const IndexedDBHostMsg_ObjectStorePut_Params& params,
+ WebKit::WebExceptionCode* ec) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
+ WebIDBObjectStore* idb_object_store = parent_->GetOrTerminateProcess(
+ &map_, params.idb_object_store_id);
+ WebIDBTransaction* idb_transaction = parent_->GetOrTerminateProcess(
+ &parent_->transaction_dispatcher_host_->map_, params.transaction_id);
+ if (!idb_transaction || !idb_object_store)
+ return;
+
+ *ec = 0;
+ scoped_ptr<WebIDBCallbacks> callbacks(
+ new IndexedDBCallbacks<WebIDBKey>(parent_, params.response_id));
+ idb_object_store->put(params.serialized_value, params.key, params.put_mode,
+ callbacks.release(), *idb_transaction, *ec);
+}
+
+void IndexedDBDispatcherHost::ObjectStoreDispatcherHost::OnDelete(
+ int idb_object_store_id,
+ int32 response_id,
+ const IndexedDBKey& key,
+ int32 transaction_id,
+ WebKit::WebExceptionCode* ec) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
+ WebIDBObjectStore* idb_object_store = parent_->GetOrTerminateProcess(
+ &map_, idb_object_store_id);
+ WebIDBTransaction* idb_transaction = parent_->GetOrTerminateProcess(
+ &parent_->transaction_dispatcher_host_->map_, transaction_id);
+ if (!idb_transaction || !idb_object_store)
+ return;
+
+ *ec = 0;
+ scoped_ptr<WebIDBCallbacks> callbacks(
+ new IndexedDBCallbacks<WebSerializedScriptValue>(parent_, response_id));
+ idb_object_store->deleteFunction(
+ key, callbacks.release(), *idb_transaction, *ec);
+}
+
+void IndexedDBDispatcherHost::ObjectStoreDispatcherHost::OnClear(
+ int idb_object_store_id,
+ int32 response_id,
+ int32 transaction_id,
+ WebKit::WebExceptionCode* ec) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
+ WebIDBObjectStore* idb_object_store = parent_->GetOrTerminateProcess(
+ &map_, idb_object_store_id);
+ WebIDBTransaction* idb_transaction = parent_->GetOrTerminateProcess(
+ &parent_->transaction_dispatcher_host_->map_, transaction_id);
+ if (!idb_transaction || !idb_object_store)
+ return;
+
+ *ec = 0;
+ scoped_ptr<WebIDBCallbacks> callbacks(
+ new IndexedDBCallbacks<WebSerializedScriptValue>(parent_, response_id));
+ idb_object_store->clear(callbacks.release(), *idb_transaction, *ec);
+}
+
+void IndexedDBDispatcherHost::ObjectStoreDispatcherHost::OnCreateIndex(
+ const IndexedDBHostMsg_ObjectStoreCreateIndex_Params& params,
+ int32* index_id, WebKit::WebExceptionCode* ec) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
+ WebIDBObjectStore* idb_object_store = parent_->GetOrTerminateProcess(
+ &map_, params.idb_object_store_id);
+ WebIDBTransaction* idb_transaction = parent_->GetOrTerminateProcess(
+ &parent_->transaction_dispatcher_host_->map_, params.transaction_id);
+ if (!idb_object_store || !idb_transaction)
+ return;
+
+ *ec = 0;
+ WebIDBIndex* index = idb_object_store->createIndex(
+ params.name, params.key_path, params.unique, *idb_transaction, *ec);
+ *index_id = *ec ? 0 : parent_->Add(index);
+}
+
+void IndexedDBDispatcherHost::ObjectStoreDispatcherHost::OnIndex(
+ int32 idb_object_store_id,
+ const string16& name,
+ int32* idb_index_id,
+ WebKit::WebExceptionCode* ec) {
+ WebIDBObjectStore* idb_object_store = parent_->GetOrTerminateProcess(
+ &map_, idb_object_store_id);
+ if (!idb_object_store)
+ return;
+
+ *ec = 0;
+ WebIDBIndex* index = idb_object_store->index(name, *ec);
+ *idb_index_id = parent_->Add(index);
+}
+
+void IndexedDBDispatcherHost::ObjectStoreDispatcherHost::OnDeleteIndex(
+ int32 idb_object_store_id,
+ const string16& name,
+ int32 transaction_id,
+ WebKit::WebExceptionCode* ec) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
+ WebIDBObjectStore* idb_object_store = parent_->GetOrTerminateProcess(
+ &map_, idb_object_store_id);
+ WebIDBTransaction* idb_transaction = parent_->GetOrTerminateProcess(
+ &parent_->transaction_dispatcher_host_->map_, transaction_id);
+ if (!idb_object_store || !idb_transaction)
+ return;
+
+ *ec = 0;
+ idb_object_store->deleteIndex(name, *idb_transaction, *ec);
+}
+
+void IndexedDBDispatcherHost::ObjectStoreDispatcherHost::OnOpenCursor(
+ const IndexedDBHostMsg_ObjectStoreOpenCursor_Params& params,
+ WebKit::WebExceptionCode* ec) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
+ WebIDBObjectStore* idb_object_store = parent_->GetOrTerminateProcess(
+ &parent_->object_store_dispatcher_host_->map_,
+ params.idb_object_store_id);
+ WebIDBTransaction* idb_transaction = parent_->GetOrTerminateProcess(
+ &parent_->transaction_dispatcher_host_->map_, params.transaction_id);
+ if (!idb_transaction || !idb_object_store)
+ return;
+
+ *ec = 0;
+ scoped_ptr<WebIDBCallbacks> callbacks(
+ new IndexedDBCallbacks<WebIDBCursor>(parent_, params.response_id));
+ idb_object_store->openCursor(
+ WebIDBKeyRange(params.lower_key, params.upper_key, params.lower_open,
+ params.upper_open),
+ params.direction, callbacks.release(), *idb_transaction, *ec);
+}
+
+void IndexedDBDispatcherHost::ObjectStoreDispatcherHost::OnDestroyed(
+ int32 object_id) {
+ parent_->DestroyObject(&map_, object_id);
+}
+
+//////////////////////////////////////////////////////////////////////
+// IndexedDBDispatcherHost::CursorDispatcherHost
+//
+
+IndexedDBDispatcherHost::CursorDispatcherHost::CursorDispatcherHost(
+ IndexedDBDispatcherHost* parent)
+ : parent_(parent) {
+ map_.set_check_on_null_data(true);
+}
+
+IndexedDBDispatcherHost::CursorDispatcherHost::~CursorDispatcherHost() {
+}
+
+bool IndexedDBDispatcherHost::CursorDispatcherHost::OnMessageReceived(
+ const IPC::Message& message, bool* msg_is_ok) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP_EX(IndexedDBDispatcherHost::CursorDispatcherHost,
+ message, *msg_is_ok)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_CursorDirection, OnDirection)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_CursorKey, OnKey)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_CursorValue, OnValue)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_CursorUpdate, OnUpdate)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_CursorContinue, OnContinue)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_CursorDelete, OnDelete)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_CursorDestroyed, OnDestroyed)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+
+void IndexedDBDispatcherHost::CursorDispatcherHost::Send(
+ IPC::Message* message) {
+ parent_->Send(message);
+}
+
+void IndexedDBDispatcherHost::CursorDispatcherHost::OnDirection(
+ int32 object_id, int32* direction) {
+ WebIDBCursor* idb_cursor = parent_->GetOrTerminateProcess(&map_, object_id);
+ if (!idb_cursor)
+ return;
+
+ *direction = idb_cursor->direction();
+}
+
+void IndexedDBDispatcherHost::CursorDispatcherHost::OnKey(
+ int32 object_id, IndexedDBKey* key) {
+ WebIDBCursor* idb_cursor = parent_->GetOrTerminateProcess(&map_, object_id);
+ if (!idb_cursor)
+ return;
+
+ *key = IndexedDBKey(idb_cursor->key());
+}
+
+void IndexedDBDispatcherHost::CursorDispatcherHost::OnValue(
+ int32 object_id,
+ SerializedScriptValue* script_value,
+ IndexedDBKey* key) {
+ WebIDBCursor* idb_cursor = parent_->GetOrTerminateProcess(&map_, object_id);
+ if (!idb_cursor)
+ return;
+
+ WebSerializedScriptValue temp_script_value;
+ WebIDBKey temp_key;
+ idb_cursor->value(temp_script_value, temp_key);
+
+ *script_value = SerializedScriptValue(temp_script_value);
+ *key = IndexedDBKey(temp_key);
+}
+
+void IndexedDBDispatcherHost::CursorDispatcherHost::OnUpdate(
+ int32 cursor_id,
+ int32 response_id,
+ const SerializedScriptValue& value,
+ WebKit::WebExceptionCode* ec) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
+ WebIDBCursor* idb_cursor = parent_->GetOrTerminateProcess(&map_, cursor_id);
+ if (!idb_cursor)
+ return;
+
+ *ec = 0;
+ idb_cursor->update(
+ value, new IndexedDBCallbacks<WebIDBKey>(parent_, response_id), *ec);
+}
+
+void IndexedDBDispatcherHost::CursorDispatcherHost::OnContinue(
+ int32 cursor_id,
+ int32 response_id,
+ const IndexedDBKey& key,
+ WebKit::WebExceptionCode* ec) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
+ WebIDBCursor* idb_cursor = parent_->GetOrTerminateProcess(&map_, cursor_id);
+ if (!idb_cursor)
+ return;
+
+ *ec = 0;
+ idb_cursor->continueFunction(
+ key, new IndexedDBCallbacks<WebIDBCursor>(parent_, response_id), *ec);
+}
+
+void IndexedDBDispatcherHost::CursorDispatcherHost::OnDelete(
+ int32 cursor_id,
+ int32 response_id,
+ WebKit::WebExceptionCode* ec) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
+ WebIDBCursor* idb_cursor = parent_->GetOrTerminateProcess(&map_, cursor_id);
+ if (!idb_cursor)
+ return;
+
+ *ec = 0;
+ // TODO(jorlow): This should be delete.
+ idb_cursor->remove(
+ new IndexedDBCallbacks<WebSerializedScriptValue>(parent_, response_id), *ec);
+}
+
+void IndexedDBDispatcherHost::CursorDispatcherHost::OnDestroyed(
+ int32 object_id) {
+ parent_->DestroyObject(&map_, object_id);
+}
+
+//////////////////////////////////////////////////////////////////////
+// IndexedDBDispatcherHost::TransactionDispatcherHost
+//
+
+IndexedDBDispatcherHost::TransactionDispatcherHost::TransactionDispatcherHost(
+ IndexedDBDispatcherHost* parent)
+ : parent_(parent) {
+ map_.set_check_on_null_data(true);
+}
+
+IndexedDBDispatcherHost::
+ TransactionDispatcherHost::~TransactionDispatcherHost() {
+ MapType::iterator it(&map_);
+ while (!it.IsAtEnd()) {
+ it.GetCurrentValue()->abort();
+ it.Advance();
+ }
+}
+
+bool IndexedDBDispatcherHost::TransactionDispatcherHost::OnMessageReceived(
+ const IPC::Message& message, bool* msg_is_ok) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP_EX(IndexedDBDispatcherHost::TransactionDispatcherHost,
+ message, *msg_is_ok)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_TransactionAbort, OnAbort)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_TransactionMode, OnMode)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_TransactionObjectStore, OnObjectStore)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_TransactionDidCompleteTaskEvents,
+ OnDidCompleteTaskEvents)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_TransactionDestroyed, OnDestroyed)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void IndexedDBDispatcherHost::TransactionDispatcherHost::Send(
+ IPC::Message* message) {
+ parent_->Send(message);
+}
+
+void IndexedDBDispatcherHost::TransactionDispatcherHost::OnAbort(
+ int32 transaction_id) {
+ WebIDBTransaction* idb_transaction = parent_->GetOrTerminateProcess(
+ &map_, transaction_id);
+ if (!idb_transaction)
+ return;
+
+ idb_transaction->abort();
+}
+
+void IndexedDBDispatcherHost::TransactionDispatcherHost::OnMode(
+ int32 transaction_id,
+ int* mode) {
+ WebIDBTransaction* idb_transaction = parent_->GetOrTerminateProcess(
+ &map_, transaction_id);
+ if (!idb_transaction)
+ return;
+
+ *mode = idb_transaction->mode();
+}
+
+void IndexedDBDispatcherHost::TransactionDispatcherHost::OnObjectStore(
+ int32 transaction_id, const string16& name, int32* object_store_id,
+ WebKit::WebExceptionCode* ec) {
+ WebIDBTransaction* idb_transaction = parent_->GetOrTerminateProcess(
+ &map_, transaction_id);
+ if (!idb_transaction)
+ return;
+
+ *ec = 0;
+ WebIDBObjectStore* object_store = idb_transaction->objectStore(name, *ec);
+ *object_store_id = object_store ? parent_->Add(object_store) : 0;
+}
+
+void IndexedDBDispatcherHost::
+ TransactionDispatcherHost::OnDidCompleteTaskEvents(int transaction_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
+ WebIDBTransaction* idb_transaction = parent_->GetOrTerminateProcess(
+ &map_, transaction_id);
+ if (!idb_transaction)
+ return;
+
+ idb_transaction->didCompleteTaskEvents();
+}
+
+void IndexedDBDispatcherHost::TransactionDispatcherHost::OnDestroyed(
+ int32 object_id) {
+ parent_->DestroyObject(&map_, object_id);
+}