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"
9 #include "base/metrics/histogram.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 "storage/browser/blob/blob_storage_context.h"
25 #include "storage/browser/blob/shareable_file_reference.h"
26 #include "storage/browser/quota/quota_manager.h"
28 using storage::ShareableFileReference
;
33 const int32 kNoCursor
= -1;
34 const int32 kNoDatabaseCallbacks
= -1;
35 const int64 kNoTransaction
= -1;
38 IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost
* dispatcher_host
,
40 int32 ipc_callbacks_id
)
41 : dispatcher_host_(dispatcher_host
),
42 ipc_callbacks_id_(ipc_callbacks_id
),
43 ipc_thread_id_(ipc_thread_id
),
44 ipc_cursor_id_(kNoCursor
),
45 host_transaction_id_(kNoTransaction
),
46 ipc_database_id_(kNoDatabase
),
47 ipc_database_callbacks_id_(kNoDatabaseCallbacks
),
48 data_loss_(blink::WebIDBDataLossNone
),
49 sent_blocked_(false) {
52 IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost
* dispatcher_host
,
54 int32 ipc_callbacks_id
,
56 : dispatcher_host_(dispatcher_host
),
57 ipc_callbacks_id_(ipc_callbacks_id
),
58 ipc_thread_id_(ipc_thread_id
),
59 ipc_cursor_id_(ipc_cursor_id
),
60 host_transaction_id_(kNoTransaction
),
61 ipc_database_id_(kNoDatabase
),
62 ipc_database_callbacks_id_(kNoDatabaseCallbacks
),
63 data_loss_(blink::WebIDBDataLossNone
),
64 sent_blocked_(false) {
67 IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost
* dispatcher_host
,
69 int32 ipc_callbacks_id
,
70 int32 ipc_database_callbacks_id
,
71 int64 host_transaction_id
,
72 const GURL
& origin_url
)
73 : dispatcher_host_(dispatcher_host
),
74 ipc_callbacks_id_(ipc_callbacks_id
),
75 ipc_thread_id_(ipc_thread_id
),
76 ipc_cursor_id_(kNoCursor
),
77 host_transaction_id_(host_transaction_id
),
78 origin_url_(origin_url
),
79 ipc_database_id_(kNoDatabase
),
80 ipc_database_callbacks_id_(ipc_database_callbacks_id
),
81 data_loss_(blink::WebIDBDataLossNone
),
82 sent_blocked_(false) {
85 IndexedDBCallbacks::~IndexedDBCallbacks() {}
87 void IndexedDBCallbacks::OnError(const IndexedDBDatabaseError
& error
) {
88 DCHECK(dispatcher_host_
.get());
90 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksError(
91 ipc_thread_id_
, ipc_callbacks_id_
, error
.code(), error
.message()));
92 dispatcher_host_
= NULL
;
94 if (!connection_open_start_time_
.is_null()) {
95 UMA_HISTOGRAM_MEDIUM_TIMES(
96 "WebCore.IndexedDB.OpenTime.Error",
97 base::TimeTicks::Now() - connection_open_start_time_
);
98 connection_open_start_time_
= base::TimeTicks();
102 void IndexedDBCallbacks::OnSuccess(const std::vector
<base::string16
>& value
) {
103 DCHECK(dispatcher_host_
.get());
105 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
106 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
107 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
108 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
109 DCHECK_EQ(blink::WebIDBDataLossNone
, data_loss_
);
111 std::vector
<base::string16
> list
;
112 for (unsigned i
= 0; i
< value
.size(); ++i
)
113 list
.push_back(value
[i
]);
115 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksSuccessStringList(
116 ipc_thread_id_
, ipc_callbacks_id_
, list
));
117 dispatcher_host_
= NULL
;
120 void IndexedDBCallbacks::OnBlocked(int64 existing_version
) {
121 DCHECK(dispatcher_host_
.get());
123 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
124 // No transaction/db callbacks for DeleteDatabase.
125 DCHECK_EQ(kNoTransaction
== host_transaction_id_
,
126 kNoDatabaseCallbacks
== ipc_database_callbacks_id_
);
127 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
132 sent_blocked_
= true;
133 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksIntBlocked(
134 ipc_thread_id_
, ipc_callbacks_id_
, existing_version
));
136 if (!connection_open_start_time_
.is_null()) {
137 UMA_HISTOGRAM_MEDIUM_TIMES(
138 "WebCore.IndexedDB.OpenTime.Blocked",
139 base::TimeTicks::Now() - connection_open_start_time_
);
140 connection_open_start_time_
= base::TimeTicks();
144 void IndexedDBCallbacks::OnDataLoss(blink::WebIDBDataLoss data_loss
,
145 std::string data_loss_message
) {
146 DCHECK_NE(blink::WebIDBDataLossNone
, data_loss
);
147 data_loss_
= data_loss
;
148 data_loss_message_
= data_loss_message
;
151 void IndexedDBCallbacks::OnUpgradeNeeded(
153 scoped_ptr
<IndexedDBConnection
> connection
,
154 const IndexedDBDatabaseMetadata
& metadata
) {
155 DCHECK(dispatcher_host_
.get());
157 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
158 DCHECK_NE(kNoTransaction
, host_transaction_id_
);
159 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
160 DCHECK_NE(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
162 dispatcher_host_
->RegisterTransactionId(host_transaction_id_
, origin_url_
);
163 int32 ipc_database_id
=
164 dispatcher_host_
->Add(connection
.release(), ipc_thread_id_
, origin_url_
);
165 if (ipc_database_id
< 0)
167 ipc_database_id_
= ipc_database_id
;
168 IndexedDBMsg_CallbacksUpgradeNeeded_Params params
;
169 params
.ipc_thread_id
= ipc_thread_id_
;
170 params
.ipc_callbacks_id
= ipc_callbacks_id_
;
171 params
.ipc_database_id
= ipc_database_id
;
172 params
.ipc_database_callbacks_id
= ipc_database_callbacks_id_
;
173 params
.old_version
= old_version
;
174 params
.idb_metadata
= IndexedDBDispatcherHost::ConvertMetadata(metadata
);
175 params
.data_loss
= data_loss_
;
176 params
.data_loss_message
= data_loss_message_
;
177 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksUpgradeNeeded(params
));
179 if (!connection_open_start_time_
.is_null()) {
180 UMA_HISTOGRAM_MEDIUM_TIMES(
181 "WebCore.IndexedDB.OpenTime.UpgradeNeeded",
182 base::TimeTicks::Now() - connection_open_start_time_
);
183 connection_open_start_time_
= base::TimeTicks();
187 void IndexedDBCallbacks::OnSuccess(scoped_ptr
<IndexedDBConnection
> connection
,
188 const IndexedDBDatabaseMetadata
& metadata
) {
189 DCHECK(dispatcher_host_
.get());
191 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
192 DCHECK_NE(kNoTransaction
, host_transaction_id_
);
193 DCHECK_NE(ipc_database_id_
== kNoDatabase
, !connection
);
194 DCHECK_NE(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
196 scoped_refptr
<IndexedDBCallbacks
> self(this);
198 int32 ipc_object_id
= kNoDatabase
;
199 // Only register if the connection was not previously sent in OnUpgradeNeeded.
200 if (ipc_database_id_
== kNoDatabase
) {
201 ipc_object_id
= dispatcher_host_
->Add(
202 connection
.release(), ipc_thread_id_
, origin_url_
);
205 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksSuccessIDBDatabase(
208 ipc_database_callbacks_id_
,
210 IndexedDBDispatcherHost::ConvertMetadata(metadata
)));
211 dispatcher_host_
= NULL
;
213 if (!connection_open_start_time_
.is_null()) {
214 UMA_HISTOGRAM_MEDIUM_TIMES(
215 "WebCore.IndexedDB.OpenTime.Success",
216 base::TimeTicks::Now() - connection_open_start_time_
);
217 connection_open_start_time_
= base::TimeTicks();
221 static std::string
CreateBlobData(
222 const IndexedDBBlobInfo
& blob_info
,
223 scoped_refptr
<IndexedDBDispatcherHost
> dispatcher_host
,
224 base::TaskRunner
* task_runner
) {
225 if (!blob_info
.uuid().empty()) {
226 // We're sending back a live blob, not a reference into our backing store.
227 return dispatcher_host
->HoldBlobData(blob_info
);
229 scoped_refptr
<ShareableFileReference
> shareable_file
=
230 ShareableFileReference::Get(blob_info
.file_path());
231 if (!shareable_file
.get()) {
232 shareable_file
= ShareableFileReference::GetOrCreate(
233 blob_info
.file_path(),
234 ShareableFileReference::DONT_DELETE_ON_FINAL_RELEASE
,
236 if (!blob_info
.release_callback().is_null())
237 shareable_file
->AddFinalReleaseCallback(blob_info
.release_callback());
239 return dispatcher_host
->HoldBlobData(blob_info
);
242 static bool CreateAllBlobs(
243 const std::vector
<IndexedDBBlobInfo
>& blob_info
,
244 std::vector
<IndexedDBMsg_BlobOrFileInfo
>* blob_or_file_info
,
245 scoped_refptr
<IndexedDBDispatcherHost
> dispatcher_host
) {
246 DCHECK_EQ(blob_info
.size(), blob_or_file_info
->size());
248 if (!dispatcher_host
->blob_storage_context())
250 for (i
= 0; i
< blob_info
.size(); ++i
) {
251 (*blob_or_file_info
)[i
].uuid
=
252 CreateBlobData(blob_info
[i
],
254 dispatcher_host
->Context()->TaskRunner());
259 template <class ParamType
, class MsgType
>
260 static void CreateBlobsAndSend(
262 scoped_refptr
<IndexedDBDispatcherHost
> dispatcher_host
,
263 const std::vector
<IndexedDBBlobInfo
>& blob_info
,
264 std::vector
<IndexedDBMsg_BlobOrFileInfo
>* blob_or_file_info
) {
265 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
266 if (CreateAllBlobs(blob_info
, blob_or_file_info
, dispatcher_host
))
267 dispatcher_host
->Send(new MsgType(*params
));
270 static void BlobLookupForCursorPrefetch(
271 IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params
* params
,
272 scoped_refptr
<IndexedDBDispatcherHost
> dispatcher_host
,
273 const std::vector
<IndexedDBValue
>& values
) {
274 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
275 DCHECK_EQ(values
.size(), params
->blob_or_file_infos
.size());
277 std::vector
<IndexedDBValue
>::const_iterator value_iter
;
278 std::vector
<std::vector
<IndexedDBMsg_BlobOrFileInfo
> >::iterator blob_iter
;
279 for (value_iter
= values
.begin(), blob_iter
=
280 params
->blob_or_file_infos
.begin(); value_iter
!= values
.end();
281 ++value_iter
, ++blob_iter
) {
282 if (!CreateAllBlobs(value_iter
->blob_info
, &*blob_iter
, dispatcher_host
))
285 dispatcher_host
->Send(
286 new IndexedDBMsg_CallbacksSuccessCursorPrefetch(*params
));
289 static void FillInBlobData(
290 const std::vector
<IndexedDBBlobInfo
>& blob_info
,
291 std::vector
<IndexedDBMsg_BlobOrFileInfo
>* blob_or_file_info
) {
292 for (const auto& iter
: blob_info
) {
293 if (iter
.is_file()) {
294 IndexedDBMsg_BlobOrFileInfo info
;
296 info
.mime_type
= iter
.type();
297 info
.file_name
= iter
.file_name();
298 info
.file_path
= iter
.file_path().AsUTF16Unsafe();
299 info
.size
= iter
.size();
300 info
.last_modified
= iter
.last_modified().ToDoubleT();
301 blob_or_file_info
->push_back(info
);
303 IndexedDBMsg_BlobOrFileInfo info
;
304 info
.mime_type
= iter
.type();
305 info
.size
= iter
.size();
306 blob_or_file_info
->push_back(info
);
311 void IndexedDBCallbacks::RegisterBlobsAndSend(
312 const std::vector
<IndexedDBBlobInfo
>& blob_info
,
313 const base::Closure
& callback
) {
314 for (const auto& iter
: blob_info
) {
315 if (!iter
.mark_used_callback().is_null())
316 iter
.mark_used_callback().Run();
318 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO
));
319 BrowserThread::PostTask(BrowserThread::IO
, FROM_HERE
, callback
);
322 void IndexedDBCallbacks::OnSuccess(scoped_refptr
<IndexedDBCursor
> cursor
,
323 const IndexedDBKey
& key
,
324 const IndexedDBKey
& primary_key
,
325 IndexedDBValue
* value
) {
326 DCHECK(dispatcher_host_
.get());
328 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
329 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
330 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
331 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
332 DCHECK_EQ(blink::WebIDBDataLossNone
, data_loss_
);
334 int32 ipc_object_id
= dispatcher_host_
->Add(cursor
.get());
335 scoped_ptr
<IndexedDBMsg_CallbacksSuccessIDBCursor_Params
> params(
336 new IndexedDBMsg_CallbacksSuccessIDBCursor_Params());
337 params
->ipc_thread_id
= ipc_thread_id_
;
338 params
->ipc_callbacks_id
= ipc_callbacks_id_
;
339 params
->ipc_cursor_id
= ipc_object_id
;
341 params
->primary_key
= primary_key
;
342 if (value
&& !value
->empty())
343 std::swap(params
->value
, value
->bits
);
344 // TODO(alecflett): Avoid a copy here: the whole params object is
345 // being copied into the message.
346 if (!value
|| value
->blob_info
.empty()) {
347 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksSuccessIDBCursor(*params
));
349 IndexedDBMsg_CallbacksSuccessIDBCursor_Params
* p
= params
.get();
350 FillInBlobData(value
->blob_info
, &p
->blob_or_file_info
);
351 RegisterBlobsAndSend(
354 CreateBlobsAndSend
<IndexedDBMsg_CallbacksSuccessIDBCursor_Params
,
355 IndexedDBMsg_CallbacksSuccessIDBCursor
>,
356 base::Owned(params
.release()),
359 base::Unretained(&p
->blob_or_file_info
)));
361 dispatcher_host_
= NULL
;
364 void IndexedDBCallbacks::OnSuccess(const IndexedDBKey
& key
,
365 const IndexedDBKey
& primary_key
,
366 IndexedDBValue
* value
) {
367 DCHECK(dispatcher_host_
.get());
369 DCHECK_NE(kNoCursor
, ipc_cursor_id_
);
370 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
371 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
372 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
373 DCHECK_EQ(blink::WebIDBDataLossNone
, data_loss_
);
375 IndexedDBCursor
* idb_cursor
=
376 dispatcher_host_
->GetCursorFromId(ipc_cursor_id_
);
382 scoped_ptr
<IndexedDBMsg_CallbacksSuccessCursorContinue_Params
> params(
383 new IndexedDBMsg_CallbacksSuccessCursorContinue_Params());
384 params
->ipc_thread_id
= ipc_thread_id_
;
385 params
->ipc_callbacks_id
= ipc_callbacks_id_
;
386 params
->ipc_cursor_id
= ipc_cursor_id_
;
388 params
->primary_key
= primary_key
;
389 if (value
&& !value
->empty())
390 std::swap(params
->value
, value
->bits
);
391 // TODO(alecflett): Avoid a copy here: the whole params object is
392 // being copied into the message.
393 if (!value
|| value
->blob_info
.empty()) {
394 dispatcher_host_
->Send(
395 new IndexedDBMsg_CallbacksSuccessCursorContinue(*params
));
397 IndexedDBMsg_CallbacksSuccessCursorContinue_Params
* p
= params
.get();
398 FillInBlobData(value
->blob_info
, &p
->blob_or_file_info
);
399 RegisterBlobsAndSend(
401 base::Bind(CreateBlobsAndSend
<
402 IndexedDBMsg_CallbacksSuccessCursorContinue_Params
,
403 IndexedDBMsg_CallbacksSuccessCursorContinue
>,
404 base::Owned(params
.release()),
407 base::Unretained(&p
->blob_or_file_info
)));
409 dispatcher_host_
= NULL
;
412 void IndexedDBCallbacks::OnSuccessWithPrefetch(
413 const std::vector
<IndexedDBKey
>& keys
,
414 const std::vector
<IndexedDBKey
>& primary_keys
,
415 std::vector
<IndexedDBValue
>* values
) {
416 DCHECK_EQ(keys
.size(), primary_keys
.size());
417 DCHECK_EQ(keys
.size(), values
->size());
419 DCHECK(dispatcher_host_
.get());
421 DCHECK_NE(kNoCursor
, ipc_cursor_id_
);
422 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
423 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
424 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
425 DCHECK_EQ(blink::WebIDBDataLossNone
, data_loss_
);
427 std::vector
<IndexedDBKey
> msg_keys
;
428 std::vector
<IndexedDBKey
> msg_primary_keys
;
430 for (size_t i
= 0; i
< keys
.size(); ++i
) {
431 msg_keys
.push_back(keys
[i
]);
432 msg_primary_keys
.push_back(primary_keys
[i
]);
435 scoped_ptr
<IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params
> params(
436 new IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params());
437 params
->ipc_thread_id
= ipc_thread_id_
;
438 params
->ipc_callbacks_id
= ipc_callbacks_id_
;
439 params
->ipc_cursor_id
= ipc_cursor_id_
;
440 params
->keys
= msg_keys
;
441 params
->primary_keys
= msg_primary_keys
;
442 std::vector
<std::string
>& values_bits
= params
->values
;
443 values_bits
.resize(values
->size());
444 std::vector
<std::vector
<IndexedDBMsg_BlobOrFileInfo
> >& values_blob_infos
=
445 params
->blob_or_file_infos
;
446 values_blob_infos
.resize(values
->size());
448 bool found_blob_info
= false;
449 std::vector
<IndexedDBValue
>::iterator iter
= values
->begin();
450 for (size_t i
= 0; iter
!= values
->end(); ++iter
, ++i
) {
451 values_bits
[i
].swap(iter
->bits
);
452 if (iter
->blob_info
.size()) {
453 found_blob_info
= true;
454 FillInBlobData(iter
->blob_info
, &values_blob_infos
[i
]);
455 for (const auto& blob_iter
: iter
->blob_info
) {
456 if (!blob_iter
.mark_used_callback().is_null())
457 blob_iter
.mark_used_callback().Run();
462 if (found_blob_info
) {
463 BrowserThread::PostTask(BrowserThread::IO
,
465 base::Bind(BlobLookupForCursorPrefetch
,
466 base::Owned(params
.release()),
470 dispatcher_host_
->Send(
471 new IndexedDBMsg_CallbacksSuccessCursorPrefetch(*params
.get()));
473 dispatcher_host_
= NULL
;
476 void IndexedDBCallbacks::OnSuccess(IndexedDBValue
* value
,
477 const IndexedDBKey
& key
,
478 const IndexedDBKeyPath
& key_path
) {
479 DCHECK(dispatcher_host_
.get());
481 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
482 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
483 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
484 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
485 DCHECK_EQ(blink::WebIDBDataLossNone
, data_loss_
);
487 scoped_ptr
<IndexedDBMsg_CallbacksSuccessValueWithKey_Params
> params(
488 new IndexedDBMsg_CallbacksSuccessValueWithKey_Params());
489 params
->ipc_thread_id
= ipc_thread_id_
;
490 params
->ipc_callbacks_id
= ipc_callbacks_id_
;
491 params
->primary_key
= key
;
492 params
->key_path
= key_path
;
493 if (value
&& !value
->empty())
494 std::swap(params
->value
, value
->bits
);
495 if (!value
|| value
->blob_info
.empty()) {
496 dispatcher_host_
->Send(
497 new IndexedDBMsg_CallbacksSuccessValueWithKey(*params
));
499 IndexedDBMsg_CallbacksSuccessValueWithKey_Params
* p
= params
.get();
500 FillInBlobData(value
->blob_info
, &p
->blob_or_file_info
);
501 RegisterBlobsAndSend(
504 CreateBlobsAndSend
<IndexedDBMsg_CallbacksSuccessValueWithKey_Params
,
505 IndexedDBMsg_CallbacksSuccessValueWithKey
>,
506 base::Owned(params
.release()),
509 base::Unretained(&p
->blob_or_file_info
)));
511 dispatcher_host_
= NULL
;
514 void IndexedDBCallbacks::OnSuccess(IndexedDBValue
* value
) {
515 DCHECK(dispatcher_host_
.get());
516 DCHECK(kNoCursor
== ipc_cursor_id_
|| value
== NULL
);
517 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
518 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
519 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
520 DCHECK_EQ(blink::WebIDBDataLossNone
, data_loss_
);
522 scoped_ptr
<IndexedDBMsg_CallbacksSuccessValue_Params
> params(
523 new IndexedDBMsg_CallbacksSuccessValue_Params());
524 params
->ipc_thread_id
= ipc_thread_id_
;
525 params
->ipc_callbacks_id
= ipc_callbacks_id_
;
526 if (value
&& !value
->empty())
527 std::swap(params
->value
, value
->bits
);
528 if (!value
|| value
->blob_info
.empty()) {
529 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksSuccessValue(*params
));
531 IndexedDBMsg_CallbacksSuccessValue_Params
* p
= params
.get();
532 FillInBlobData(value
->blob_info
, &p
->blob_or_file_info
);
533 RegisterBlobsAndSend(
535 base::Bind(CreateBlobsAndSend
<IndexedDBMsg_CallbacksSuccessValue_Params
,
536 IndexedDBMsg_CallbacksSuccessValue
>,
537 base::Owned(params
.release()),
540 base::Unretained(&p
->blob_or_file_info
)));
542 dispatcher_host_
= NULL
;
545 void IndexedDBCallbacks::OnSuccess(const IndexedDBKey
& value
) {
546 DCHECK(dispatcher_host_
.get());
548 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
549 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
550 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
551 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
552 DCHECK_EQ(blink::WebIDBDataLossNone
, data_loss_
);
554 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksSuccessIndexedDBKey(
555 ipc_thread_id_
, ipc_callbacks_id_
, value
));
556 dispatcher_host_
= NULL
;
559 void IndexedDBCallbacks::OnSuccess(int64 value
) {
560 DCHECK(dispatcher_host_
.get());
562 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
563 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
564 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
565 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
566 DCHECK_EQ(blink::WebIDBDataLossNone
, data_loss_
);
568 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksSuccessInteger(
569 ipc_thread_id_
, ipc_callbacks_id_
, value
));
570 dispatcher_host_
= NULL
;
573 void IndexedDBCallbacks::OnSuccess() {
574 DCHECK(dispatcher_host_
.get());
576 DCHECK_EQ(kNoCursor
, ipc_cursor_id_
);
577 DCHECK_EQ(kNoTransaction
, host_transaction_id_
);
578 DCHECK_EQ(kNoDatabase
, ipc_database_id_
);
579 DCHECK_EQ(kNoDatabaseCallbacks
, ipc_database_callbacks_id_
);
580 DCHECK_EQ(blink::WebIDBDataLossNone
, data_loss_
);
582 dispatcher_host_
->Send(new IndexedDBMsg_CallbacksSuccessUndefined(
583 ipc_thread_id_
, ipc_callbacks_id_
));
584 dispatcher_host_
= NULL
;
587 void IndexedDBCallbacks::SetConnectionOpenStartTime(
588 const base::TimeTicks
& start_time
) {
589 connection_open_start_time_
= start_time
;
592 } // namespace content