| Index: content/browser/indexed_db/indexed_db_dispatcher_host.cc
|
| diff --git a/content/browser/indexed_db/indexed_db_dispatcher_host.cc b/content/browser/indexed_db/indexed_db_dispatcher_host.cc
|
| index 37ab7717e5c437ac0d42a5d7f9a9c8712ae5a280..1e55c899e141e3b792dc5bfedf817b243e58cc25 100644
|
| --- a/content/browser/indexed_db/indexed_db_dispatcher_host.cc
|
| +++ b/content/browser/indexed_db/indexed_db_dispatcher_host.cc
|
| @@ -7,7 +7,9 @@
|
| #include "base/bind.h"
|
| #include "base/command_line.h"
|
| #include "base/files/file_path.h"
|
| +#include "base/memory/scoped_vector.h"
|
| #include "base/process/process.h"
|
| +#include "base/stl_util.h"
|
| #include "base/strings/utf_string_conversions.h"
|
| #include "content/browser/indexed_db/indexed_db_callbacks.h"
|
| #include "content/browser/indexed_db/indexed_db_connection.h"
|
| @@ -15,6 +17,7 @@
|
| #include "content/browser/indexed_db/indexed_db_cursor.h"
|
| #include "content/browser/indexed_db/indexed_db_database_callbacks.h"
|
| #include "content/browser/indexed_db/indexed_db_metadata.h"
|
| +#include "content/browser/indexed_db/indexed_db_value.h"
|
| #include "content/browser/renderer_host/render_message_filter.h"
|
| #include "content/common/indexed_db/indexed_db_messages.h"
|
| #include "content/public/browser/browser_thread.h"
|
| @@ -23,6 +26,7 @@
|
| #include "content/public/common/result_codes.h"
|
| #include "third_party/WebKit/public/platform/WebIDBDatabaseException.h"
|
| #include "url/gurl.h"
|
| +#include "webkit/browser/blob/blob_storage_context.h"
|
| #include "webkit/browser/database/database_util.h"
|
| #include "webkit/common/database/database_identifier.h"
|
|
|
| @@ -32,14 +36,48 @@ using blink::WebIDBKey;
|
| namespace content {
|
|
|
| IndexedDBDispatcherHost::IndexedDBDispatcherHost(
|
| - IndexedDBContextImpl* indexed_db_context)
|
| - : indexed_db_context_(indexed_db_context),
|
| + int ipc_process_id,
|
| + net::URLRequestContextGetter* request_context_getter,
|
| + IndexedDBContextImpl* indexed_db_context,
|
| + ChromeBlobStorageContext* blob_storage_context)
|
| + : request_context_getter_(request_context_getter),
|
| + request_context_(NULL),
|
| + indexed_db_context_(indexed_db_context),
|
| + blob_storage_context_(blob_storage_context),
|
| database_dispatcher_host_(new DatabaseDispatcherHost(this)),
|
| - cursor_dispatcher_host_(new CursorDispatcherHost(this)) {
|
| + cursor_dispatcher_host_(new CursorDispatcherHost(this)),
|
| + ipc_process_id_(ipc_process_id) {
|
| DCHECK(indexed_db_context_);
|
| }
|
|
|
| -IndexedDBDispatcherHost::~IndexedDBDispatcherHost() {}
|
| +IndexedDBDispatcherHost::IndexedDBDispatcherHost(
|
| + int ipc_process_id,
|
| + net::URLRequestContext* request_context,
|
| + IndexedDBContextImpl* indexed_db_context,
|
| + ChromeBlobStorageContext* blob_storage_context)
|
| + : request_context_(request_context),
|
| + indexed_db_context_(indexed_db_context),
|
| + blob_storage_context_(blob_storage_context),
|
| + database_dispatcher_host_(new DatabaseDispatcherHost(this)),
|
| + cursor_dispatcher_host_(new CursorDispatcherHost(this)),
|
| + ipc_process_id_(ipc_process_id) {
|
| + DCHECK(indexed_db_context_);
|
| +}
|
| +
|
| +IndexedDBDispatcherHost::~IndexedDBDispatcherHost() {
|
| + STLDeleteValues(&blob_data_handle_map_);
|
| +}
|
| +
|
| +void IndexedDBDispatcherHost::OnChannelConnected(int32 peer_pid) {
|
| + BrowserMessageFilter::OnChannelConnected(peer_pid);
|
| +
|
| + if (request_context_getter_.get()) {
|
| + DCHECK(!request_context_);
|
| + request_context_ = request_context_getter_->GetURLRequestContext();
|
| + request_context_getter_ = NULL;
|
| + DCHECK(request_context_);
|
| + }
|
| +}
|
|
|
| void IndexedDBDispatcherHost::OnChannelClosing() {
|
| bool success = indexed_db_context_->TaskRunner()->PostTask(
|
| @@ -76,8 +114,10 @@ void IndexedDBDispatcherHost::ResetDispatcherHosts() {
|
|
|
| base::TaskRunner* IndexedDBDispatcherHost::OverrideTaskRunnerForMessage(
|
| const IPC::Message& message) {
|
| - if (IPC_MESSAGE_CLASS(message) == IndexedDBMsgStart)
|
| - return indexed_db_context_->TaskRunner();
|
| + if (IPC_MESSAGE_CLASS(message) == IndexedDBMsgStart) {
|
| + if (message.type() != IndexedDBHostMsg_DatabasePut::ID)
|
| + return indexed_db_context_->TaskRunner();
|
| + }
|
| return NULL;
|
| }
|
|
|
| @@ -86,7 +126,8 @@ bool IndexedDBDispatcherHost::OnMessageReceived(const IPC::Message& message,
|
| if (IPC_MESSAGE_CLASS(message) != IndexedDBMsgStart)
|
| return false;
|
|
|
| - DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
|
| + DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread() ||
|
| + message.type() == IndexedDBHostMsg_DatabasePut::ID);
|
|
|
| bool handled =
|
| database_dispatcher_host_->OnMessageReceived(message, message_was_ok) ||
|
| @@ -100,6 +141,7 @@ bool IndexedDBDispatcherHost::OnMessageReceived(const IPC::Message& message,
|
| IPC_MESSAGE_HANDLER(IndexedDBHostMsg_FactoryOpen, OnIDBFactoryOpen)
|
| IPC_MESSAGE_HANDLER(IndexedDBHostMsg_FactoryDeleteDatabase,
|
| OnIDBFactoryDeleteDatabase)
|
| + IPC_MESSAGE_HANDLER(IndexedDBHostMsg_AckReceivedBlobs, OnAckReceivedBlobs)
|
| IPC_MESSAGE_UNHANDLED(handled = false)
|
| IPC_END_MESSAGE_MAP()
|
| }
|
| @@ -166,6 +208,22 @@ uint32 IndexedDBDispatcherHost::TransactionIdToProcessId(
|
| return (host_transaction_id >> 32) & 0xffffffff;
|
| }
|
|
|
| +void IndexedDBDispatcherHost::HoldBlobDataHandle(
|
| + const std::string& uuid,
|
| + scoped_ptr<webkit_blob::BlobDataHandle>& blob_data_handle) {
|
| + DCHECK(blob_data_handle_map_.find(uuid) == blob_data_handle_map_.end());
|
| + blob_data_handle_map_[uuid] = blob_data_handle.release();
|
| +}
|
| +
|
| +void IndexedDBDispatcherHost::DropBlobDataHandle(const std::string& uuid) {
|
| + BlobDataHandleMap::iterator iter = blob_data_handle_map_.find(uuid);
|
| + if (iter != blob_data_handle_map_.end()) {
|
| + delete iter->second;
|
| + blob_data_handle_map_.erase(iter);
|
| + } else {
|
| + DLOG(FATAL) << "Failed to find blob UUID in map:" << uuid;
|
| + }
|
| +}
|
|
|
| IndexedDBCursor* IndexedDBDispatcherHost::GetCursorFromId(int32 ipc_cursor_id) {
|
| DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
|
| @@ -226,7 +284,8 @@ void IndexedDBDispatcherHost::OnIDBFactoryGetDatabaseNames(
|
| new IndexedDBCallbacks(
|
| this, params.ipc_thread_id, params.ipc_callbacks_id),
|
| origin_url,
|
| - indexed_db_path);
|
| + indexed_db_path,
|
| + Context()->TaskRunner());
|
| }
|
|
|
| void IndexedDBDispatcherHost::OnIDBFactoryOpen(
|
| @@ -253,11 +312,14 @@ void IndexedDBDispatcherHost::OnIDBFactoryOpen(
|
| this, params.ipc_thread_id, params.ipc_database_callbacks_id);
|
| Context()->GetIDBFactory()->Open(params.name,
|
| params.version,
|
| + request_context_,
|
| host_transaction_id,
|
| callbacks,
|
| database_callbacks,
|
| origin_url,
|
| - indexed_db_path);
|
| + indexed_db_path,
|
| + ipc_process_id_,
|
| + Context()->TaskRunner());
|
| }
|
|
|
| void IndexedDBDispatcherHost::OnIDBFactoryDeleteDatabase(
|
| @@ -268,10 +330,29 @@ void IndexedDBDispatcherHost::OnIDBFactoryDeleteDatabase(
|
| base::FilePath indexed_db_path = indexed_db_context_->data_path();
|
| Context()->GetIDBFactory()->DeleteDatabase(
|
| params.name,
|
| + request_context_,
|
| new IndexedDBCallbacks(
|
| this, params.ipc_thread_id, params.ipc_callbacks_id),
|
| origin_url,
|
| - indexed_db_path);
|
| + indexed_db_path,
|
| + Context()->TaskRunner());
|
| +}
|
| +
|
| +void IndexedDBDispatcherHost::OnAckReceivedBlobs(
|
| + const std::vector<std::string>& uuids) {
|
| + DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
|
| + std::vector<std::string>::const_iterator iter;
|
| + for (iter = uuids.begin(); iter != uuids.end(); ++iter) {
|
| + DropBlobDataHandle(*iter);
|
| + }
|
| +}
|
| +
|
| +// OnPutHelper exists only to allow us to hop threads while holding a reference
|
| +// to the IndexedDBDispatcherHost.
|
| +void IndexedDBDispatcherHost::OnPutHelper(
|
| + const IndexedDBHostMsg_DatabasePut_Params& params,
|
| + std::vector<webkit_blob::BlobDataHandle*> handles) {
|
| + database_dispatcher_host_->OnPut(params, handles);
|
| }
|
|
|
| void IndexedDBDispatcherHost::FinishTransaction(int64 host_transaction_id,
|
| @@ -383,8 +464,11 @@ void IndexedDBDispatcherHost::DatabaseDispatcherHost::CloseAll() {
|
| bool IndexedDBDispatcherHost::DatabaseDispatcherHost::OnMessageReceived(
|
| const IPC::Message& message,
|
| bool* msg_is_ok) {
|
| +
|
| DCHECK(
|
| + (message.type() == IndexedDBHostMsg_DatabasePut::ID) ||
|
| parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
|
| +
|
| bool handled = true;
|
| IPC_BEGIN_MESSAGE_MAP_EX(
|
| IndexedDBDispatcherHost::DatabaseDispatcherHost, message, *msg_is_ok)
|
| @@ -397,7 +481,7 @@ bool IndexedDBDispatcherHost::DatabaseDispatcherHost::OnMessageReceived(
|
| IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseClose, OnClose)
|
| IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseDestroyed, OnDestroyed)
|
| IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseGet, OnGet)
|
| - IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabasePut, OnPut)
|
| + IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabasePut, OnPutWrapper)
|
| IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseSetIndexKeys, OnSetIndexKeys)
|
| IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseSetIndexesReady,
|
| OnSetIndexesReady)
|
| @@ -411,6 +495,7 @@ bool IndexedDBDispatcherHost::DatabaseDispatcherHost::OnMessageReceived(
|
| IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseCommit, OnCommit)
|
| IPC_MESSAGE_UNHANDLED(handled = false)
|
| IPC_END_MESSAGE_MAP()
|
| +
|
| return handled;
|
| }
|
|
|
| @@ -518,11 +603,31 @@ void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnGet(
|
| callbacks);
|
| }
|
|
|
| -void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnPut(
|
| +void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnPutWrapper(
|
| const IndexedDBHostMsg_DatabasePut_Params& params) {
|
| + std::vector<webkit_blob::BlobDataHandle*> handles;
|
| + for (size_t i = 0; i < params.blob_or_file_info.size(); ++i) {
|
| + const IndexedDBMsg_BlobOrFileInfo& info = params.blob_or_file_info[i];
|
| + handles.push_back(parent_->blob_storage_context_->context()
|
| + ->GetBlobDataFromUUID(info.uuid)
|
| + .release());
|
| + }
|
| + parent_->indexed_db_context_->TaskRunner()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(
|
| + &IndexedDBDispatcherHost::OnPutHelper, parent_, params, handles));
|
| +}
|
| +
|
| +void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnPut(
|
| + const IndexedDBHostMsg_DatabasePut_Params& params,
|
| + std::vector<webkit_blob::BlobDataHandle*> handles) {
|
| +
|
| DCHECK(
|
| parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
|
|
|
| + ScopedVector<webkit_blob::BlobDataHandle> scoped_handles;
|
| + scoped_handles.swap(handles);
|
| +
|
| IndexedDBConnection* connection =
|
| parent_->GetOrTerminateProcess(&map_, params.ipc_database_id);
|
| if (!connection || !connection->IsConnected())
|
| @@ -531,12 +636,28 @@ void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnPut(
|
| parent_, params.ipc_thread_id, params.ipc_callbacks_id));
|
|
|
| int64 host_transaction_id = parent_->HostTransactionId(params.transaction_id);
|
| +
|
| + std::vector<IndexedDBBlobInfo> blob_info(params.blob_or_file_info.size());
|
| +
|
| + for (size_t i = 0; i < params.blob_or_file_info.size(); ++i) {
|
| + const IndexedDBMsg_BlobOrFileInfo& info = params.blob_or_file_info[i];
|
| + if (info.is_file)
|
| + blob_info[i] =
|
| + IndexedDBBlobInfo(base::FilePath::FromUTF16Unsafe(info.file_path),
|
| + info.file_name,
|
| + info.mime_type);
|
| + else
|
| + blob_info[i] = IndexedDBBlobInfo(info.uuid, info.mime_type, info.size);
|
| + }
|
| // TODO(alecflett): Avoid a copy here.
|
| - std::string value_copy(params.value);
|
| + IndexedDBValue value;
|
| + value.bits = params.value;
|
| + value.blob_info.swap(blob_info);
|
| connection->database()->Put(
|
| host_transaction_id,
|
| params.object_store_id,
|
| - &value_copy,
|
| + &value,
|
| + &scoped_handles,
|
| make_scoped_ptr(new IndexedDBKey(params.key)),
|
| static_cast<IndexedDBDatabase::PutMode>(params.put_mode),
|
| callbacks,
|
| @@ -764,9 +885,6 @@ IndexedDBDispatcherHost::CursorDispatcherHost::~CursorDispatcherHost() {}
|
| bool IndexedDBDispatcherHost::CursorDispatcherHost::OnMessageReceived(
|
| const IPC::Message& message,
|
| bool* msg_is_ok) {
|
| - DCHECK(
|
| - parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
|
| -
|
| bool handled = true;
|
| IPC_BEGIN_MESSAGE_MAP_EX(
|
| IndexedDBDispatcherHost::CursorDispatcherHost, message, *msg_is_ok)
|
| @@ -777,6 +895,11 @@ bool IndexedDBDispatcherHost::CursorDispatcherHost::OnMessageReceived(
|
| IPC_MESSAGE_HANDLER(IndexedDBHostMsg_CursorDestroyed, OnDestroyed)
|
| IPC_MESSAGE_UNHANDLED(handled = false)
|
| IPC_END_MESSAGE_MAP()
|
| +
|
| + DCHECK(
|
| + !handled ||
|
| + parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
|
| +
|
| return handled;
|
| }
|
|
|
|
|