Index: content/browser/indexed_db/indexed_db_callbacks.cc |
diff --git a/content/browser/indexed_db/indexed_db_callbacks.cc b/content/browser/indexed_db/indexed_db_callbacks.cc |
index eb639072bfc5c21cde8db2f750a2e322605bb14b..1c16bd0b058ec092f055d378a8ee214a31e17458 100644 |
--- a/content/browser/indexed_db/indexed_db_callbacks.cc |
+++ b/content/browser/indexed_db/indexed_db_callbacks.cc |
@@ -14,6 +14,7 @@ |
#include "base/time/time.h" |
#include "content/browser/child_process_security_policy_impl.h" |
#include "content/browser/fileapi/fileapi_message_filter.h" |
+#include "content/browser/indexed_db/database_impl.h" |
#include "content/browser/indexed_db/indexed_db_blob_info.h" |
#include "content/browser/indexed_db/indexed_db_connection.h" |
#include "content/browser/indexed_db/indexed_db_context_impl.h" |
@@ -25,11 +26,13 @@ |
#include "content/common/indexed_db/indexed_db_constants.h" |
#include "content/common/indexed_db/indexed_db_messages.h" |
#include "content/common/indexed_db/indexed_db_metadata.h" |
+#include "mojo/public/cpp/bindings/strong_associated_binding.h" |
#include "storage/browser/blob/blob_storage_context.h" |
#include "storage/browser/blob/shareable_file_reference.h" |
#include "storage/browser/quota/quota_manager.h" |
using indexed_db::mojom::CallbacksAssociatedPtrInfo; |
+using std::swap; |
using storage::ShareableFileReference; |
namespace content { |
@@ -37,26 +40,82 @@ namespace content { |
namespace { |
const int32_t kNoCursor = -1; |
const int64_t kNoTransaction = -1; |
+ |
+void ConvertBlobInfo( |
+ const std::vector<IndexedDBBlobInfo>& blob_info, |
+ std::vector<::indexed_db::mojom::BlobInfoPtr>* blob_or_file_info) { |
+ blob_or_file_info->reserve(blob_info.size()); |
+ for (const auto& iter : blob_info) { |
+ if (!iter.mark_used_callback().is_null()) |
+ iter.mark_used_callback().Run(); |
+ |
+ auto info = ::indexed_db::mojom::BlobInfo::New(); |
+ info->mime_type = iter.type(); |
+ info->size = iter.size(); |
+ if (iter.is_file()) { |
+ info->file = ::indexed_db::mojom::FileInfo::New(); |
+ info->file->name = iter.file_name(); |
+ info->file->path = iter.file_path(); |
+ info->file->last_modified = iter.last_modified(); |
+ } |
+ blob_or_file_info->push_back(std::move(info)); |
+ } |
} |
+// Destructively converts an IndexedDBReturnValue to a Mojo ReturnValue. |
+::indexed_db::mojom::ReturnValuePtr ConvertReturnValue( |
+ IndexedDBReturnValue* value) { |
+ auto mojo_value = ::indexed_db::mojom::ReturnValue::New(); |
+ mojo_value->value = ::indexed_db::mojom::Value::New(); |
+ if (value->primary_key.IsValid()) { |
+ mojo_value->primary_key = value->primary_key; |
+ mojo_value->key_path = value->key_path; |
+ } |
+ if (!value->empty()) |
+ swap(mojo_value->value->bits, value->bits); |
+ ConvertBlobInfo(value->blob_info, &mojo_value->value->blob_or_file_info); |
+ return mojo_value; |
+} |
+ |
+} // namespace |
+ |
class IndexedDBCallbacks::IOThreadHelper { |
public: |
- explicit IOThreadHelper(CallbacksAssociatedPtrInfo callbacks_info); |
+ IOThreadHelper(CallbacksAssociatedPtrInfo callbacks_info, |
+ scoped_refptr<IndexedDBDispatcherHost> dispatcher_host); |
~IOThreadHelper(); |
void SendError(const IndexedDBDatabaseError& error); |
void SendSuccessStringList(const std::vector<base::string16>& value); |
void SendBlocked(int64_t existing_version); |
- void SendUpgradeNeeded(int32_t database_id, |
+ void SendUpgradeNeeded(std::unique_ptr<DatabaseImpl> database, |
int64_t old_version, |
blink::WebIDBDataLoss data_loss, |
const std::string& data_loss_message, |
const content::IndexedDBDatabaseMetadata& metadata); |
- void SendSuccessDatabase(int32_t database_id, |
+ void SendSuccessDatabase(std::unique_ptr<DatabaseImpl> database, |
const content::IndexedDBDatabaseMetadata& metadata); |
+ void SendSuccessCursor(int32_t cursor_id, |
+ const IndexedDBKey& key, |
+ const IndexedDBKey& primary_key, |
+ ::indexed_db::mojom::ValuePtr value, |
+ const std::vector<IndexedDBBlobInfo>& blob_info); |
+ void SendSuccessValue(::indexed_db::mojom::ReturnValuePtr value, |
+ const std::vector<IndexedDBBlobInfo>& blob_info); |
+ void SendSuccessArray( |
+ std::vector<::indexed_db::mojom::ReturnValuePtr> mojo_values, |
+ const std::vector<IndexedDBReturnValue>& values); |
+ void SendSuccessKey(const IndexedDBKey& value); |
void SendSuccessInteger(int64_t value); |
+ void SendSuccess(); |
+ |
+ std::string CreateBlobData(const IndexedDBBlobInfo& blob_info); |
+ bool CreateAllBlobs( |
+ const std::vector<IndexedDBBlobInfo>& blob_info, |
+ std::vector<::indexed_db::mojom::BlobInfoPtr>* blob_or_file_info); |
private: |
+ scoped_refptr<IndexedDBDispatcherHost> dispatcher_host_; |
::indexed_db::mojom::CallbacksAssociatedPtr callbacks_; |
DISALLOW_COPY_AND_ASSIGN(IOThreadHelper); |
@@ -70,7 +129,6 @@ IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost* dispatcher_host, |
ipc_thread_id_(ipc_thread_id), |
ipc_cursor_id_(kNoCursor), |
host_transaction_id_(kNoTransaction), |
- ipc_database_id_(kNoDatabase), |
data_loss_(blink::WebIDBDataLossNone), |
sent_blocked_(false), |
io_helper_(nullptr) {} |
@@ -84,7 +142,6 @@ IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost* dispatcher_host, |
ipc_thread_id_(ipc_thread_id), |
ipc_cursor_id_(ipc_cursor_id), |
host_transaction_id_(kNoTransaction), |
- ipc_database_id_(kNoDatabase), |
data_loss_(blink::WebIDBDataLossNone), |
sent_blocked_(false), |
io_helper_(nullptr) {} |
@@ -97,10 +154,10 @@ IndexedDBCallbacks::IndexedDBCallbacks( |
ipc_cursor_id_(kNoCursor), |
host_transaction_id_(kNoTransaction), |
origin_(origin), |
- ipc_database_id_(kNoDatabase), |
data_loss_(blink::WebIDBDataLossNone), |
sent_blocked_(false), |
- io_helper_(new IOThreadHelper(std::move(callbacks_info))) { |
+ io_helper_( |
+ new IOThreadHelper(std::move(callbacks_info), dispatcher_host_)) { |
DCHECK_CURRENTLY_ON(BrowserThread::IO); |
thread_checker_.DetachFromThread(); |
} |
@@ -138,7 +195,6 @@ void IndexedDBCallbacks::OnSuccess(const std::vector<base::string16>& value) { |
DCHECK(io_helper_); |
DCHECK_EQ(kNoCursor, ipc_cursor_id_); |
DCHECK_EQ(kNoTransaction, host_transaction_id_); |
- DCHECK_EQ(kNoDatabase, ipc_database_id_); |
BrowserThread::PostTask( |
BrowserThread::IO, FROM_HERE, |
@@ -179,23 +235,21 @@ void IndexedDBCallbacks::OnUpgradeNeeded( |
DCHECK(thread_checker_.CalledOnValidThread()); |
DCHECK(dispatcher_host_); |
DCHECK(io_helper_); |
+ |
DCHECK_NE(kNoTransaction, host_transaction_id_); |
DCHECK_EQ(kNoCursor, ipc_cursor_id_); |
- DCHECK_EQ(kNoDatabase, ipc_database_id_); |
+ DCHECK(!database_sent_); |
data_loss_ = data_loss_info.status; |
dispatcher_host_->RegisterTransactionId(host_transaction_id_, origin_); |
- int32_t ipc_database_id = |
- dispatcher_host_->Add(connection.release(), origin_); |
- if (ipc_database_id < 0) |
- return; |
- |
- ipc_database_id_ = ipc_database_id; |
+ database_sent_ = true; |
+ auto database = base::MakeUnique<DatabaseImpl>(std::move(connection), origin_, |
+ dispatcher_host_); |
BrowserThread::PostTask( |
BrowserThread::IO, FROM_HERE, |
base::Bind(&IOThreadHelper::SendUpgradeNeeded, |
- base::Unretained(io_helper_.get()), ipc_database_id, |
+ base::Unretained(io_helper_.get()), base::Passed(&database), |
old_version, data_loss_info.status, data_loss_info.message, |
metadata)); |
@@ -213,22 +267,24 @@ void IndexedDBCallbacks::OnSuccess( |
DCHECK(thread_checker_.CalledOnValidThread()); |
DCHECK(dispatcher_host_); |
DCHECK(io_helper_); |
+ |
DCHECK_EQ(kNoCursor, ipc_cursor_id_); |
DCHECK_NE(kNoTransaction, host_transaction_id_); |
- DCHECK_NE(ipc_database_id_ == kNoDatabase, !connection); |
+ DCHECK_EQ(database_sent_, !connection); |
scoped_refptr<IndexedDBCallbacks> self(this); |
- int32_t ipc_object_id = kNoDatabase; |
- // Only register if the connection was not previously sent in OnUpgradeNeeded. |
- if (ipc_database_id_ == kNoDatabase) { |
- ipc_object_id = dispatcher_host_->Add(connection.release(), origin_); |
- } |
- |
- BrowserThread::PostTask( |
- BrowserThread::IO, FROM_HERE, |
- base::Bind(&IOThreadHelper::SendSuccessDatabase, |
- base::Unretained(io_helper_.get()), ipc_object_id, metadata)); |
+ // Only send a new Database if the connection was not previously sent in |
+ // OnUpgradeNeeded. |
+ std::unique_ptr<DatabaseImpl> database; |
+ if (!database_sent_) |
+ database.reset( |
+ new DatabaseImpl(std::move(connection), origin_, dispatcher_host_)); |
+ |
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
+ base::Bind(&IOThreadHelper::SendSuccessDatabase, |
+ base::Unretained(io_helper_.get()), |
+ base::Passed(&database), metadata)); |
dispatcher_host_ = nullptr; |
if (!connection_open_start_time_.is_null()) { |
@@ -305,22 +361,6 @@ static void BlobLookupForCursorPrefetch( |
new IndexedDBMsg_CallbacksSuccessCursorPrefetch(*params)); |
} |
-static void BlobLookupForGetAll( |
- IndexedDBMsg_CallbacksSuccessArray_Params* params, |
- scoped_refptr<IndexedDBDispatcherHost> dispatcher_host, |
- const std::vector<IndexedDBReturnValue>& values) { |
- DCHECK_CURRENTLY_ON(BrowserThread::IO); |
- DCHECK_EQ(values.size(), params->values.size()); |
- |
- for (size_t i = 0; i < values.size(); ++i) { |
- if (!CreateAllBlobs(values[i].blob_info, |
- ¶ms->values[i].blob_or_file_info, dispatcher_host)) |
- return; |
- } |
- |
- dispatcher_host->Send(new IndexedDBMsg_CallbacksSuccessArray(*params)); |
-} |
- |
static void FillInBlobData( |
const std::vector<IndexedDBBlobInfo>& blob_info, |
std::vector<IndexedDBMsg_BlobOrFileInfo>* blob_or_file_info) { |
@@ -360,38 +400,28 @@ void IndexedDBCallbacks::OnSuccess(scoped_refptr<IndexedDBCursor> cursor, |
IndexedDBValue* value) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
DCHECK(dispatcher_host_); |
- DCHECK(!io_helper_); |
+ DCHECK(io_helper_); |
DCHECK_EQ(kNoCursor, ipc_cursor_id_); |
DCHECK_EQ(kNoTransaction, host_transaction_id_); |
- DCHECK_EQ(kNoDatabase, ipc_database_id_); |
DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_); |
- int32_t ipc_object_id = dispatcher_host_->Add(cursor.get()); |
- std::unique_ptr<IndexedDBMsg_CallbacksSuccessIDBCursor_Params> params( |
- new IndexedDBMsg_CallbacksSuccessIDBCursor_Params()); |
- params->ipc_thread_id = ipc_thread_id_; |
- params->ipc_callbacks_id = ipc_callbacks_id_; |
- params->ipc_cursor_id = ipc_object_id; |
- params->key = key; |
- params->primary_key = primary_key; |
- if (value && !value->empty()) |
- std::swap(params->value.bits, value->bits); |
- // TODO(alecflett): Avoid a copy here: the whole params object is |
- // being copied into the message. |
- if (!value || value->blob_info.empty()) { |
- dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessIDBCursor(*params)); |
- } else { |
- IndexedDBMsg_CallbacksSuccessIDBCursor_Params* p = params.get(); |
- FillInBlobData(value->blob_info, &p->value.blob_or_file_info); |
- RegisterBlobsAndSend( |
- value->blob_info, |
- base::Bind( |
- CreateBlobsAndSend<IndexedDBMsg_CallbacksSuccessIDBCursor_Params, |
- IndexedDBMsg_CallbacksSuccessIDBCursor>, |
- base::Owned(params.release()), dispatcher_host_, value->blob_info, |
- base::Unretained(&p->value.blob_or_file_info))); |
+ ::indexed_db::mojom::ValuePtr mojo_value; |
+ std::vector<IndexedDBBlobInfo> blob_info; |
+ if (value) { |
+ mojo_value = ::indexed_db::mojom::Value::New(); |
+ if (!value->empty()) |
+ swap(mojo_value->bits, value->bits); |
+ ConvertBlobInfo(value->blob_info, &mojo_value->blob_or_file_info); |
+ blob_info = value->blob_info; |
} |
+ |
+ BrowserThread::PostTask( |
+ BrowserThread::IO, FROM_HERE, |
+ base::Bind(&IOThreadHelper::SendSuccessCursor, |
+ base::Unretained(io_helper_.get()), |
+ dispatcher_host_->Add(cursor.get()), key, primary_key, |
+ base::Passed(&mojo_value), base::Passed(&blob_info))); |
dispatcher_host_ = nullptr; |
} |
@@ -404,7 +434,6 @@ void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& key, |
DCHECK_NE(kNoCursor, ipc_cursor_id_); |
DCHECK_EQ(kNoTransaction, host_transaction_id_); |
- DCHECK_EQ(kNoDatabase, ipc_database_id_); |
DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_); |
IndexedDBCursor* idb_cursor = |
@@ -422,7 +451,7 @@ void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& key, |
params->key = key; |
params->primary_key = primary_key; |
if (value && !value->empty()) |
- std::swap(params->value.bits, value->bits); |
+ swap(params->value.bits, value->bits); |
// TODO(alecflett): Avoid a copy here: the whole params object is |
// being copied into the message. |
if (!value || value->blob_info.empty()) { |
@@ -455,7 +484,6 @@ void IndexedDBCallbacks::OnSuccessWithPrefetch( |
DCHECK_NE(kNoCursor, ipc_cursor_id_); |
DCHECK_EQ(kNoTransaction, host_transaction_id_); |
- DCHECK_EQ(kNoDatabase, ipc_database_id_); |
DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_); |
std::vector<IndexedDBKey> msg_keys; |
@@ -506,7 +534,6 @@ void IndexedDBCallbacks::OnSuccessWithPrefetch( |
void IndexedDBCallbacks::OnSuccess(IndexedDBReturnValue* value) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
DCHECK(dispatcher_host_); |
- DCHECK(!io_helper_); |
if (value && value->primary_key.IsValid()) { |
DCHECK_EQ(kNoCursor, ipc_cursor_id_); |
@@ -514,93 +541,84 @@ void IndexedDBCallbacks::OnSuccess(IndexedDBReturnValue* value) { |
DCHECK(kNoCursor == ipc_cursor_id_ || value == NULL); |
} |
DCHECK_EQ(kNoTransaction, host_transaction_id_); |
- DCHECK_EQ(kNoDatabase, ipc_database_id_); |
DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_); |
- std::unique_ptr<IndexedDBMsg_CallbacksSuccessValue_Params> params( |
- new IndexedDBMsg_CallbacksSuccessValue_Params()); |
- params->ipc_thread_id = ipc_thread_id_; |
- params->ipc_callbacks_id = ipc_callbacks_id_; |
- if (value && value->primary_key.IsValid()) { |
- params->value.primary_key = value->primary_key; |
- params->value.key_path = value->key_path; |
- } |
- if (value && !value->empty()) |
- std::swap(params->value.bits, value->bits); |
- if (!value || value->blob_info.empty()) { |
- dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessValue(*params)); |
+ if (io_helper_) { |
+ DCHECK_EQ(kNoCursor, ipc_cursor_id_); |
+ |
+ ::indexed_db::mojom::ReturnValuePtr mojo_value; |
+ std::vector<IndexedDBBlobInfo> blob_info; |
+ if (value) { |
+ mojo_value = ConvertReturnValue(value); |
+ blob_info = value->blob_info; |
+ } |
+ BrowserThread::PostTask( |
+ BrowserThread::IO, FROM_HERE, |
+ base::Bind(&IOThreadHelper::SendSuccessValue, |
+ base::Unretained(io_helper_.get()), |
+ base::Passed(&mojo_value), base::Passed(&blob_info))); |
} else { |
- IndexedDBMsg_CallbacksSuccessValue_Params* p = params.get(); |
- FillInBlobData(value->blob_info, &p->value.blob_or_file_info); |
- RegisterBlobsAndSend( |
- value->blob_info, |
- base::Bind(CreateBlobsAndSend<IndexedDBMsg_CallbacksSuccessValue_Params, |
- IndexedDBMsg_CallbacksSuccessValue>, |
- base::Owned(params.release()), dispatcher_host_, |
- value->blob_info, |
- base::Unretained(&p->value.blob_or_file_info))); |
+ auto params = base::MakeUnique<IndexedDBMsg_CallbacksSuccessValue_Params>(); |
+ params->ipc_thread_id = ipc_thread_id_; |
+ params->ipc_callbacks_id = ipc_callbacks_id_; |
+ if (value && value->primary_key.IsValid()) { |
+ params->value.primary_key = value->primary_key; |
+ params->value.key_path = value->key_path; |
+ } |
+ if (value && !value->empty()) |
+ swap(params->value.bits, value->bits); |
+ if (!value || value->blob_info.empty()) { |
+ dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessValue(*params)); |
+ } else { |
+ IndexedDBMsg_CallbacksSuccessValue_Params* p = params.get(); |
+ FillInBlobData(value->blob_info, &p->value.blob_or_file_info); |
+ RegisterBlobsAndSend( |
+ value->blob_info, |
+ base::Bind( |
+ CreateBlobsAndSend<IndexedDBMsg_CallbacksSuccessValue_Params, |
+ IndexedDBMsg_CallbacksSuccessValue>, |
+ base::Owned(params.release()), dispatcher_host_, value->blob_info, |
+ base::Unretained(&p->value.blob_or_file_info))); |
+ } |
} |
dispatcher_host_ = nullptr; |
} |
void IndexedDBCallbacks::OnSuccessArray( |
- std::vector<IndexedDBReturnValue>* values, |
- const IndexedDBKeyPath& key_path) { |
+ std::vector<IndexedDBReturnValue>* values) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
DCHECK(dispatcher_host_); |
- DCHECK(!io_helper_); |
+ DCHECK(io_helper_); |
DCHECK_EQ(kNoTransaction, host_transaction_id_); |
- DCHECK_EQ(kNoDatabase, ipc_database_id_); |
DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_); |
+ DCHECK_EQ(kNoCursor, ipc_cursor_id_); |
- std::unique_ptr<IndexedDBMsg_CallbacksSuccessArray_Params> params( |
- new IndexedDBMsg_CallbacksSuccessArray_Params()); |
- params->ipc_thread_id = ipc_thread_id_; |
- params->ipc_callbacks_id = ipc_callbacks_id_; |
- params->values.resize(values->size()); |
- |
- bool found_blob_info = false; |
- for (size_t i = 0; i < values->size(); ++i) { |
- IndexedDBMsg_ReturnValue& pvalue = params->values[i]; |
- IndexedDBReturnValue& value = (*values)[i]; |
- pvalue.bits.swap(value.bits); |
- if (!value.blob_info.empty()) { |
- found_blob_info = true; |
- FillInBlobData(value.blob_info, &pvalue.blob_or_file_info); |
- for (const auto& blob_info : value.blob_info) { |
- if (!blob_info.mark_used_callback().is_null()) |
- blob_info.mark_used_callback().Run(); |
- } |
- } |
- pvalue.primary_key = value.primary_key; |
- pvalue.key_path = key_path; |
- } |
+ std::vector<::indexed_db::mojom::ReturnValuePtr> mojo_values; |
+ mojo_values.reserve(values->size()); |
+ for (size_t i = 0; i < values->size(); ++i) |
+ mojo_values.push_back(ConvertReturnValue(&(*values)[i])); |
- if (found_blob_info) { |
- BrowserThread::PostTask( |
- BrowserThread::IO, FROM_HERE, |
- base::Bind(BlobLookupForGetAll, base::Owned(params.release()), |
- dispatcher_host_, *values)); |
- } else { |
- dispatcher_host_->Send( |
- new IndexedDBMsg_CallbacksSuccessArray(*params.get())); |
- } |
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
+ base::Bind(&IOThreadHelper::SendSuccessArray, |
+ base::Unretained(io_helper_.get()), |
+ base::Passed(&mojo_values), *values)); |
dispatcher_host_ = nullptr; |
} |
void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& value) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
DCHECK(dispatcher_host_); |
- DCHECK(!io_helper_); |
+ DCHECK(io_helper_); |
DCHECK_EQ(kNoCursor, ipc_cursor_id_); |
DCHECK_EQ(kNoTransaction, host_transaction_id_); |
- DCHECK_EQ(kNoDatabase, ipc_database_id_); |
DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_); |
- dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessIndexedDBKey( |
- ipc_thread_id_, ipc_callbacks_id_, value)); |
+ BrowserThread::PostTask( |
+ BrowserThread::IO, FROM_HERE, |
+ base::Bind(&IOThreadHelper::SendSuccessKey, |
+ base::Unretained(io_helper_.get()), value)); |
dispatcher_host_ = nullptr; |
} |
@@ -615,7 +633,6 @@ void IndexedDBCallbacks::OnSuccess(int64_t value) { |
} else { |
DCHECK_EQ(kNoCursor, ipc_cursor_id_); |
DCHECK_EQ(kNoTransaction, host_transaction_id_); |
- DCHECK_EQ(kNoDatabase, ipc_database_id_); |
DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_); |
dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessInteger( |
@@ -627,15 +644,15 @@ void IndexedDBCallbacks::OnSuccess(int64_t value) { |
void IndexedDBCallbacks::OnSuccess() { |
DCHECK(thread_checker_.CalledOnValidThread()); |
DCHECK(dispatcher_host_); |
- DCHECK(!io_helper_); |
+ DCHECK(io_helper_); |
DCHECK_EQ(kNoCursor, ipc_cursor_id_); |
DCHECK_EQ(kNoTransaction, host_transaction_id_); |
- DCHECK_EQ(kNoDatabase, ipc_database_id_); |
DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_); |
- dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessUndefined( |
- ipc_thread_id_, ipc_callbacks_id_)); |
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
+ base::Bind(&IOThreadHelper::SendSuccess, |
+ base::Unretained(io_helper_.get()))); |
dispatcher_host_ = nullptr; |
} |
@@ -651,7 +668,9 @@ void IndexedDBCallbacks::SetConnectionOpenStartTime( |
} |
IndexedDBCallbacks::IOThreadHelper::IOThreadHelper( |
- CallbacksAssociatedPtrInfo callbacks_info) { |
+ CallbacksAssociatedPtrInfo callbacks_info, |
+ scoped_refptr<IndexedDBDispatcherHost> dispatcher_host) |
+ : dispatcher_host_(std::move(dispatcher_host)) { |
DCHECK_CURRENTLY_ON(BrowserThread::IO); |
callbacks_.Bind(std::move(callbacks_info)); |
} |
@@ -673,23 +692,105 @@ void IndexedDBCallbacks::IOThreadHelper::SendBlocked(int64_t existing_version) { |
} |
void IndexedDBCallbacks::IOThreadHelper::SendUpgradeNeeded( |
- int32_t database_id, |
+ std::unique_ptr<DatabaseImpl> database, |
int64_t old_version, |
blink::WebIDBDataLoss data_loss, |
const std::string& data_loss_message, |
const content::IndexedDBDatabaseMetadata& metadata) { |
- callbacks_->UpgradeNeeded(database_id, old_version, data_loss, |
+ ::indexed_db::mojom::DatabaseAssociatedPtrInfo ptr_info; |
+ ::indexed_db::mojom::DatabaseAssociatedRequest request; |
+ callbacks_.associated_group()->CreateAssociatedInterface( |
+ mojo::AssociatedGroup::WILL_PASS_PTR, &ptr_info, &request); |
+ mojo::MakeStrongAssociatedBinding(std::move(database), std::move(request)); |
+ callbacks_->UpgradeNeeded(std::move(ptr_info), old_version, data_loss, |
data_loss_message, metadata); |
} |
void IndexedDBCallbacks::IOThreadHelper::SendSuccessDatabase( |
- int32_t database_id, |
+ std::unique_ptr<DatabaseImpl> database, |
const content::IndexedDBDatabaseMetadata& metadata) { |
- callbacks_->SuccessDatabase(database_id, metadata); |
+ ::indexed_db::mojom::DatabaseAssociatedPtrInfo ptr_info; |
+ if (database) { |
+ ::indexed_db::mojom::DatabaseAssociatedRequest request; |
+ callbacks_.associated_group()->CreateAssociatedInterface( |
+ mojo::AssociatedGroup::WILL_PASS_PTR, &ptr_info, &request); |
+ mojo::MakeStrongAssociatedBinding(std::move(database), std::move(request)); |
+ } |
+ callbacks_->SuccessDatabase(std::move(ptr_info), metadata); |
+} |
+ |
+void IndexedDBCallbacks::IOThreadHelper::SendSuccessCursor( |
+ int32_t cursor_id, |
+ const IndexedDBKey& key, |
+ const IndexedDBKey& primary_key, |
+ ::indexed_db::mojom::ValuePtr value, |
+ const std::vector<IndexedDBBlobInfo>& blob_info) { |
+ if (!value || CreateAllBlobs(blob_info, &value->blob_or_file_info)) |
+ callbacks_->SuccessCursor(cursor_id, key, primary_key, std::move(value)); |
+} |
+ |
+void IndexedDBCallbacks::IOThreadHelper::SendSuccessValue( |
+ ::indexed_db::mojom::ReturnValuePtr value, |
+ const std::vector<IndexedDBBlobInfo>& blob_info) { |
+ if (!value || CreateAllBlobs(blob_info, &value->value->blob_or_file_info)) |
+ callbacks_->SuccessValue(std::move(value)); |
+} |
+ |
+void IndexedDBCallbacks::IOThreadHelper::SendSuccessArray( |
+ std::vector<::indexed_db::mojom::ReturnValuePtr> mojo_values, |
+ const std::vector<IndexedDBReturnValue>& values) { |
+ DCHECK_EQ(mojo_values.size(), values.size()); |
+ |
+ for (size_t i = 0; i < mojo_values.size(); ++i) { |
+ if (!CreateAllBlobs(values[i].blob_info, |
+ &mojo_values[i]->value->blob_or_file_info)) |
+ return; |
+ } |
+ callbacks_->SuccessArray(std::move(mojo_values)); |
+} |
+ |
+void IndexedDBCallbacks::IOThreadHelper::SendSuccessKey( |
+ const IndexedDBKey& value) { |
+ callbacks_->SuccessKey(value); |
} |
void IndexedDBCallbacks::IOThreadHelper::SendSuccessInteger(int64_t value) { |
callbacks_->SuccessInteger(value); |
} |
+void IndexedDBCallbacks::IOThreadHelper::SendSuccess() { |
+ callbacks_->Success(); |
+} |
+ |
+std::string IndexedDBCallbacks::IOThreadHelper::CreateBlobData( |
+ const IndexedDBBlobInfo& blob_info) { |
+ if (!blob_info.uuid().empty()) { |
+ // We're sending back a live blob, not a reference into our backing store. |
+ return dispatcher_host_->HoldBlobData(blob_info); |
+ } |
+ scoped_refptr<ShareableFileReference> shareable_file = |
+ ShareableFileReference::Get(blob_info.file_path()); |
+ if (!shareable_file) { |
+ shareable_file = ShareableFileReference::GetOrCreate( |
+ blob_info.file_path(), |
+ ShareableFileReference::DONT_DELETE_ON_FINAL_RELEASE, |
+ dispatcher_host_->context()->TaskRunner()); |
+ if (!blob_info.release_callback().is_null()) |
+ shareable_file->AddFinalReleaseCallback(blob_info.release_callback()); |
+ } |
+ return dispatcher_host_->HoldBlobData(blob_info); |
+} |
+ |
+bool IndexedDBCallbacks::IOThreadHelper::CreateAllBlobs( |
+ const std::vector<IndexedDBBlobInfo>& blob_info, |
+ std::vector<::indexed_db::mojom::BlobInfoPtr>* blob_or_file_info) { |
+ IDB_TRACE("IndexedDBCallbacks::CreateAllBlobs"); |
+ DCHECK_EQ(blob_info.size(), blob_or_file_info->size()); |
+ if (!dispatcher_host_->blob_storage_context()) |
+ return false; |
+ for (size_t i = 0; i < blob_info.size(); ++i) |
+ (*blob_or_file_info)[i]->uuid = CreateBlobData(blob_info[i]); |
+ return true; |
+} |
+ |
} // namespace content |