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
) {}
51 IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost
* dispatcher_host
,
53 int32 ipc_callbacks_id
,
55 : dispatcher_host_(dispatcher_host
),
56 ipc_callbacks_id_(ipc_callbacks_id
),
57 ipc_thread_id_(ipc_thread_id
),
58 ipc_cursor_id_(ipc_cursor_id
),
59 host_transaction_id_(kNoTransaction
),
60 ipc_database_id_(kNoDatabase
),
61 ipc_database_callbacks_id_(kNoDatabaseCallbacks
),
62 data_loss_(blink::WebIDBDataLossNone
) {}
64 IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost
* dispatcher_host
,
66 int32 ipc_callbacks_id
,
67 int32 ipc_database_callbacks_id
,
68 int64 host_transaction_id
,
69 const GURL
& origin_url
)
70 : dispatcher_host_(dispatcher_host
),
71 ipc_callbacks_id_(ipc_callbacks_id
),
72 ipc_thread_id_(ipc_thread_id
),
73 ipc_cursor_id_(kNoCursor
),
74 host_transaction_id_(host_transaction_id
),
75 origin_url_(origin_url
),
76 ipc_database_id_(kNoDatabase
),
77 ipc_database_callbacks_id_(ipc_database_callbacks_id
),
78 data_loss_(blink::WebIDBDataLossNone
) {}
80 IndexedDBCallbacks::~IndexedDBCallbacks() {}
82 void IndexedDBCallbacks::OnError(const IndexedDBDatabaseError
& error
) {
83 DCHECK(dispatcher_host_
.get());
85 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksError(
86 ipc_thread_id_
, ipc_callbacks_id_
, error
.code(), error
.message()));
87 dispatcher_host_
= NULL
;
90 void IndexedDBCallbacks::OnSuccess(const std::vector
<base::string16
>& value
) {
91 DCHECK(dispatcher_host_
.get());
93 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
94 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
95 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
96 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
97 DCHECK_EQ(blink::WebIDBDataLossNone
, data_loss_
);
99 std::vector
<base::string16
> list
;
100 for (unsigned i
= 0; i
< value
.size(); ++i
)
101 list
.push_back(value
[i
]);
103 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksSuccessStringList(
104 ipc_thread_id_
, ipc_callbacks_id_
, list
));
105 dispatcher_host_
= NULL
;
108 void IndexedDBCallbacks::OnBlocked(int64 existing_version
) {
109 DCHECK(dispatcher_host_
.get());
111 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
112 // No transaction/db callbacks for DeleteDatabase.
113 DCHECK_EQ(kNoTransaction
== host_transaction_id_
,
114 kNoDatabaseCallbacks
== ipc_database_callbacks_id_
);
115 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
117 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksIntBlocked(
118 ipc_thread_id_
, ipc_callbacks_id_
, existing_version
));
121 void IndexedDBCallbacks::OnDataLoss(blink::WebIDBDataLoss data_loss
,
122 std::string data_loss_message
) {
123 DCHECK_NE(blink::WebIDBDataLossNone
, data_loss
);
124 data_loss_
= data_loss
;
125 data_loss_message_
= data_loss_message
;
128 void IndexedDBCallbacks::OnUpgradeNeeded(
130 scoped_ptr
<IndexedDBConnection
> connection
,
131 const IndexedDBDatabaseMetadata
& metadata
) {
132 DCHECK(dispatcher_host_
.get());
134 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
135 DCHECK_NE(kNoTransaction
, host_transaction_id_
);
136 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
137 DCHECK_NE(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
139 dispatcher_host_
->RegisterTransactionId(host_transaction_id_
, origin_url_
);
140 int32 ipc_database_id
=
141 dispatcher_host_
->Add(connection
.release(), ipc_thread_id_
, origin_url_
);
142 if (ipc_database_id
< 0)
144 ipc_database_id_
= ipc_database_id
;
145 IndexedDBMsg_CallbacksUpgradeNeeded_Params params
;
146 params
.ipc_thread_id
= ipc_thread_id_
;
147 params
.ipc_callbacks_id
= ipc_callbacks_id_
;
148 params
.ipc_database_id
= ipc_database_id
;
149 params
.ipc_database_callbacks_id
= ipc_database_callbacks_id_
;
150 params
.old_version
= old_version
;
151 params
.idb_metadata
= IndexedDBDispatcherHost::ConvertMetadata(metadata
);
152 params
.data_loss
= data_loss_
;
153 params
.data_loss_message
= data_loss_message_
;
154 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksUpgradeNeeded(params
));
157 void IndexedDBCallbacks::OnSuccess(scoped_ptr
<IndexedDBConnection
> connection
,
158 const IndexedDBDatabaseMetadata
& metadata
) {
159 DCHECK(dispatcher_host_
.get());
161 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
162 DCHECK_NE(kNoTransaction
, host_transaction_id_
);
163 DCHECK_NE(ipc_database_id_
== kNoDatabase
, !connection
);
164 DCHECK_NE(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
166 scoped_refptr
<IndexedDBCallbacks
> self(this);
168 int32 ipc_object_id
= kNoDatabase
;
169 // Only register if the connection was not previously sent in OnUpgradeNeeded.
170 if (ipc_database_id_
== kNoDatabase
) {
171 ipc_object_id
= dispatcher_host_
->Add(
172 connection
.release(), ipc_thread_id_
, origin_url_
);
175 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksSuccessIDBDatabase(
178 ipc_database_callbacks_id_
,
180 IndexedDBDispatcherHost::ConvertMetadata(metadata
)));
181 dispatcher_host_
= NULL
;
184 static std::string
CreateBlobData(
185 const IndexedDBBlobInfo
& blob_info
,
186 scoped_refptr
<IndexedDBDispatcherHost
> dispatcher_host
,
187 webkit_blob::BlobStorageContext
* blob_storage_context
,
188 base::TaskRunner
* task_runner
) {
189 std::string uuid
= blob_info
.uuid();
191 // We're sending back a live blob, not a reference into our backing store.
192 scoped_ptr
<webkit_blob::BlobDataHandle
> blob_data_handle(
193 blob_storage_context
->GetBlobDataFromUUID(uuid
));
194 dispatcher_host
->HoldBlobDataHandle(uuid
, blob_data_handle
);
197 scoped_refptr
<ShareableFileReference
> shareable_file
=
198 ShareableFileReference::Get(blob_info
.file_path());
199 if (!shareable_file
.get()) {
200 shareable_file
= ShareableFileReference::GetOrCreate(
201 blob_info
.file_path(),
202 ShareableFileReference::DONT_DELETE_ON_FINAL_RELEASE
,
204 if (!blob_info
.release_callback().is_null())
205 shareable_file
->AddFinalReleaseCallback(blob_info
.release_callback());
208 uuid
= base::GenerateGUID();
209 scoped_refptr
<webkit_blob::BlobData
> blob_data
=
210 new webkit_blob::BlobData(uuid
);
211 blob_data
->AppendFile(
212 blob_info
.file_path(), 0, blob_info
.size(), blob_info
.last_modified());
213 scoped_ptr
<webkit_blob::BlobDataHandle
> blob_data_handle(
214 blob_storage_context
->AddFinishedBlob(blob_data
.get()));
215 dispatcher_host
->HoldBlobDataHandle(uuid
, blob_data_handle
);
220 static bool CreateAllBlobs(
221 const std::vector
<IndexedDBBlobInfo
>& blob_info
,
222 std::vector
<IndexedDBMsg_BlobOrFileInfo
>* blob_or_file_info
,
223 scoped_refptr
<IndexedDBDispatcherHost
> dispatcher_host
) {
224 DCHECK_EQ(blob_info
.size(), blob_or_file_info
->size());
226 if (!dispatcher_host
->blob_storage_context())
228 for (i
= 0; i
< blob_info
.size(); ++i
) {
229 (*blob_or_file_info
)[i
].uuid
=
230 CreateBlobData(blob_info
[i
],
232 dispatcher_host
->blob_storage_context(),
233 dispatcher_host
->Context()->TaskRunner());
238 template <class ParamType
, class MsgType
>
239 static void CreateBlobsAndSend(
241 scoped_refptr
<IndexedDBDispatcherHost
> dispatcher_host
,
242 const std::vector
<IndexedDBBlobInfo
>& blob_info
,
243 std::vector
<IndexedDBMsg_BlobOrFileInfo
>* blob_or_file_info
) {
244 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
245 if (CreateAllBlobs(blob_info
, blob_or_file_info
, dispatcher_host
))
246 dispatcher_host
->Send(new MsgType(*params
));
249 static void BlobLookupForCursorPrefetch(
250 IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params
* params
,
251 scoped_refptr
<IndexedDBDispatcherHost
> dispatcher_host
,
252 const std::vector
<IndexedDBValue
>& values
,
253 std::vector
<std::vector
<IndexedDBMsg_BlobOrFileInfo
> >*
254 blob_or_file_infos
) {
255 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
256 DCHECK_EQ(values
.size(), blob_or_file_infos
->size());
258 std::vector
<IndexedDBValue
>::const_iterator value_iter
;
259 std::vector
<std::vector
<IndexedDBMsg_BlobOrFileInfo
> >::iterator blob_iter
;
260 for (value_iter
= values
.begin(), blob_iter
= blob_or_file_infos
->begin();
261 value_iter
!= values
.end();
262 ++value_iter
, ++blob_iter
) {
263 if (!CreateAllBlobs(value_iter
->blob_info
, &*blob_iter
, dispatcher_host
))
266 dispatcher_host
->Send(
267 new IndexedDBMsg_CallbacksSuccessCursorPrefetch(*params
));
270 static void FillInBlobData(
271 const std::vector
<IndexedDBBlobInfo
>& blob_info
,
272 std::vector
<IndexedDBMsg_BlobOrFileInfo
>* blob_or_file_info
) {
273 for (std::vector
<IndexedDBBlobInfo
>::const_iterator iter
= blob_info
.begin();
274 iter
!= blob_info
.end();
276 if (iter
->is_file()) {
277 IndexedDBMsg_BlobOrFileInfo info
;
279 info
.mime_type
= iter
->type();
280 info
.file_name
= iter
->file_name();
281 info
.file_path
= iter
->file_path().AsUTF16Unsafe();
282 info
.size
= iter
->size();
283 info
.last_modified
= iter
->last_modified().ToDoubleT();
284 blob_or_file_info
->push_back(info
);
286 IndexedDBMsg_BlobOrFileInfo info
;
287 info
.mime_type
= iter
->type();
288 info
.size
= iter
->size();
289 blob_or_file_info
->push_back(info
);
294 void IndexedDBCallbacks::RegisterBlobsAndSend(
295 const std::vector
<IndexedDBBlobInfo
>& blob_info
,
296 const base::Closure
& callback
) {
297 std::vector
<IndexedDBBlobInfo
>::const_iterator iter
;
298 for (iter
= blob_info
.begin(); iter
!= blob_info
.end(); ++iter
) {
299 if (!iter
->mark_used_callback().is_null())
300 iter
->mark_used_callback().Run();
302 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO
));
303 BrowserThread::PostTask(BrowserThread::IO
, FROM_HERE
, callback
);
306 void IndexedDBCallbacks::OnSuccess(scoped_refptr
<IndexedDBCursor
> cursor
,
307 const IndexedDBKey
& key
,
308 const IndexedDBKey
& primary_key
,
309 IndexedDBValue
* value
) {
310 DCHECK(dispatcher_host_
.get());
312 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
313 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
314 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
315 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
316 DCHECK_EQ(blink::WebIDBDataLossNone
, data_loss_
);
318 int32 ipc_object_id
= dispatcher_host_
->Add(cursor
.get());
319 scoped_ptr
<IndexedDBMsg_CallbacksSuccessIDBCursor_Params
> params(
320 new IndexedDBMsg_CallbacksSuccessIDBCursor_Params());
321 params
->ipc_thread_id
= ipc_thread_id_
;
322 params
->ipc_callbacks_id
= ipc_callbacks_id_
;
323 params
->ipc_cursor_id
= ipc_object_id
;
325 params
->primary_key
= primary_key
;
326 if (value
&& !value
->empty())
327 std::swap(params
->value
, value
->bits
);
328 // TODO(alecflett): Avoid a copy here: the whole params object is
329 // being copied into the message.
330 if (!value
|| value
->blob_info
.empty()) {
331 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksSuccessIDBCursor(*params
));
333 IndexedDBMsg_CallbacksSuccessIDBCursor_Params
* p
= params
.get();
334 FillInBlobData(value
->blob_info
, &p
->blob_or_file_info
);
335 RegisterBlobsAndSend(
338 CreateBlobsAndSend
<IndexedDBMsg_CallbacksSuccessIDBCursor_Params
,
339 IndexedDBMsg_CallbacksSuccessIDBCursor
>,
340 base::Owned(params
.release()),
343 base::Unretained(&p
->blob_or_file_info
)));
345 dispatcher_host_
= NULL
;
348 void IndexedDBCallbacks::OnSuccess(const IndexedDBKey
& key
,
349 const IndexedDBKey
& primary_key
,
350 IndexedDBValue
* value
) {
351 DCHECK(dispatcher_host_
.get());
353 DCHECK_NE(kNoCursor
, ipc_cursor_id_
);
354 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
355 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
356 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
357 DCHECK_EQ(blink::WebIDBDataLossNone
, data_loss_
);
359 IndexedDBCursor
* idb_cursor
=
360 dispatcher_host_
->GetCursorFromId(ipc_cursor_id_
);
366 scoped_ptr
<IndexedDBMsg_CallbacksSuccessCursorContinue_Params
> params(
367 new IndexedDBMsg_CallbacksSuccessCursorContinue_Params());
368 params
->ipc_thread_id
= ipc_thread_id_
;
369 params
->ipc_callbacks_id
= ipc_callbacks_id_
;
370 params
->ipc_cursor_id
= ipc_cursor_id_
;
372 params
->primary_key
= primary_key
;
373 if (value
&& !value
->empty())
374 std::swap(params
->value
, value
->bits
);
375 // TODO(alecflett): Avoid a copy here: the whole params object is
376 // being copied into the message.
377 if (!value
|| value
->blob_info
.empty()) {
378 dispatcher_host_
->Send(
379 new IndexedDBMsg_CallbacksSuccessCursorContinue(*params
));
381 IndexedDBMsg_CallbacksSuccessCursorContinue_Params
* p
= params
.get();
382 FillInBlobData(value
->blob_info
, &p
->blob_or_file_info
);
383 RegisterBlobsAndSend(
385 base::Bind(CreateBlobsAndSend
<
386 IndexedDBMsg_CallbacksSuccessCursorContinue_Params
,
387 IndexedDBMsg_CallbacksSuccessCursorContinue
>,
388 base::Owned(params
.release()),
391 base::Unretained(&p
->blob_or_file_info
)));
393 dispatcher_host_
= NULL
;
396 void IndexedDBCallbacks::OnSuccessWithPrefetch(
397 const std::vector
<IndexedDBKey
>& keys
,
398 const std::vector
<IndexedDBKey
>& primary_keys
,
399 std::vector
<IndexedDBValue
>& values
) {
400 DCHECK_EQ(keys
.size(), primary_keys
.size());
401 DCHECK_EQ(keys
.size(), values
.size());
403 DCHECK(dispatcher_host_
.get());
405 DCHECK_NE(kNoCursor
, ipc_cursor_id_
);
406 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
407 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
408 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
409 DCHECK_EQ(blink::WebIDBDataLossNone
, data_loss_
);
411 std::vector
<IndexedDBKey
> msgKeys
;
412 std::vector
<IndexedDBKey
> msgPrimaryKeys
;
414 for (size_t i
= 0; i
< keys
.size(); ++i
) {
415 msgKeys
.push_back(keys
[i
]);
416 msgPrimaryKeys
.push_back(primary_keys
[i
]);
419 scoped_ptr
<IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params
> params(
420 new IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params());
421 params
->ipc_thread_id
= ipc_thread_id_
;
422 params
->ipc_callbacks_id
= ipc_callbacks_id_
;
423 params
->ipc_cursor_id
= ipc_cursor_id_
;
424 params
->keys
= msgKeys
;
425 params
->primary_keys
= msgPrimaryKeys
;
426 std::vector
<std::string
>& values_bits
= params
->values
;
427 values_bits
.resize(values
.size());
428 std::vector
<std::vector
<IndexedDBMsg_BlobOrFileInfo
> >& values_blob_infos
=
429 params
->blob_or_file_infos
;
430 values_blob_infos
.resize(values
.size());
432 bool found_blob_info
= false;
433 std::vector
<IndexedDBValue
>::iterator iter
= values
.begin();
434 for (size_t i
= 0; iter
!= values
.end(); ++iter
, ++i
) {
435 values_bits
[i
].swap(iter
->bits
);
436 if (iter
->blob_info
.size()) {
437 found_blob_info
= true;
438 FillInBlobData(iter
->blob_info
, &values_blob_infos
[i
]);
439 std::vector
<IndexedDBBlobInfo
>::const_iterator blob_iter
;
440 for (blob_iter
= iter
->blob_info
.begin();
441 blob_iter
!= iter
->blob_info
.end();
443 if (!blob_iter
->mark_used_callback().is_null())
444 blob_iter
->mark_used_callback().Run();
449 if (found_blob_info
) {
450 BrowserThread::PostTask(
453 base::Bind(BlobLookupForCursorPrefetch
,
454 base::Owned(params
.release()),
457 base::Unretained(¶ms
->blob_or_file_infos
)));
459 dispatcher_host_
->Send(
460 new IndexedDBMsg_CallbacksSuccessCursorPrefetch(*params
.get()));
462 dispatcher_host_
= NULL
;
465 void IndexedDBCallbacks::OnSuccess(IndexedDBValue
* value
,
466 const IndexedDBKey
& key
,
467 const IndexedDBKeyPath
& key_path
) {
468 DCHECK(dispatcher_host_
.get());
470 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
471 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
472 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
473 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
474 DCHECK_EQ(blink::WebIDBDataLossNone
, data_loss_
);
476 scoped_ptr
<IndexedDBMsg_CallbacksSuccessValueWithKey_Params
> params(
477 new IndexedDBMsg_CallbacksSuccessValueWithKey_Params());
478 params
->ipc_thread_id
= ipc_thread_id_
;
479 params
->ipc_callbacks_id
= ipc_callbacks_id_
;
480 params
->primary_key
= key
;
481 params
->key_path
= key_path
;
482 if (value
&& !value
->empty())
483 std::swap(params
->value
, value
->bits
);
484 if (!value
|| value
->blob_info
.empty()) {
485 dispatcher_host_
->Send(
486 new IndexedDBMsg_CallbacksSuccessValueWithKey(*params
));
488 IndexedDBMsg_CallbacksSuccessValueWithKey_Params
* p
= params
.get();
489 FillInBlobData(value
->blob_info
, &p
->blob_or_file_info
);
490 RegisterBlobsAndSend(
493 CreateBlobsAndSend
<IndexedDBMsg_CallbacksSuccessValueWithKey_Params
,
494 IndexedDBMsg_CallbacksSuccessValueWithKey
>,
495 base::Owned(params
.release()),
498 base::Unretained(&p
->blob_or_file_info
)));
500 dispatcher_host_
= NULL
;
503 void IndexedDBCallbacks::OnSuccess(IndexedDBValue
* value
) {
504 DCHECK(dispatcher_host_
.get());
505 DCHECK(kNoCursor
== ipc_cursor_id_
|| value
== NULL
);
506 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
507 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
508 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
509 DCHECK_EQ(blink::WebIDBDataLossNone
, data_loss_
);
511 scoped_ptr
<IndexedDBMsg_CallbacksSuccessValue_Params
> params(
512 new IndexedDBMsg_CallbacksSuccessValue_Params());
513 params
->ipc_thread_id
= ipc_thread_id_
;
514 params
->ipc_callbacks_id
= ipc_callbacks_id_
;
515 if (value
&& !value
->empty())
516 std::swap(params
->value
, value
->bits
);
517 if (!value
|| value
->blob_info
.empty()) {
518 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksSuccessValue(*params
));
520 IndexedDBMsg_CallbacksSuccessValue_Params
* p
= params
.get();
521 FillInBlobData(value
->blob_info
, &p
->blob_or_file_info
);
522 RegisterBlobsAndSend(
524 base::Bind(CreateBlobsAndSend
<IndexedDBMsg_CallbacksSuccessValue_Params
,
525 IndexedDBMsg_CallbacksSuccessValue
>,
526 base::Owned(params
.release()),
529 base::Unretained(&p
->blob_or_file_info
)));
531 dispatcher_host_
= NULL
;
534 void IndexedDBCallbacks::OnSuccess(const IndexedDBKey
& value
) {
535 DCHECK(dispatcher_host_
.get());
537 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
538 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
539 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
540 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
541 DCHECK_EQ(blink::WebIDBDataLossNone
, data_loss_
);
543 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksSuccessIndexedDBKey(
544 ipc_thread_id_
, ipc_callbacks_id_
, value
));
545 dispatcher_host_
= NULL
;
548 void IndexedDBCallbacks::OnSuccess(int64 value
) {
549 DCHECK(dispatcher_host_
.get());
551 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
552 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
553 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
554 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
555 DCHECK_EQ(blink::WebIDBDataLossNone
, data_loss_
);
557 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksSuccessInteger(
558 ipc_thread_id_
, ipc_callbacks_id_
, value
));
559 dispatcher_host_
= NULL
;
562 void IndexedDBCallbacks::OnSuccess() {
563 DCHECK(dispatcher_host_
.get());
565 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
566 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
567 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
568 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
569 DCHECK_EQ(blink::WebIDBDataLossNone
, data_loss_
);
571 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksSuccessUndefined(
572 ipc_thread_id_
, ipc_callbacks_id_
));
573 dispatcher_host_
= NULL
;
576 } // namespace content