1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/indexed_db/indexed_db_callbacks.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "base/time/time.h"
12 #include "content/browser/child_process_security_policy_impl.h"
13 #include "content/browser/fileapi/fileapi_message_filter.h"
14 #include "content/browser/indexed_db/indexed_db_blob_info.h"
15 #include "content/browser/indexed_db/indexed_db_connection.h"
16 #include "content/browser/indexed_db/indexed_db_context_impl.h"
17 #include "content/browser/indexed_db/indexed_db_cursor.h"
18 #include "content/browser/indexed_db/indexed_db_database_callbacks.h"
19 #include "content/browser/indexed_db/indexed_db_database_error.h"
20 #include "content/browser/indexed_db/indexed_db_metadata.h"
21 #include "content/browser/indexed_db/indexed_db_value.h"
22 #include "content/common/indexed_db/indexed_db_constants.h"
23 #include "content/common/indexed_db/indexed_db_messages.h"
24 #include "webkit/browser/blob/blob_storage_context.h"
25 #include "webkit/browser/quota/quota_manager.h"
26 #include "webkit/common/blob/blob_data.h"
27 #include "webkit/common/blob/shareable_file_reference.h"
29 using webkit_blob::ShareableFileReference;
34 const int32 kNoCursor = -1;
35 const int32 kNoDatabaseCallbacks = -1;
36 const int64 kNoTransaction = -1;
39 IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost* dispatcher_host,
41 int32 ipc_callbacks_id)
42 : dispatcher_host_(dispatcher_host),
43 ipc_callbacks_id_(ipc_callbacks_id),
44 ipc_thread_id_(ipc_thread_id),
45 ipc_cursor_id_(kNoCursor),
46 host_transaction_id_(kNoTransaction),
47 ipc_database_id_(kNoDatabase),
48 ipc_database_callbacks_id_(kNoDatabaseCallbacks),
49 data_loss_(blink::WebIDBDataLossNone),
50 sent_blocked_(false) {
53 IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost* dispatcher_host,
55 int32 ipc_callbacks_id,
57 : dispatcher_host_(dispatcher_host),
58 ipc_callbacks_id_(ipc_callbacks_id),
59 ipc_thread_id_(ipc_thread_id),
60 ipc_cursor_id_(ipc_cursor_id),
61 host_transaction_id_(kNoTransaction),
62 ipc_database_id_(kNoDatabase),
63 ipc_database_callbacks_id_(kNoDatabaseCallbacks),
64 data_loss_(blink::WebIDBDataLossNone),
65 sent_blocked_(false) {
68 IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost* dispatcher_host,
70 int32 ipc_callbacks_id,
71 int32 ipc_database_callbacks_id,
72 int64 host_transaction_id,
73 const GURL& origin_url)
74 : dispatcher_host_(dispatcher_host),
75 ipc_callbacks_id_(ipc_callbacks_id),
76 ipc_thread_id_(ipc_thread_id),
77 ipc_cursor_id_(kNoCursor),
78 host_transaction_id_(host_transaction_id),
79 origin_url_(origin_url),
80 ipc_database_id_(kNoDatabase),
81 ipc_database_callbacks_id_(ipc_database_callbacks_id),
82 data_loss_(blink::WebIDBDataLossNone),
83 sent_blocked_(false) {
86 IndexedDBCallbacks::~IndexedDBCallbacks() {}
88 void IndexedDBCallbacks::OnError(const IndexedDBDatabaseError& error) {
89 DCHECK(dispatcher_host_.get());
91 dispatcher_host_->Send(new IndexedDBMsg_CallbacksError(
92 ipc_thread_id_, ipc_callbacks_id_, error.code(), error.message()));
93 dispatcher_host_ = NULL;
96 void IndexedDBCallbacks::OnSuccess(const std::vector<base::string16>& value) {
97 DCHECK(dispatcher_host_.get());
99 DCHECK_EQ(kNoCursor, ipc_cursor_id_);
100 DCHECK_EQ(kNoTransaction, host_transaction_id_);
101 DCHECK_EQ(kNoDatabase, ipc_database_id_);
102 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
103 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
105 std::vector<base::string16> list;
106 for (unsigned i = 0; i < value.size(); ++i)
107 list.push_back(value[i]);
109 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessStringList(
110 ipc_thread_id_, ipc_callbacks_id_, list));
111 dispatcher_host_ = NULL;
114 void IndexedDBCallbacks::OnBlocked(int64 existing_version) {
115 DCHECK(dispatcher_host_.get());
117 DCHECK_EQ(kNoCursor, ipc_cursor_id_);
118 // No transaction/db callbacks for DeleteDatabase.
119 DCHECK_EQ(kNoTransaction == host_transaction_id_,
120 kNoDatabaseCallbacks == ipc_database_callbacks_id_);
121 DCHECK_EQ(kNoDatabase, ipc_database_id_);
126 sent_blocked_ = true;
127 dispatcher_host_->Send(new IndexedDBMsg_CallbacksIntBlocked(
128 ipc_thread_id_, ipc_callbacks_id_, existing_version));
131 void IndexedDBCallbacks::OnDataLoss(blink::WebIDBDataLoss data_loss,
132 std::string data_loss_message) {
133 DCHECK_NE(blink::WebIDBDataLossNone, data_loss);
134 data_loss_ = data_loss;
135 data_loss_message_ = data_loss_message;
138 void IndexedDBCallbacks::OnUpgradeNeeded(
140 scoped_ptr<IndexedDBConnection> connection,
141 const IndexedDBDatabaseMetadata& metadata) {
142 DCHECK(dispatcher_host_.get());
144 DCHECK_EQ(kNoCursor, ipc_cursor_id_);
145 DCHECK_NE(kNoTransaction, host_transaction_id_);
146 DCHECK_EQ(kNoDatabase, ipc_database_id_);
147 DCHECK_NE(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
149 dispatcher_host_->RegisterTransactionId(host_transaction_id_, origin_url_);
150 int32 ipc_database_id =
151 dispatcher_host_->Add(connection.release(), ipc_thread_id_, origin_url_);
152 if (ipc_database_id < 0)
154 ipc_database_id_ = ipc_database_id;
155 IndexedDBMsg_CallbacksUpgradeNeeded_Params params;
156 params.ipc_thread_id = ipc_thread_id_;
157 params.ipc_callbacks_id = ipc_callbacks_id_;
158 params.ipc_database_id = ipc_database_id;
159 params.ipc_database_callbacks_id = ipc_database_callbacks_id_;
160 params.old_version = old_version;
161 params.idb_metadata = IndexedDBDispatcherHost::ConvertMetadata(metadata);
162 params.data_loss = data_loss_;
163 params.data_loss_message = data_loss_message_;
164 dispatcher_host_->Send(new IndexedDBMsg_CallbacksUpgradeNeeded(params));
167 void IndexedDBCallbacks::OnSuccess(scoped_ptr<IndexedDBConnection> connection,
168 const IndexedDBDatabaseMetadata& metadata) {
169 DCHECK(dispatcher_host_.get());
171 DCHECK_EQ(kNoCursor, ipc_cursor_id_);
172 DCHECK_NE(kNoTransaction, host_transaction_id_);
173 DCHECK_NE(ipc_database_id_ == kNoDatabase, !connection);
174 DCHECK_NE(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
176 scoped_refptr<IndexedDBCallbacks> self(this);
178 int32 ipc_object_id = kNoDatabase;
179 // Only register if the connection was not previously sent in OnUpgradeNeeded.
180 if (ipc_database_id_ == kNoDatabase) {
181 ipc_object_id = dispatcher_host_->Add(
182 connection.release(), ipc_thread_id_, origin_url_);
185 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessIDBDatabase(
188 ipc_database_callbacks_id_,
190 IndexedDBDispatcherHost::ConvertMetadata(metadata)));
191 dispatcher_host_ = NULL;
194 static std::string CreateBlobData(
195 const IndexedDBBlobInfo& blob_info,
196 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host,
197 webkit_blob::BlobStorageContext* blob_storage_context,
198 base::TaskRunner* task_runner) {
199 std::string uuid = blob_info.uuid();
201 // We're sending back a live blob, not a reference into our backing store.
202 scoped_ptr<webkit_blob::BlobDataHandle> blob_data_handle(
203 blob_storage_context->GetBlobDataFromUUID(uuid));
204 dispatcher_host->HoldBlobDataHandle(uuid, blob_data_handle.Pass());
207 scoped_refptr<ShareableFileReference> shareable_file =
208 ShareableFileReference::Get(blob_info.file_path());
209 if (!shareable_file.get()) {
210 shareable_file = ShareableFileReference::GetOrCreate(
211 blob_info.file_path(),
212 ShareableFileReference::DONT_DELETE_ON_FINAL_RELEASE,
214 if (!blob_info.release_callback().is_null())
215 shareable_file->AddFinalReleaseCallback(blob_info.release_callback());
218 uuid = base::GenerateGUID();
219 scoped_refptr<webkit_blob::BlobData> blob_data =
220 new webkit_blob::BlobData(uuid);
221 blob_data->set_content_type(base::UTF16ToUTF8(blob_info.type()));
222 blob_data->AppendFile(
223 blob_info.file_path(), 0, blob_info.size(), blob_info.last_modified());
224 scoped_ptr<webkit_blob::BlobDataHandle> blob_data_handle(
225 blob_storage_context->AddFinishedBlob(blob_data.get()));
226 dispatcher_host->HoldBlobDataHandle(uuid, blob_data_handle.Pass());
231 static bool CreateAllBlobs(
232 const std::vector<IndexedDBBlobInfo>& blob_info,
233 std::vector<IndexedDBMsg_BlobOrFileInfo>* blob_or_file_info,
234 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host) {
235 DCHECK_EQ(blob_info.size(), blob_or_file_info->size());
237 if (!dispatcher_host->blob_storage_context())
239 for (i = 0; i < blob_info.size(); ++i) {
240 (*blob_or_file_info)[i].uuid =
241 CreateBlobData(blob_info[i],
243 dispatcher_host->blob_storage_context(),
244 dispatcher_host->Context()->TaskRunner());
249 template <class ParamType, class MsgType>
250 static void CreateBlobsAndSend(
252 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host,
253 const std::vector<IndexedDBBlobInfo>& blob_info,
254 std::vector<IndexedDBMsg_BlobOrFileInfo>* blob_or_file_info) {
255 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
256 if (CreateAllBlobs(blob_info, blob_or_file_info, dispatcher_host))
257 dispatcher_host->Send(new MsgType(*params));
260 static void BlobLookupForCursorPrefetch(
261 IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params* params,
262 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host,
263 const std::vector<IndexedDBValue>& values) {
264 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
265 DCHECK_EQ(values.size(), params->blob_or_file_infos.size());
267 std::vector<IndexedDBValue>::const_iterator value_iter;
268 std::vector<std::vector<IndexedDBMsg_BlobOrFileInfo> >::iterator blob_iter;
269 for (value_iter = values.begin(), blob_iter =
270 params->blob_or_file_infos.begin(); value_iter != values.end();
271 ++value_iter, ++blob_iter) {
272 if (!CreateAllBlobs(value_iter->blob_info, &*blob_iter, dispatcher_host))
275 dispatcher_host->Send(
276 new IndexedDBMsg_CallbacksSuccessCursorPrefetch(*params));
279 static void FillInBlobData(
280 const std::vector<IndexedDBBlobInfo>& blob_info,
281 std::vector<IndexedDBMsg_BlobOrFileInfo>* blob_or_file_info) {
282 for (std::vector<IndexedDBBlobInfo>::const_iterator iter = blob_info.begin();
283 iter != blob_info.end();
285 if (iter->is_file()) {
286 IndexedDBMsg_BlobOrFileInfo info;
288 info.mime_type = iter->type();
289 info.file_name = iter->file_name();
290 info.file_path = iter->file_path().AsUTF16Unsafe();
291 info.size = iter->size();
292 info.last_modified = iter->last_modified().ToDoubleT();
293 blob_or_file_info->push_back(info);
295 IndexedDBMsg_BlobOrFileInfo info;
296 info.mime_type = iter->type();
297 info.size = iter->size();
298 blob_or_file_info->push_back(info);
303 void IndexedDBCallbacks::RegisterBlobsAndSend(
304 const std::vector<IndexedDBBlobInfo>& blob_info,
305 const base::Closure& callback) {
306 std::vector<IndexedDBBlobInfo>::const_iterator iter;
307 for (iter = blob_info.begin(); iter != blob_info.end(); ++iter) {
308 if (!iter->mark_used_callback().is_null())
309 iter->mark_used_callback().Run();
311 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO));
312 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, callback);
315 void IndexedDBCallbacks::OnSuccess(scoped_refptr<IndexedDBCursor> cursor,
316 const IndexedDBKey& key,
317 const IndexedDBKey& primary_key,
318 IndexedDBValue* value) {
319 DCHECK(dispatcher_host_.get());
321 DCHECK_EQ(kNoCursor, ipc_cursor_id_);
322 DCHECK_EQ(kNoTransaction, host_transaction_id_);
323 DCHECK_EQ(kNoDatabase, ipc_database_id_);
324 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
325 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
327 int32 ipc_object_id = dispatcher_host_->Add(cursor.get());
328 scoped_ptr<IndexedDBMsg_CallbacksSuccessIDBCursor_Params> params(
329 new IndexedDBMsg_CallbacksSuccessIDBCursor_Params());
330 params->ipc_thread_id = ipc_thread_id_;
331 params->ipc_callbacks_id = ipc_callbacks_id_;
332 params->ipc_cursor_id = ipc_object_id;
334 params->primary_key = primary_key;
335 if (value && !value->empty())
336 std::swap(params->value, value->bits);
337 // TODO(alecflett): Avoid a copy here: the whole params object is
338 // being copied into the message.
339 if (!value || value->blob_info.empty()) {
340 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessIDBCursor(*params));
342 IndexedDBMsg_CallbacksSuccessIDBCursor_Params* p = params.get();
343 FillInBlobData(value->blob_info, &p->blob_or_file_info);
344 RegisterBlobsAndSend(
347 CreateBlobsAndSend<IndexedDBMsg_CallbacksSuccessIDBCursor_Params,
348 IndexedDBMsg_CallbacksSuccessIDBCursor>,
349 base::Owned(params.release()),
352 base::Unretained(&p->blob_or_file_info)));
354 dispatcher_host_ = NULL;
357 void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& key,
358 const IndexedDBKey& primary_key,
359 IndexedDBValue* value) {
360 DCHECK(dispatcher_host_.get());
362 DCHECK_NE(kNoCursor, ipc_cursor_id_);
363 DCHECK_EQ(kNoTransaction, host_transaction_id_);
364 DCHECK_EQ(kNoDatabase, ipc_database_id_);
365 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
366 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
368 IndexedDBCursor* idb_cursor =
369 dispatcher_host_->GetCursorFromId(ipc_cursor_id_);
375 scoped_ptr<IndexedDBMsg_CallbacksSuccessCursorContinue_Params> params(
376 new IndexedDBMsg_CallbacksSuccessCursorContinue_Params());
377 params->ipc_thread_id = ipc_thread_id_;
378 params->ipc_callbacks_id = ipc_callbacks_id_;
379 params->ipc_cursor_id = ipc_cursor_id_;
381 params->primary_key = primary_key;
382 if (value && !value->empty())
383 std::swap(params->value, value->bits);
384 // TODO(alecflett): Avoid a copy here: the whole params object is
385 // being copied into the message.
386 if (!value || value->blob_info.empty()) {
387 dispatcher_host_->Send(
388 new IndexedDBMsg_CallbacksSuccessCursorContinue(*params));
390 IndexedDBMsg_CallbacksSuccessCursorContinue_Params* p = params.get();
391 FillInBlobData(value->blob_info, &p->blob_or_file_info);
392 RegisterBlobsAndSend(
394 base::Bind(CreateBlobsAndSend<
395 IndexedDBMsg_CallbacksSuccessCursorContinue_Params,
396 IndexedDBMsg_CallbacksSuccessCursorContinue>,
397 base::Owned(params.release()),
400 base::Unretained(&p->blob_or_file_info)));
402 dispatcher_host_ = NULL;
405 void IndexedDBCallbacks::OnSuccessWithPrefetch(
406 const std::vector<IndexedDBKey>& keys,
407 const std::vector<IndexedDBKey>& primary_keys,
408 std::vector<IndexedDBValue>* values) {
409 DCHECK_EQ(keys.size(), primary_keys.size());
410 DCHECK_EQ(keys.size(), values->size());
412 DCHECK(dispatcher_host_.get());
414 DCHECK_NE(kNoCursor, ipc_cursor_id_);
415 DCHECK_EQ(kNoTransaction, host_transaction_id_);
416 DCHECK_EQ(kNoDatabase, ipc_database_id_);
417 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
418 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
420 std::vector<IndexedDBKey> msgKeys;
421 std::vector<IndexedDBKey> msgPrimaryKeys;
423 for (size_t i = 0; i < keys.size(); ++i) {
424 msgKeys.push_back(keys[i]);
425 msgPrimaryKeys.push_back(primary_keys[i]);
428 scoped_ptr<IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params> params(
429 new IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params());
430 params->ipc_thread_id = ipc_thread_id_;
431 params->ipc_callbacks_id = ipc_callbacks_id_;
432 params->ipc_cursor_id = ipc_cursor_id_;
433 params->keys = msgKeys;
434 params->primary_keys = msgPrimaryKeys;
435 std::vector<std::string>& values_bits = params->values;
436 values_bits.resize(values->size());
437 std::vector<std::vector<IndexedDBMsg_BlobOrFileInfo> >& values_blob_infos =
438 params->blob_or_file_infos;
439 values_blob_infos.resize(values->size());
441 bool found_blob_info = false;
442 std::vector<IndexedDBValue>::iterator iter = values->begin();
443 for (size_t i = 0; iter != values->end(); ++iter, ++i) {
444 values_bits[i].swap(iter->bits);
445 if (iter->blob_info.size()) {
446 found_blob_info = true;
447 FillInBlobData(iter->blob_info, &values_blob_infos[i]);
448 std::vector<IndexedDBBlobInfo>::const_iterator blob_iter;
449 for (blob_iter = iter->blob_info.begin();
450 blob_iter != iter->blob_info.end();
452 if (!blob_iter->mark_used_callback().is_null())
453 blob_iter->mark_used_callback().Run();
458 if (found_blob_info) {
459 BrowserThread::PostTask(BrowserThread::IO,
461 base::Bind(BlobLookupForCursorPrefetch,
462 base::Owned(params.release()),
466 dispatcher_host_->Send(
467 new IndexedDBMsg_CallbacksSuccessCursorPrefetch(*params.get()));
469 dispatcher_host_ = NULL;
472 void IndexedDBCallbacks::OnSuccess(IndexedDBValue* value,
473 const IndexedDBKey& key,
474 const IndexedDBKeyPath& key_path) {
475 DCHECK(dispatcher_host_.get());
477 DCHECK_EQ(kNoCursor, ipc_cursor_id_);
478 DCHECK_EQ(kNoTransaction, host_transaction_id_);
479 DCHECK_EQ(kNoDatabase, ipc_database_id_);
480 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
481 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
483 scoped_ptr<IndexedDBMsg_CallbacksSuccessValueWithKey_Params> params(
484 new IndexedDBMsg_CallbacksSuccessValueWithKey_Params());
485 params->ipc_thread_id = ipc_thread_id_;
486 params->ipc_callbacks_id = ipc_callbacks_id_;
487 params->primary_key = key;
488 params->key_path = key_path;
489 if (value && !value->empty())
490 std::swap(params->value, value->bits);
491 if (!value || value->blob_info.empty()) {
492 dispatcher_host_->Send(
493 new IndexedDBMsg_CallbacksSuccessValueWithKey(*params));
495 IndexedDBMsg_CallbacksSuccessValueWithKey_Params* p = params.get();
496 FillInBlobData(value->blob_info, &p->blob_or_file_info);
497 RegisterBlobsAndSend(
500 CreateBlobsAndSend<IndexedDBMsg_CallbacksSuccessValueWithKey_Params,
501 IndexedDBMsg_CallbacksSuccessValueWithKey>,
502 base::Owned(params.release()),
505 base::Unretained(&p->blob_or_file_info)));
507 dispatcher_host_ = NULL;
510 void IndexedDBCallbacks::OnSuccess(IndexedDBValue* value) {
511 DCHECK(dispatcher_host_.get());
512 DCHECK(kNoCursor == ipc_cursor_id_ || value == NULL);
513 DCHECK_EQ(kNoTransaction, host_transaction_id_);
514 DCHECK_EQ(kNoDatabase, ipc_database_id_);
515 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
516 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
518 scoped_ptr<IndexedDBMsg_CallbacksSuccessValue_Params> params(
519 new IndexedDBMsg_CallbacksSuccessValue_Params());
520 params->ipc_thread_id = ipc_thread_id_;
521 params->ipc_callbacks_id = ipc_callbacks_id_;
522 if (value && !value->empty())
523 std::swap(params->value, value->bits);
524 if (!value || value->blob_info.empty()) {
525 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessValue(*params));
527 IndexedDBMsg_CallbacksSuccessValue_Params* p = params.get();
528 FillInBlobData(value->blob_info, &p->blob_or_file_info);
529 RegisterBlobsAndSend(
531 base::Bind(CreateBlobsAndSend<IndexedDBMsg_CallbacksSuccessValue_Params,
532 IndexedDBMsg_CallbacksSuccessValue>,
533 base::Owned(params.release()),
536 base::Unretained(&p->blob_or_file_info)));
538 dispatcher_host_ = NULL;
541 void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& value) {
542 DCHECK(dispatcher_host_.get());
544 DCHECK_EQ(kNoCursor, ipc_cursor_id_);
545 DCHECK_EQ(kNoTransaction, host_transaction_id_);
546 DCHECK_EQ(kNoDatabase, ipc_database_id_);
547 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
548 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
550 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessIndexedDBKey(
551 ipc_thread_id_, ipc_callbacks_id_, value));
552 dispatcher_host_ = NULL;
555 void IndexedDBCallbacks::OnSuccess(int64 value) {
556 DCHECK(dispatcher_host_.get());
558 DCHECK_EQ(kNoCursor, ipc_cursor_id_);
559 DCHECK_EQ(kNoTransaction, host_transaction_id_);
560 DCHECK_EQ(kNoDatabase, ipc_database_id_);
561 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
562 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
564 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessInteger(
565 ipc_thread_id_, ipc_callbacks_id_, value));
566 dispatcher_host_ = NULL;
569 void IndexedDBCallbacks::OnSuccess() {
570 DCHECK(dispatcher_host_.get());
572 DCHECK_EQ(kNoCursor, ipc_cursor_id_);
573 DCHECK_EQ(kNoTransaction, host_transaction_id_);
574 DCHECK_EQ(kNoDatabase, ipc_database_id_);
575 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
576 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
578 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessUndefined(
579 ipc_thread_id_, ipc_callbacks_id_));
580 dispatcher_host_ = NULL;
583 } // namespace content