summaryrefslogtreecommitdiffstats
path: root/content/renderer/indexed_db/indexed_db_dispatcher.cc
diff options
context:
space:
mode:
Diffstat (limited to 'content/renderer/indexed_db/indexed_db_dispatcher.cc')
-rw-r--r--content/renderer/indexed_db/indexed_db_dispatcher.cc687
1 files changed, 687 insertions, 0 deletions
diff --git a/content/renderer/indexed_db/indexed_db_dispatcher.cc b/content/renderer/indexed_db/indexed_db_dispatcher.cc
new file mode 100644
index 0000000..4ad0ab5
--- /dev/null
+++ b/content/renderer/indexed_db/indexed_db_dispatcher.cc
@@ -0,0 +1,687 @@
+// Copyright (c) 2011 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/indexed_db/indexed_db_dispatcher.h"
+
+#include "base/lazy_instance.h"
+#include "base/threading/thread_local.h"
+#include "content/common/indexed_db/indexed_db_messages.h"
+#include "content/renderer/indexed_db/renderer_webidbcursor_impl.h"
+#include "content/renderer/indexed_db/renderer_webidbdatabase_impl.h"
+#include "content/renderer/indexed_db/renderer_webidbindex_impl.h"
+#include "content/renderer/indexed_db/renderer_webidbobjectstore_impl.h"
+#include "content/renderer/indexed_db/renderer_webidbtransaction_impl.h"
+#include "content/renderer/render_thread_impl.h"
+#include "content/renderer/render_view_impl.h"
+#include "ipc/ipc_channel.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBDatabaseCallbacks.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBDatabaseError.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBKeyRange.h"
+
+using base::ThreadLocalPointer;
+using WebKit::WebDOMStringList;
+using WebKit::WebExceptionCode;
+using WebKit::WebFrame;
+using WebKit::WebIDBCallbacks;
+using WebKit::WebIDBKeyRange;
+using WebKit::WebIDBDatabase;
+using WebKit::WebIDBDatabaseCallbacks;
+using WebKit::WebIDBDatabaseError;
+using WebKit::WebIDBTransaction;
+using WebKit::WebIDBTransactionCallbacks;
+using webkit_glue::WorkerTaskRunner;
+
+static base::LazyInstance<ThreadLocalPointer<IndexedDBDispatcher>,
+ base::LeakyLazyInstanceTraits<ThreadLocalPointer<IndexedDBDispatcher> > >
+ g_idb_dispatcher_tls = LAZY_INSTANCE_INITIALIZER;
+
+namespace {
+
+int32 CurrentWorkerId() {
+ return WorkerTaskRunner::Instance()->CurrentWorkerId();
+}
+
+} // unnamed namespace
+
+IndexedDBDispatcher::IndexedDBDispatcher() {
+ g_idb_dispatcher_tls.Pointer()->Set(this);
+}
+
+IndexedDBDispatcher::~IndexedDBDispatcher() {
+ g_idb_dispatcher_tls.Pointer()->Set(NULL);
+}
+
+IndexedDBDispatcher* IndexedDBDispatcher::ThreadSpecificInstance() {
+ if (g_idb_dispatcher_tls.Pointer()->Get())
+ return g_idb_dispatcher_tls.Pointer()->Get();
+
+ IndexedDBDispatcher* dispatcher = new IndexedDBDispatcher;
+ if (WorkerTaskRunner::Instance()->CurrentWorkerId())
+ webkit_glue::WorkerTaskRunner::Instance()->AddStopObserver(dispatcher);
+ return dispatcher;
+}
+
+void IndexedDBDispatcher::OnWorkerRunLoopStopped() {
+ delete this;
+}
+
+void IndexedDBDispatcher::OnMessageReceived(const IPC::Message& msg) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(IndexedDBDispatcher, msg)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessIDBCursor,
+ OnSuccessOpenCursor)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessCursorContinue,
+ OnSuccessCursorContinue)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessCursorPrefetch,
+ OnSuccessCursorPrefetch)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessIDBDatabase,
+ OnSuccessIDBDatabase)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessIndexedDBKey,
+ OnSuccessIndexedDBKey)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessIDBTransaction,
+ OnSuccessIDBTransaction)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessStringList,
+ OnSuccessStringList)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessSerializedScriptValue,
+ OnSuccessSerializedScriptValue)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksError, OnError)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksBlocked, OnBlocked)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_TransactionCallbacksAbort, OnAbort)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_TransactionCallbacksComplete, OnComplete)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_DatabaseCallbacksVersionChange,
+ OnVersionChange)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ // If a message gets here, IndexedDBMessageFilter already determined that it
+ // is an IndexedDB message.
+ DCHECK(handled);
+}
+
+void IndexedDBDispatcher::Send(IPC::Message* msg) {
+ ChildThread::current()->Send(msg);
+}
+
+void IndexedDBDispatcher::RequestIDBCursorUpdate(
+ const content::SerializedScriptValue& value,
+ WebIDBCallbacks* callbacks_ptr,
+ int32 idb_cursor_id,
+ WebExceptionCode* ec) {
+ ResetCursorPrefetchCaches();
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+
+ int32 response_id = pending_callbacks_.Add(callbacks.release());
+ Send(
+ new IndexedDBHostMsg_CursorUpdate(idb_cursor_id, CurrentWorkerId(),
+ response_id, value, ec));
+ if (*ec)
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::RequestIDBCursorContinue(
+ const IndexedDBKey& key,
+ WebIDBCallbacks* callbacks_ptr,
+ int32 idb_cursor_id,
+ WebExceptionCode* ec) {
+ // Reset all cursor prefetch caches except for this cursor.
+ ResetCursorPrefetchCaches(idb_cursor_id);
+
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+
+ int32 response_id = pending_callbacks_.Add(callbacks.release());
+ Send(
+ new IndexedDBHostMsg_CursorContinue(idb_cursor_id, CurrentWorkerId(),
+ response_id, key, ec));
+ if (*ec)
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::RequestIDBCursorPrefetch(
+ int n,
+ WebIDBCallbacks* callbacks_ptr,
+ int32 idb_cursor_id,
+ WebExceptionCode* ec) {
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+
+ int32 response_id = pending_callbacks_.Add(callbacks.release());
+ Send(new IndexedDBHostMsg_CursorPrefetch(idb_cursor_id, CurrentWorkerId(),
+ response_id, n, ec));
+ if (*ec)
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::RequestIDBCursorPrefetchReset(
+ int used_prefetches, int unused_prefetches, int32 idb_cursor_id) {
+ Send(new IndexedDBHostMsg_CursorPrefetchReset(idb_cursor_id,
+ used_prefetches,
+ unused_prefetches));
+}
+
+void IndexedDBDispatcher::RequestIDBCursorDelete(
+ WebIDBCallbacks* callbacks_ptr,
+ int32 idb_cursor_id,
+ WebExceptionCode* ec) {
+ ResetCursorPrefetchCaches();
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+
+ int32 response_id = pending_callbacks_.Add(callbacks.release());
+ Send(new IndexedDBHostMsg_CursorDelete(idb_cursor_id, CurrentWorkerId(),
+ response_id, ec));
+ if (*ec)
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::RequestIDBFactoryOpen(
+ const string16& name,
+ WebIDBCallbacks* callbacks_ptr,
+ const string16& origin,
+ WebFrame* web_frame) {
+ ResetCursorPrefetchCaches();
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+
+ if (!web_frame)
+ return; // We must be shutting down.
+ RenderViewImpl* render_view = RenderViewImpl::FromWebView(web_frame->view());
+ if (!render_view)
+ return; // We must be shutting down.
+
+ IndexedDBHostMsg_FactoryOpen_Params params;
+ params.thread_id = CurrentWorkerId();
+ params.response_id = pending_callbacks_.Add(callbacks.release());
+ params.origin = origin;
+ params.name = name;
+ Send(new IndexedDBHostMsg_FactoryOpen(params));
+}
+
+void IndexedDBDispatcher::RequestIDBFactoryGetDatabaseNames(
+ WebIDBCallbacks* callbacks_ptr,
+ const string16& origin,
+ WebFrame* web_frame) {
+ ResetCursorPrefetchCaches();
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+
+ if (!web_frame)
+ return; // We must be shutting down.
+ RenderViewImpl* render_view = RenderViewImpl::FromWebView(web_frame->view());
+ if (!render_view)
+ return; // We must be shutting down.
+
+ IndexedDBHostMsg_FactoryGetDatabaseNames_Params params;
+ params.thread_id = CurrentWorkerId();
+ params.response_id = pending_callbacks_.Add(callbacks.release());
+ params.origin = origin;
+ Send(new IndexedDBHostMsg_FactoryGetDatabaseNames(params));
+}
+
+void IndexedDBDispatcher::RequestIDBFactoryDeleteDatabase(
+ const string16& name,
+ WebIDBCallbacks* callbacks_ptr,
+ const string16& origin,
+ WebFrame* web_frame) {
+ ResetCursorPrefetchCaches();
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+
+ if (!web_frame)
+ return; // We must be shutting down.
+ RenderViewImpl* render_view = RenderViewImpl::FromWebView(web_frame->view());
+ if (!render_view)
+ return; // We must be shutting down.
+
+ IndexedDBHostMsg_FactoryDeleteDatabase_Params params;
+ params.thread_id = CurrentWorkerId();
+ params.response_id = pending_callbacks_.Add(callbacks.release());
+ params.origin = origin;
+ params.name = name;
+ Send(new IndexedDBHostMsg_FactoryDeleteDatabase(params));
+}
+
+void IndexedDBDispatcher::RequestIDBDatabaseClose(int32 idb_database_id) {
+ ResetCursorPrefetchCaches();
+ Send(new IndexedDBHostMsg_DatabaseClose(idb_database_id));
+ pending_database_callbacks_.Remove(idb_database_id);
+}
+
+void IndexedDBDispatcher::RequestIDBDatabaseOpen(
+ WebIDBDatabaseCallbacks* callbacks_ptr,
+ int32 idb_database_id) {
+ ResetCursorPrefetchCaches();
+ scoped_ptr<WebIDBDatabaseCallbacks> callbacks(callbacks_ptr);
+
+ DCHECK(!pending_database_callbacks_.Lookup(idb_database_id));
+ pending_database_callbacks_.AddWithID(callbacks.release(), idb_database_id);
+ Send(new IndexedDBHostMsg_DatabaseOpen(idb_database_id, CurrentWorkerId(),
+ idb_database_id));
+}
+
+void IndexedDBDispatcher::RequestIDBDatabaseSetVersion(
+ const string16& version,
+ WebIDBCallbacks* callbacks_ptr,
+ int32 idb_database_id,
+ WebExceptionCode* ec) {
+ ResetCursorPrefetchCaches();
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+
+ int32 response_id = pending_callbacks_.Add(callbacks.release());
+ Send(new IndexedDBHostMsg_DatabaseSetVersion(idb_database_id,
+ CurrentWorkerId(),
+ response_id, version, ec));
+ if (*ec)
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::RequestIDBIndexOpenObjectCursor(
+ const WebIDBKeyRange& idb_key_range,
+ unsigned short direction,
+ WebIDBCallbacks* callbacks_ptr,
+ int32 idb_index_id,
+ const WebIDBTransaction& transaction,
+ WebExceptionCode* ec) {
+ ResetCursorPrefetchCaches();
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+ IndexedDBHostMsg_IndexOpenCursor_Params params;
+ params.thread_id = CurrentWorkerId();
+ params.response_id = pending_callbacks_.Add(callbacks.release());
+ params.lower_key.Set(idb_key_range.lower());
+ params.upper_key.Set(idb_key_range.upper());
+ params.lower_open = idb_key_range.lowerOpen();
+ params.upper_open = idb_key_range.upperOpen();
+ params.direction = direction;
+ params.idb_index_id = idb_index_id;
+ params.transaction_id = TransactionId(transaction);
+ Send(new IndexedDBHostMsg_IndexOpenObjectCursor(params, ec));
+ if (*ec)
+ pending_callbacks_.Remove(params.response_id);
+}
+
+void IndexedDBDispatcher::RequestIDBIndexOpenKeyCursor(
+ const WebIDBKeyRange& idb_key_range,
+ unsigned short direction,
+ WebIDBCallbacks* callbacks_ptr,
+ int32 idb_index_id,
+ const WebIDBTransaction& transaction,
+ WebExceptionCode* ec) {
+ ResetCursorPrefetchCaches();
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+ IndexedDBHostMsg_IndexOpenCursor_Params params;
+ params.thread_id = CurrentWorkerId();
+ params.response_id = pending_callbacks_.Add(callbacks.release());
+ // TODO(jorlow): We really should just create a Chromium abstraction for
+ // KeyRange rather than doing it ad-hoc like this.
+ params.lower_key.Set(idb_key_range.lower());
+ params.upper_key.Set(idb_key_range.upper());
+ params.lower_open = idb_key_range.lowerOpen();
+ params.upper_open = idb_key_range.upperOpen();
+ params.direction = direction;
+ params.idb_index_id = idb_index_id;
+ params.transaction_id = TransactionId(transaction);
+ Send(new IndexedDBHostMsg_IndexOpenKeyCursor(params, ec));
+ if (*ec)
+ pending_callbacks_.Remove(params.response_id);
+}
+
+void IndexedDBDispatcher::RequestIDBIndexCount(
+ const WebIDBKeyRange& idb_key_range,
+ WebIDBCallbacks* callbacks_ptr,
+ int32 idb_index_id,
+ const WebIDBTransaction& transaction,
+ WebExceptionCode* ec) {
+ ResetCursorPrefetchCaches();
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+ IndexedDBHostMsg_IndexCount_Params params;
+ params.thread_id = CurrentWorkerId();
+ params.response_id = pending_callbacks_.Add(callbacks.release());
+ params.lower_key.Set(idb_key_range.lower());
+ params.upper_key.Set(idb_key_range.upper());
+ params.lower_open = idb_key_range.lowerOpen();
+ params.upper_open = idb_key_range.upperOpen();
+ params.idb_index_id = idb_index_id;
+ params.transaction_id = TransactionId(transaction);
+ Send(new IndexedDBHostMsg_IndexCount(params, ec));
+ if (*ec)
+ pending_callbacks_.Remove(params.response_id);
+}
+
+void IndexedDBDispatcher::RequestIDBIndexGetObject(
+ const IndexedDBKey& key,
+ WebIDBCallbacks* callbacks_ptr,
+ int32 idb_index_id,
+ const WebIDBTransaction& transaction,
+ WebExceptionCode* ec) {
+ ResetCursorPrefetchCaches();
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+ int32 response_id = pending_callbacks_.Add(callbacks.release());
+ Send(new IndexedDBHostMsg_IndexGetObject(idb_index_id, CurrentWorkerId(),
+ response_id, key,
+ TransactionId(transaction), ec));
+ if (*ec)
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::RequestIDBIndexGetKey(
+ const IndexedDBKey& key,
+ WebIDBCallbacks* callbacks_ptr,
+ int32 idb_index_id,
+ const WebIDBTransaction& transaction,
+ WebExceptionCode* ec) {
+ ResetCursorPrefetchCaches();
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+ int32 response_id = pending_callbacks_.Add(callbacks.release());
+ Send(new IndexedDBHostMsg_IndexGetKey(
+ idb_index_id, CurrentWorkerId(), response_id, key,
+ TransactionId(transaction), ec));
+ if (*ec)
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::RequestIDBObjectStoreGet(
+ const IndexedDBKey& key,
+ WebIDBCallbacks* callbacks_ptr,
+ int32 idb_object_store_id,
+ const WebIDBTransaction& transaction,
+ WebExceptionCode* ec) {
+ ResetCursorPrefetchCaches();
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+
+ int32 response_id = pending_callbacks_.Add(callbacks.release());
+ Send(new IndexedDBHostMsg_ObjectStoreGet(
+ idb_object_store_id, CurrentWorkerId(), response_id,
+ key, TransactionId(transaction), ec));
+ if (*ec)
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::RequestIDBObjectStorePut(
+ const content::SerializedScriptValue& value,
+ const IndexedDBKey& key,
+ WebKit::WebIDBObjectStore::PutMode put_mode,
+ WebIDBCallbacks* callbacks_ptr,
+ int32 idb_object_store_id,
+ const WebIDBTransaction& transaction,
+ WebExceptionCode* ec) {
+ ResetCursorPrefetchCaches();
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+ IndexedDBHostMsg_ObjectStorePut_Params params;
+ params.thread_id = CurrentWorkerId();
+ params.idb_object_store_id = idb_object_store_id;
+ params.response_id = pending_callbacks_.Add(callbacks.release());
+ params.serialized_value = value;
+ params.key = key;
+ params.put_mode = put_mode;
+ params.transaction_id = TransactionId(transaction);
+ Send(new IndexedDBHostMsg_ObjectStorePut(params, ec));
+ if (*ec)
+ pending_callbacks_.Remove(params.response_id);
+}
+
+void IndexedDBDispatcher::RequestIDBObjectStoreDelete(
+ const IndexedDBKey& key,
+ WebIDBCallbacks* callbacks_ptr,
+ int32 idb_object_store_id,
+ const WebIDBTransaction& transaction,
+ WebExceptionCode* ec) {
+ ResetCursorPrefetchCaches();
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+
+ int32 response_id = pending_callbacks_.Add(callbacks.release());
+ Send(new IndexedDBHostMsg_ObjectStoreDelete(
+ idb_object_store_id, CurrentWorkerId(), response_id, key,
+ TransactionId(transaction), ec));
+ if (*ec)
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::RequestIDBObjectStoreClear(
+ WebIDBCallbacks* callbacks_ptr,
+ int32 idb_object_store_id,
+ const WebIDBTransaction& transaction,
+ WebExceptionCode* ec) {
+ ResetCursorPrefetchCaches();
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+
+ int32 response_id = pending_callbacks_.Add(callbacks.release());
+ Send(new IndexedDBHostMsg_ObjectStoreClear(
+ idb_object_store_id, CurrentWorkerId(), response_id,
+ TransactionId(transaction), ec));
+ if (*ec)
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::RequestIDBObjectStoreOpenCursor(
+ const WebIDBKeyRange& idb_key_range,
+ unsigned short direction,
+ WebIDBCallbacks* callbacks_ptr,
+ int32 idb_object_store_id,
+ const WebIDBTransaction& transaction,
+ WebExceptionCode* ec) {
+ ResetCursorPrefetchCaches();
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+ IndexedDBHostMsg_ObjectStoreOpenCursor_Params params;
+ params.thread_id = CurrentWorkerId();
+ params.response_id = pending_callbacks_.Add(callbacks.release());
+ params.lower_key.Set(idb_key_range.lower());
+ params.upper_key.Set(idb_key_range.upper());
+ params.lower_open = idb_key_range.lowerOpen();
+ params.upper_open = idb_key_range.upperOpen();
+ params.direction = direction;
+ params.idb_object_store_id = idb_object_store_id;
+ params.transaction_id = TransactionId(transaction);
+ Send(new IndexedDBHostMsg_ObjectStoreOpenCursor(params, ec));
+ if (*ec)
+ pending_callbacks_.Remove(params.response_id);
+}
+
+void IndexedDBDispatcher::RequestIDBObjectStoreCount(
+ const WebIDBKeyRange& idb_key_range,
+ WebIDBCallbacks* callbacks_ptr,
+ int32 idb_object_store_id,
+ const WebIDBTransaction& transaction,
+ WebExceptionCode* ec) {
+ ResetCursorPrefetchCaches();
+ scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
+ IndexedDBHostMsg_ObjectStoreCount_Params params;
+ params.thread_id = CurrentWorkerId();
+ params.response_id = pending_callbacks_.Add(callbacks.release());
+ params.lower_key.Set(idb_key_range.lower());
+ params.upper_key.Set(idb_key_range.upper());
+ params.lower_open = idb_key_range.lowerOpen();
+ params.upper_open = idb_key_range.upperOpen();
+ params.idb_object_store_id = idb_object_store_id;
+ params.transaction_id = TransactionId(transaction);
+ Send(new IndexedDBHostMsg_ObjectStoreCount(params, ec));
+ if (*ec)
+ pending_callbacks_.Remove(params.response_id);
+}
+
+void IndexedDBDispatcher::RegisterWebIDBTransactionCallbacks(
+ WebIDBTransactionCallbacks* callbacks,
+ int32 id) {
+ pending_transaction_callbacks_.AddWithID(callbacks, id);
+}
+
+void IndexedDBDispatcher::CursorDestroyed(int32 cursor_id) {
+ cursors_.erase(cursor_id);
+}
+
+int32 IndexedDBDispatcher::TransactionId(
+ const WebIDBTransaction& transaction) {
+ const RendererWebIDBTransactionImpl* impl =
+ static_cast<const RendererWebIDBTransactionImpl*>(&transaction);
+ return impl->id();
+}
+
+void IndexedDBDispatcher::OnSuccessIDBDatabase(int32 thread_id,
+ int32 response_id,
+ int32 object_id) {
+ DCHECK_EQ(thread_id, CurrentWorkerId());
+ WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(response_id);
+ if (!callbacks)
+ return;
+ callbacks->onSuccess(new RendererWebIDBDatabaseImpl(object_id));
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::OnSuccessIndexedDBKey(int32 thread_id,
+ int32 response_id,
+ const IndexedDBKey& key) {
+ DCHECK_EQ(thread_id, CurrentWorkerId());
+ WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(response_id);
+ if (!callbacks)
+ return;
+ callbacks->onSuccess(key);
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::OnSuccessIDBTransaction(int32 thread_id,
+ int32 response_id,
+ int32 object_id) {
+ DCHECK_EQ(thread_id, CurrentWorkerId());
+ WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(response_id);
+ if (!callbacks)
+ return;
+ callbacks->onSuccess(new RendererWebIDBTransactionImpl(object_id));
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::OnSuccessStringList(
+ int32 thread_id, int32 response_id, const std::vector<string16>& value) {
+ DCHECK_EQ(thread_id, CurrentWorkerId());
+ WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(response_id);
+ if (!callbacks)
+ return;
+ WebDOMStringList string_list;
+ for (std::vector<string16>::const_iterator it = value.begin();
+ it != value.end(); ++it)
+ string_list.append(*it);
+ callbacks->onSuccess(string_list);
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::OnSuccessSerializedScriptValue(
+ int32 thread_id, int32 response_id,
+ const content::SerializedScriptValue& value) {
+ DCHECK_EQ(thread_id, CurrentWorkerId());
+ WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(response_id);
+ if (!callbacks)
+ return;
+ callbacks->onSuccess(value);
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::OnSuccessOpenCursor(
+ const IndexedDBMsg_CallbacksSuccessIDBCursor_Params& p) {
+ DCHECK_EQ(p.thread_id, CurrentWorkerId());
+ int32 response_id = p.response_id;
+ int32 object_id = p.cursor_id;
+ const IndexedDBKey& key = p.key;
+ const IndexedDBKey& primary_key = p.primary_key;
+ const content::SerializedScriptValue& value = p.serialized_value;
+
+ WebIDBCallbacks* callbacks =
+ pending_callbacks_.Lookup(response_id);
+ if (!callbacks)
+ return;
+
+ RendererWebIDBCursorImpl* cursor = new RendererWebIDBCursorImpl(object_id);
+ cursors_[object_id] = cursor;
+ cursor->SetKeyAndValue(key, primary_key, value);
+ callbacks->onSuccess(cursor);
+
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::OnSuccessCursorContinue(
+ const IndexedDBMsg_CallbacksSuccessCursorContinue_Params& p) {
+ DCHECK_EQ(p.thread_id, CurrentWorkerId());
+ int32 response_id = p.response_id;
+ int32 cursor_id = p.cursor_id;
+ const IndexedDBKey& key = p.key;
+ const IndexedDBKey& primary_key = p.primary_key;
+ const content::SerializedScriptValue& value = p.serialized_value;
+
+ RendererWebIDBCursorImpl* cursor = cursors_[cursor_id];
+ DCHECK(cursor);
+ cursor->SetKeyAndValue(key, primary_key, value);
+
+ WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(response_id);
+ if (!callbacks)
+ return;
+ callbacks->onSuccessWithContinuation();
+
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::OnSuccessCursorPrefetch(
+ const IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params& p) {
+ DCHECK_EQ(p.thread_id, CurrentWorkerId());
+ int32 response_id = p.response_id;
+ int32 cursor_id = p.cursor_id;
+ const std::vector<IndexedDBKey>& keys = p.keys;
+ const std::vector<IndexedDBKey>& primary_keys = p.primary_keys;
+ const std::vector<content::SerializedScriptValue>& values = p.values;
+ RendererWebIDBCursorImpl* cursor = cursors_[cursor_id];
+ DCHECK(cursor);
+ cursor->SetPrefetchData(keys, primary_keys, values);
+
+ WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(response_id);
+ cursor->CachedContinue(callbacks);
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::OnBlocked(int32 thread_id, int32 response_id) {
+ DCHECK_EQ(thread_id, CurrentWorkerId());
+ WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(response_id);
+ callbacks->onBlocked();
+}
+
+void IndexedDBDispatcher::OnError(int32 thread_id, int32 response_id, int code,
+ const string16& message) {
+ DCHECK_EQ(thread_id, CurrentWorkerId());
+ WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(response_id);
+ if (!callbacks)
+ return;
+ callbacks->onError(WebIDBDatabaseError(code, message));
+ pending_callbacks_.Remove(response_id);
+}
+
+void IndexedDBDispatcher::OnAbort(int32 thread_id, int32 transaction_id) {
+ DCHECK_EQ(thread_id, CurrentWorkerId());
+ WebIDBTransactionCallbacks* callbacks =
+ pending_transaction_callbacks_.Lookup(transaction_id);
+ if (!callbacks)
+ return;
+ callbacks->onAbort();
+ pending_transaction_callbacks_.Remove(transaction_id);
+}
+
+void IndexedDBDispatcher::OnComplete(int32 thread_id, int32 transaction_id) {
+ DCHECK_EQ(thread_id, CurrentWorkerId());
+ WebIDBTransactionCallbacks* callbacks =
+ pending_transaction_callbacks_.Lookup(transaction_id);
+ if (!callbacks)
+ return;
+ callbacks->onComplete();
+ pending_transaction_callbacks_.Remove(transaction_id);
+}
+
+void IndexedDBDispatcher::OnVersionChange(int32 thread_id,
+ int32 database_id,
+ const string16& newVersion) {
+ DCHECK_EQ(thread_id, CurrentWorkerId());
+ WebIDBDatabaseCallbacks* callbacks =
+ pending_database_callbacks_.Lookup(database_id);
+ // callbacks would be NULL if a versionchange event is received after close
+ // has been called.
+ if (!callbacks)
+ return;
+ callbacks->onVersionChange(newVersion);
+}
+
+void IndexedDBDispatcher::ResetCursorPrefetchCaches(int32 exception_cursor_id) {
+ typedef std::map<int32, RendererWebIDBCursorImpl*>::iterator Iterator;
+ for (Iterator i = cursors_.begin(); i != cursors_.end(); ++i) {
+ if (i->first == exception_cursor_id)
+ continue;
+ i->second->ResetPrefetchCache();
+ }
+}