Blink roll 25b6bd3a7a131ffe68d809546ad1a20707915cdc:3a503f41ae42e5b79cfcd2ff10e65afde...
[chromium-blink-merge.git] / content / browser / indexed_db / indexed_db_callbacks.cc
bloba5aafddd557f3b871f816d978d54706f964de8e6
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"
7 #include <algorithm>
9 #include "base/guid.h"
10 #include "base/metrics/histogram.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/time/time.h"
13 #include "content/browser/child_process_security_policy_impl.h"
14 #include "content/browser/fileapi/fileapi_message_filter.h"
15 #include "content/browser/indexed_db/indexed_db_blob_info.h"
16 #include "content/browser/indexed_db/indexed_db_connection.h"
17 #include "content/browser/indexed_db/indexed_db_context_impl.h"
18 #include "content/browser/indexed_db/indexed_db_cursor.h"
19 #include "content/browser/indexed_db/indexed_db_database_callbacks.h"
20 #include "content/browser/indexed_db/indexed_db_database_error.h"
21 #include "content/browser/indexed_db/indexed_db_metadata.h"
22 #include "content/browser/indexed_db/indexed_db_value.h"
23 #include "content/common/indexed_db/indexed_db_constants.h"
24 #include "content/common/indexed_db/indexed_db_messages.h"
25 #include "storage/browser/blob/blob_storage_context.h"
26 #include "storage/browser/quota/quota_manager.h"
27 #include "storage/common/blob/blob_data.h"
28 #include "storage/common/blob/shareable_file_reference.h"
30 using storage::ShareableFileReference;
32 namespace content {
34 namespace {
35 const int32 kNoCursor = -1;
36 const int32 kNoDatabaseCallbacks = -1;
37 const int64 kNoTransaction = -1;
40 IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost* dispatcher_host,
41 int32 ipc_thread_id,
42 int32 ipc_callbacks_id)
43 : dispatcher_host_(dispatcher_host),
44 ipc_callbacks_id_(ipc_callbacks_id),
45 ipc_thread_id_(ipc_thread_id),
46 ipc_cursor_id_(kNoCursor),
47 host_transaction_id_(kNoTransaction),
48 ipc_database_id_(kNoDatabase),
49 ipc_database_callbacks_id_(kNoDatabaseCallbacks),
50 data_loss_(blink::WebIDBDataLossNone),
51 sent_blocked_(false) {
54 IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost* dispatcher_host,
55 int32 ipc_thread_id,
56 int32 ipc_callbacks_id,
57 int32 ipc_cursor_id)
58 : dispatcher_host_(dispatcher_host),
59 ipc_callbacks_id_(ipc_callbacks_id),
60 ipc_thread_id_(ipc_thread_id),
61 ipc_cursor_id_(ipc_cursor_id),
62 host_transaction_id_(kNoTransaction),
63 ipc_database_id_(kNoDatabase),
64 ipc_database_callbacks_id_(kNoDatabaseCallbacks),
65 data_loss_(blink::WebIDBDataLossNone),
66 sent_blocked_(false) {
69 IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost* dispatcher_host,
70 int32 ipc_thread_id,
71 int32 ipc_callbacks_id,
72 int32 ipc_database_callbacks_id,
73 int64 host_transaction_id,
74 const GURL& origin_url)
75 : dispatcher_host_(dispatcher_host),
76 ipc_callbacks_id_(ipc_callbacks_id),
77 ipc_thread_id_(ipc_thread_id),
78 ipc_cursor_id_(kNoCursor),
79 host_transaction_id_(host_transaction_id),
80 origin_url_(origin_url),
81 ipc_database_id_(kNoDatabase),
82 ipc_database_callbacks_id_(ipc_database_callbacks_id),
83 data_loss_(blink::WebIDBDataLossNone),
84 sent_blocked_(false) {
87 IndexedDBCallbacks::~IndexedDBCallbacks() {}
89 void IndexedDBCallbacks::OnError(const IndexedDBDatabaseError& error) {
90 DCHECK(dispatcher_host_.get());
92 dispatcher_host_->Send(new IndexedDBMsg_CallbacksError(
93 ipc_thread_id_, ipc_callbacks_id_, error.code(), error.message()));
94 dispatcher_host_ = NULL;
96 if (!connection_open_start_time_.is_null()) {
97 UMA_HISTOGRAM_MEDIUM_TIMES(
98 "WebCore.IndexedDB.OpenTime.Error",
99 base::TimeTicks::Now() - connection_open_start_time_);
100 connection_open_start_time_ = base::TimeTicks();
104 void IndexedDBCallbacks::OnSuccess(const std::vector<base::string16>& value) {
105 DCHECK(dispatcher_host_.get());
107 DCHECK_EQ(kNoCursor, ipc_cursor_id_);
108 DCHECK_EQ(kNoTransaction, host_transaction_id_);
109 DCHECK_EQ(kNoDatabase, ipc_database_id_);
110 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
111 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
113 std::vector<base::string16> list;
114 for (unsigned i = 0; i < value.size(); ++i)
115 list.push_back(value[i]);
117 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessStringList(
118 ipc_thread_id_, ipc_callbacks_id_, list));
119 dispatcher_host_ = NULL;
122 void IndexedDBCallbacks::OnBlocked(int64 existing_version) {
123 DCHECK(dispatcher_host_.get());
125 DCHECK_EQ(kNoCursor, ipc_cursor_id_);
126 // No transaction/db callbacks for DeleteDatabase.
127 DCHECK_EQ(kNoTransaction == host_transaction_id_,
128 kNoDatabaseCallbacks == ipc_database_callbacks_id_);
129 DCHECK_EQ(kNoDatabase, ipc_database_id_);
131 if (sent_blocked_)
132 return;
134 sent_blocked_ = true;
135 dispatcher_host_->Send(new IndexedDBMsg_CallbacksIntBlocked(
136 ipc_thread_id_, ipc_callbacks_id_, existing_version));
138 if (!connection_open_start_time_.is_null()) {
139 UMA_HISTOGRAM_MEDIUM_TIMES(
140 "WebCore.IndexedDB.OpenTime.Blocked",
141 base::TimeTicks::Now() - connection_open_start_time_);
142 connection_open_start_time_ = base::TimeTicks();
146 void IndexedDBCallbacks::OnDataLoss(blink::WebIDBDataLoss data_loss,
147 std::string data_loss_message) {
148 DCHECK_NE(blink::WebIDBDataLossNone, data_loss);
149 data_loss_ = data_loss;
150 data_loss_message_ = data_loss_message;
153 void IndexedDBCallbacks::OnUpgradeNeeded(
154 int64 old_version,
155 scoped_ptr<IndexedDBConnection> connection,
156 const IndexedDBDatabaseMetadata& metadata) {
157 DCHECK(dispatcher_host_.get());
159 DCHECK_EQ(kNoCursor, ipc_cursor_id_);
160 DCHECK_NE(kNoTransaction, host_transaction_id_);
161 DCHECK_EQ(kNoDatabase, ipc_database_id_);
162 DCHECK_NE(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
164 dispatcher_host_->RegisterTransactionId(host_transaction_id_, origin_url_);
165 int32 ipc_database_id =
166 dispatcher_host_->Add(connection.release(), ipc_thread_id_, origin_url_);
167 if (ipc_database_id < 0)
168 return;
169 ipc_database_id_ = ipc_database_id;
170 IndexedDBMsg_CallbacksUpgradeNeeded_Params params;
171 params.ipc_thread_id = ipc_thread_id_;
172 params.ipc_callbacks_id = ipc_callbacks_id_;
173 params.ipc_database_id = ipc_database_id;
174 params.ipc_database_callbacks_id = ipc_database_callbacks_id_;
175 params.old_version = old_version;
176 params.idb_metadata = IndexedDBDispatcherHost::ConvertMetadata(metadata);
177 params.data_loss = data_loss_;
178 params.data_loss_message = data_loss_message_;
179 dispatcher_host_->Send(new IndexedDBMsg_CallbacksUpgradeNeeded(params));
181 if (!connection_open_start_time_.is_null()) {
182 UMA_HISTOGRAM_MEDIUM_TIMES(
183 "WebCore.IndexedDB.OpenTime.UpgradeNeeded",
184 base::TimeTicks::Now() - connection_open_start_time_);
185 connection_open_start_time_ = base::TimeTicks();
189 void IndexedDBCallbacks::OnSuccess(scoped_ptr<IndexedDBConnection> connection,
190 const IndexedDBDatabaseMetadata& metadata) {
191 DCHECK(dispatcher_host_.get());
193 DCHECK_EQ(kNoCursor, ipc_cursor_id_);
194 DCHECK_NE(kNoTransaction, host_transaction_id_);
195 DCHECK_NE(ipc_database_id_ == kNoDatabase, !connection);
196 DCHECK_NE(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
198 scoped_refptr<IndexedDBCallbacks> self(this);
200 int32 ipc_object_id = kNoDatabase;
201 // Only register if the connection was not previously sent in OnUpgradeNeeded.
202 if (ipc_database_id_ == kNoDatabase) {
203 ipc_object_id = dispatcher_host_->Add(
204 connection.release(), ipc_thread_id_, origin_url_);
207 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessIDBDatabase(
208 ipc_thread_id_,
209 ipc_callbacks_id_,
210 ipc_database_callbacks_id_,
211 ipc_object_id,
212 IndexedDBDispatcherHost::ConvertMetadata(metadata)));
213 dispatcher_host_ = NULL;
215 if (!connection_open_start_time_.is_null()) {
216 UMA_HISTOGRAM_MEDIUM_TIMES(
217 "WebCore.IndexedDB.OpenTime.Success",
218 base::TimeTicks::Now() - connection_open_start_time_);
219 connection_open_start_time_ = base::TimeTicks();
223 static std::string CreateBlobData(
224 const IndexedDBBlobInfo& blob_info,
225 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host,
226 storage::BlobStorageContext* blob_storage_context,
227 base::TaskRunner* task_runner) {
228 std::string uuid = blob_info.uuid();
229 if (!uuid.empty()) {
230 // We're sending back a live blob, not a reference into our backing store.
231 scoped_ptr<storage::BlobDataHandle> blob_data_handle(
232 blob_storage_context->GetBlobDataFromUUID(uuid));
233 dispatcher_host->HoldBlobDataHandle(uuid, blob_data_handle.Pass());
234 return uuid;
236 scoped_refptr<ShareableFileReference> shareable_file =
237 ShareableFileReference::Get(blob_info.file_path());
238 if (!shareable_file.get()) {
239 shareable_file = ShareableFileReference::GetOrCreate(
240 blob_info.file_path(),
241 ShareableFileReference::DONT_DELETE_ON_FINAL_RELEASE,
242 task_runner);
243 if (!blob_info.release_callback().is_null())
244 shareable_file->AddFinalReleaseCallback(blob_info.release_callback());
247 uuid = base::GenerateGUID();
248 scoped_refptr<storage::BlobData> blob_data = new storage::BlobData(uuid);
249 blob_data->set_content_type(base::UTF16ToUTF8(blob_info.type()));
250 blob_data->AppendFile(
251 blob_info.file_path(), 0, blob_info.size(), blob_info.last_modified());
252 scoped_ptr<storage::BlobDataHandle> blob_data_handle(
253 blob_storage_context->AddFinishedBlob(blob_data.get()));
254 dispatcher_host->HoldBlobDataHandle(uuid, blob_data_handle.Pass());
256 return uuid;
259 static bool CreateAllBlobs(
260 const std::vector<IndexedDBBlobInfo>& blob_info,
261 std::vector<IndexedDBMsg_BlobOrFileInfo>* blob_or_file_info,
262 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host) {
263 DCHECK_EQ(blob_info.size(), blob_or_file_info->size());
264 size_t i;
265 if (!dispatcher_host->blob_storage_context())
266 return false;
267 for (i = 0; i < blob_info.size(); ++i) {
268 (*blob_or_file_info)[i].uuid =
269 CreateBlobData(blob_info[i],
270 dispatcher_host,
271 dispatcher_host->blob_storage_context(),
272 dispatcher_host->Context()->TaskRunner());
274 return true;
277 template <class ParamType, class MsgType>
278 static void CreateBlobsAndSend(
279 ParamType* params,
280 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host,
281 const std::vector<IndexedDBBlobInfo>& blob_info,
282 std::vector<IndexedDBMsg_BlobOrFileInfo>* blob_or_file_info) {
283 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
284 if (CreateAllBlobs(blob_info, blob_or_file_info, dispatcher_host))
285 dispatcher_host->Send(new MsgType(*params));
288 static void BlobLookupForCursorPrefetch(
289 IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params* params,
290 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host,
291 const std::vector<IndexedDBValue>& values) {
292 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
293 DCHECK_EQ(values.size(), params->blob_or_file_infos.size());
295 std::vector<IndexedDBValue>::const_iterator value_iter;
296 std::vector<std::vector<IndexedDBMsg_BlobOrFileInfo> >::iterator blob_iter;
297 for (value_iter = values.begin(), blob_iter =
298 params->blob_or_file_infos.begin(); value_iter != values.end();
299 ++value_iter, ++blob_iter) {
300 if (!CreateAllBlobs(value_iter->blob_info, &*blob_iter, dispatcher_host))
301 return;
303 dispatcher_host->Send(
304 new IndexedDBMsg_CallbacksSuccessCursorPrefetch(*params));
307 static void FillInBlobData(
308 const std::vector<IndexedDBBlobInfo>& blob_info,
309 std::vector<IndexedDBMsg_BlobOrFileInfo>* blob_or_file_info) {
310 for (const auto& iter : blob_info) {
311 if (iter.is_file()) {
312 IndexedDBMsg_BlobOrFileInfo info;
313 info.is_file = true;
314 info.mime_type = iter.type();
315 info.file_name = iter.file_name();
316 info.file_path = iter.file_path().AsUTF16Unsafe();
317 info.size = iter.size();
318 info.last_modified = iter.last_modified().ToDoubleT();
319 blob_or_file_info->push_back(info);
320 } else {
321 IndexedDBMsg_BlobOrFileInfo info;
322 info.mime_type = iter.type();
323 info.size = iter.size();
324 blob_or_file_info->push_back(info);
329 void IndexedDBCallbacks::RegisterBlobsAndSend(
330 const std::vector<IndexedDBBlobInfo>& blob_info,
331 const base::Closure& callback) {
332 for (const auto& iter : blob_info) {
333 if (!iter.mark_used_callback().is_null())
334 iter.mark_used_callback().Run();
336 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO));
337 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, callback);
340 void IndexedDBCallbacks::OnSuccess(scoped_refptr<IndexedDBCursor> cursor,
341 const IndexedDBKey& key,
342 const IndexedDBKey& primary_key,
343 IndexedDBValue* value) {
344 DCHECK(dispatcher_host_.get());
346 DCHECK_EQ(kNoCursor, ipc_cursor_id_);
347 DCHECK_EQ(kNoTransaction, host_transaction_id_);
348 DCHECK_EQ(kNoDatabase, ipc_database_id_);
349 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
350 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
352 int32 ipc_object_id = dispatcher_host_->Add(cursor.get());
353 scoped_ptr<IndexedDBMsg_CallbacksSuccessIDBCursor_Params> params(
354 new IndexedDBMsg_CallbacksSuccessIDBCursor_Params());
355 params->ipc_thread_id = ipc_thread_id_;
356 params->ipc_callbacks_id = ipc_callbacks_id_;
357 params->ipc_cursor_id = ipc_object_id;
358 params->key = key;
359 params->primary_key = primary_key;
360 if (value && !value->empty())
361 std::swap(params->value, value->bits);
362 // TODO(alecflett): Avoid a copy here: the whole params object is
363 // being copied into the message.
364 if (!value || value->blob_info.empty()) {
365 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessIDBCursor(*params));
366 } else {
367 IndexedDBMsg_CallbacksSuccessIDBCursor_Params* p = params.get();
368 FillInBlobData(value->blob_info, &p->blob_or_file_info);
369 RegisterBlobsAndSend(
370 value->blob_info,
371 base::Bind(
372 CreateBlobsAndSend<IndexedDBMsg_CallbacksSuccessIDBCursor_Params,
373 IndexedDBMsg_CallbacksSuccessIDBCursor>,
374 base::Owned(params.release()),
375 dispatcher_host_,
376 value->blob_info,
377 base::Unretained(&p->blob_or_file_info)));
379 dispatcher_host_ = NULL;
382 void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& key,
383 const IndexedDBKey& primary_key,
384 IndexedDBValue* value) {
385 DCHECK(dispatcher_host_.get());
387 DCHECK_NE(kNoCursor, ipc_cursor_id_);
388 DCHECK_EQ(kNoTransaction, host_transaction_id_);
389 DCHECK_EQ(kNoDatabase, ipc_database_id_);
390 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
391 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
393 IndexedDBCursor* idb_cursor =
394 dispatcher_host_->GetCursorFromId(ipc_cursor_id_);
396 DCHECK(idb_cursor);
397 if (!idb_cursor)
398 return;
400 scoped_ptr<IndexedDBMsg_CallbacksSuccessCursorContinue_Params> params(
401 new IndexedDBMsg_CallbacksSuccessCursorContinue_Params());
402 params->ipc_thread_id = ipc_thread_id_;
403 params->ipc_callbacks_id = ipc_callbacks_id_;
404 params->ipc_cursor_id = ipc_cursor_id_;
405 params->key = key;
406 params->primary_key = primary_key;
407 if (value && !value->empty())
408 std::swap(params->value, value->bits);
409 // TODO(alecflett): Avoid a copy here: the whole params object is
410 // being copied into the message.
411 if (!value || value->blob_info.empty()) {
412 dispatcher_host_->Send(
413 new IndexedDBMsg_CallbacksSuccessCursorContinue(*params));
414 } else {
415 IndexedDBMsg_CallbacksSuccessCursorContinue_Params* p = params.get();
416 FillInBlobData(value->blob_info, &p->blob_or_file_info);
417 RegisterBlobsAndSend(
418 value->blob_info,
419 base::Bind(CreateBlobsAndSend<
420 IndexedDBMsg_CallbacksSuccessCursorContinue_Params,
421 IndexedDBMsg_CallbacksSuccessCursorContinue>,
422 base::Owned(params.release()),
423 dispatcher_host_,
424 value->blob_info,
425 base::Unretained(&p->blob_or_file_info)));
427 dispatcher_host_ = NULL;
430 void IndexedDBCallbacks::OnSuccessWithPrefetch(
431 const std::vector<IndexedDBKey>& keys,
432 const std::vector<IndexedDBKey>& primary_keys,
433 std::vector<IndexedDBValue>* values) {
434 DCHECK_EQ(keys.size(), primary_keys.size());
435 DCHECK_EQ(keys.size(), values->size());
437 DCHECK(dispatcher_host_.get());
439 DCHECK_NE(kNoCursor, ipc_cursor_id_);
440 DCHECK_EQ(kNoTransaction, host_transaction_id_);
441 DCHECK_EQ(kNoDatabase, ipc_database_id_);
442 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
443 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
445 std::vector<IndexedDBKey> msgKeys;
446 std::vector<IndexedDBKey> msgPrimaryKeys;
448 for (size_t i = 0; i < keys.size(); ++i) {
449 msgKeys.push_back(keys[i]);
450 msgPrimaryKeys.push_back(primary_keys[i]);
453 scoped_ptr<IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params> params(
454 new IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params());
455 params->ipc_thread_id = ipc_thread_id_;
456 params->ipc_callbacks_id = ipc_callbacks_id_;
457 params->ipc_cursor_id = ipc_cursor_id_;
458 params->keys = msgKeys;
459 params->primary_keys = msgPrimaryKeys;
460 std::vector<std::string>& values_bits = params->values;
461 values_bits.resize(values->size());
462 std::vector<std::vector<IndexedDBMsg_BlobOrFileInfo> >& values_blob_infos =
463 params->blob_or_file_infos;
464 values_blob_infos.resize(values->size());
466 bool found_blob_info = false;
467 std::vector<IndexedDBValue>::iterator iter = values->begin();
468 for (size_t i = 0; iter != values->end(); ++iter, ++i) {
469 values_bits[i].swap(iter->bits);
470 if (iter->blob_info.size()) {
471 found_blob_info = true;
472 FillInBlobData(iter->blob_info, &values_blob_infos[i]);
473 for (const auto& blob_iter : iter->blob_info) {
474 if (!blob_iter.mark_used_callback().is_null())
475 blob_iter.mark_used_callback().Run();
480 if (found_blob_info) {
481 BrowserThread::PostTask(BrowserThread::IO,
482 FROM_HERE,
483 base::Bind(BlobLookupForCursorPrefetch,
484 base::Owned(params.release()),
485 dispatcher_host_,
486 *values));
487 } else {
488 dispatcher_host_->Send(
489 new IndexedDBMsg_CallbacksSuccessCursorPrefetch(*params.get()));
491 dispatcher_host_ = NULL;
494 void IndexedDBCallbacks::OnSuccess(IndexedDBValue* value,
495 const IndexedDBKey& key,
496 const IndexedDBKeyPath& key_path) {
497 DCHECK(dispatcher_host_.get());
499 DCHECK_EQ(kNoCursor, ipc_cursor_id_);
500 DCHECK_EQ(kNoTransaction, host_transaction_id_);
501 DCHECK_EQ(kNoDatabase, ipc_database_id_);
502 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
503 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
505 scoped_ptr<IndexedDBMsg_CallbacksSuccessValueWithKey_Params> params(
506 new IndexedDBMsg_CallbacksSuccessValueWithKey_Params());
507 params->ipc_thread_id = ipc_thread_id_;
508 params->ipc_callbacks_id = ipc_callbacks_id_;
509 params->primary_key = key;
510 params->key_path = key_path;
511 if (value && !value->empty())
512 std::swap(params->value, value->bits);
513 if (!value || value->blob_info.empty()) {
514 dispatcher_host_->Send(
515 new IndexedDBMsg_CallbacksSuccessValueWithKey(*params));
516 } else {
517 IndexedDBMsg_CallbacksSuccessValueWithKey_Params* p = params.get();
518 FillInBlobData(value->blob_info, &p->blob_or_file_info);
519 RegisterBlobsAndSend(
520 value->blob_info,
521 base::Bind(
522 CreateBlobsAndSend<IndexedDBMsg_CallbacksSuccessValueWithKey_Params,
523 IndexedDBMsg_CallbacksSuccessValueWithKey>,
524 base::Owned(params.release()),
525 dispatcher_host_,
526 value->blob_info,
527 base::Unretained(&p->blob_or_file_info)));
529 dispatcher_host_ = NULL;
532 void IndexedDBCallbacks::OnSuccess(IndexedDBValue* value) {
533 DCHECK(dispatcher_host_.get());
534 DCHECK(kNoCursor == ipc_cursor_id_ || value == NULL);
535 DCHECK_EQ(kNoTransaction, host_transaction_id_);
536 DCHECK_EQ(kNoDatabase, ipc_database_id_);
537 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
538 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
540 scoped_ptr<IndexedDBMsg_CallbacksSuccessValue_Params> params(
541 new IndexedDBMsg_CallbacksSuccessValue_Params());
542 params->ipc_thread_id = ipc_thread_id_;
543 params->ipc_callbacks_id = ipc_callbacks_id_;
544 if (value && !value->empty())
545 std::swap(params->value, value->bits);
546 if (!value || value->blob_info.empty()) {
547 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessValue(*params));
548 } else {
549 IndexedDBMsg_CallbacksSuccessValue_Params* p = params.get();
550 FillInBlobData(value->blob_info, &p->blob_or_file_info);
551 RegisterBlobsAndSend(
552 value->blob_info,
553 base::Bind(CreateBlobsAndSend<IndexedDBMsg_CallbacksSuccessValue_Params,
554 IndexedDBMsg_CallbacksSuccessValue>,
555 base::Owned(params.release()),
556 dispatcher_host_,
557 value->blob_info,
558 base::Unretained(&p->blob_or_file_info)));
560 dispatcher_host_ = NULL;
563 void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& value) {
564 DCHECK(dispatcher_host_.get());
566 DCHECK_EQ(kNoCursor, ipc_cursor_id_);
567 DCHECK_EQ(kNoTransaction, host_transaction_id_);
568 DCHECK_EQ(kNoDatabase, ipc_database_id_);
569 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
570 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
572 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessIndexedDBKey(
573 ipc_thread_id_, ipc_callbacks_id_, value));
574 dispatcher_host_ = NULL;
577 void IndexedDBCallbacks::OnSuccess(int64 value) {
578 DCHECK(dispatcher_host_.get());
580 DCHECK_EQ(kNoCursor, ipc_cursor_id_);
581 DCHECK_EQ(kNoTransaction, host_transaction_id_);
582 DCHECK_EQ(kNoDatabase, ipc_database_id_);
583 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
584 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
586 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessInteger(
587 ipc_thread_id_, ipc_callbacks_id_, value));
588 dispatcher_host_ = NULL;
591 void IndexedDBCallbacks::OnSuccess() {
592 DCHECK(dispatcher_host_.get());
594 DCHECK_EQ(kNoCursor, ipc_cursor_id_);
595 DCHECK_EQ(kNoTransaction, host_transaction_id_);
596 DCHECK_EQ(kNoDatabase, ipc_database_id_);
597 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
598 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
600 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessUndefined(
601 ipc_thread_id_, ipc_callbacks_id_));
602 dispatcher_host_ = NULL;
605 void IndexedDBCallbacks::SetConnectionOpenStartTime(
606 const base::TimeTicks& start_time) {
607 connection_open_start_time_ = start_time;
610 } // namespace content