Chromium Code Reviews| 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..676091f8f47b7f20286e3e2c5d7abb6e12211dd0 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_) { |
|
jsbell
2013/12/19 00:39:17
Note the trailing _ inside the ()
ericu
2013/12/19 05:19:11
*Man* I hate that class of typo. That should alwa
jsbell
2013/12/20 00:59:28
I was surprised that wasn't caught. I'll file a FR
|
| 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,23 @@ 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 +285,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 +313,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 +331,27 @@ 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); |
| + } |
| +} |
| + |
| +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 +463,10 @@ void IndexedDBDispatcherHost::DatabaseDispatcherHost::CloseAll() { |
| bool IndexedDBDispatcherHost::DatabaseDispatcherHost::OnMessageReceived( |
| const IPC::Message& message, |
| bool* msg_is_ok) { |
| - DCHECK( |
| + |
| + 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 +479,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 +493,7 @@ bool IndexedDBDispatcherHost::DatabaseDispatcherHost::OnMessageReceived( |
| IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseCommit, OnCommit) |
| IPC_MESSAGE_UNHANDLED(handled = false) |
| IPC_END_MESSAGE_MAP() |
| + |
| return handled; |
| } |
| @@ -518,11 +601,31 @@ void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnGet( |
| callbacks); |
| } |
| -void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnPut( |
| +void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnPutWrapper( |
|
jsbell
2013/12/19 00:55:49
This could definitely use a comment that OnPutWrap
ericu
2013/12/19 05:19:11
Done.
|
| 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 +634,27 @@ 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 +882,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 +892,10 @@ 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; |
| } |