indexed_db_callbacks.cc revision 116680a4aac90f2aa7413d9095a592090648e557
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. 4 5#include "content/browser/indexed_db/indexed_db_callbacks.h" 6 7#include <algorithm> 8 9#include "base/guid.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" 28 29using webkit_blob::ShareableFileReference; 30 31namespace content { 32 33namespace { 34const int32 kNoCursor = -1; 35const int32 kNoDatabaseCallbacks = -1; 36const int64 kNoTransaction = -1; 37} 38 39IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost* dispatcher_host, 40 int32 ipc_thread_id, 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) { 51} 52 53IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost* dispatcher_host, 54 int32 ipc_thread_id, 55 int32 ipc_callbacks_id, 56 int32 ipc_cursor_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) { 66} 67 68IndexedDBCallbacks::IndexedDBCallbacks(IndexedDBDispatcherHost* dispatcher_host, 69 int32 ipc_thread_id, 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) { 84} 85 86IndexedDBCallbacks::~IndexedDBCallbacks() {} 87 88void IndexedDBCallbacks::OnError(const IndexedDBDatabaseError& error) { 89 DCHECK(dispatcher_host_.get()); 90 91 dispatcher_host_->Send(new IndexedDBMsg_CallbacksError( 92 ipc_thread_id_, ipc_callbacks_id_, error.code(), error.message())); 93 dispatcher_host_ = NULL; 94} 95 96void IndexedDBCallbacks::OnSuccess(const std::vector<base::string16>& value) { 97 DCHECK(dispatcher_host_.get()); 98 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_); 104 105 std::vector<base::string16> list; 106 for (unsigned i = 0; i < value.size(); ++i) 107 list.push_back(value[i]); 108 109 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessStringList( 110 ipc_thread_id_, ipc_callbacks_id_, list)); 111 dispatcher_host_ = NULL; 112} 113 114void IndexedDBCallbacks::OnBlocked(int64 existing_version) { 115 DCHECK(dispatcher_host_.get()); 116 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_); 122 123 if (sent_blocked_) 124 return; 125 126 sent_blocked_ = true; 127 dispatcher_host_->Send(new IndexedDBMsg_CallbacksIntBlocked( 128 ipc_thread_id_, ipc_callbacks_id_, existing_version)); 129} 130 131void 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; 136} 137 138void IndexedDBCallbacks::OnUpgradeNeeded( 139 int64 old_version, 140 scoped_ptr<IndexedDBConnection> connection, 141 const IndexedDBDatabaseMetadata& metadata) { 142 DCHECK(dispatcher_host_.get()); 143 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_); 148 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) 153 return; 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)); 165} 166 167void IndexedDBCallbacks::OnSuccess(scoped_ptr<IndexedDBConnection> connection, 168 const IndexedDBDatabaseMetadata& metadata) { 169 DCHECK(dispatcher_host_.get()); 170 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_); 175 176 scoped_refptr<IndexedDBCallbacks> self(this); 177 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_); 183 } 184 185 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessIDBDatabase( 186 ipc_thread_id_, 187 ipc_callbacks_id_, 188 ipc_database_callbacks_id_, 189 ipc_object_id, 190 IndexedDBDispatcherHost::ConvertMetadata(metadata))); 191 dispatcher_host_ = NULL; 192} 193 194static 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(); 200 if (!uuid.empty()) { 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); 205 return uuid; 206 } 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, 213 task_runner); 214 if (!blob_info.release_callback().is_null()) 215 shareable_file->AddFinalReleaseCallback(blob_info.release_callback()); 216 } 217 218 uuid = base::GenerateGUID(); 219 scoped_refptr<webkit_blob::BlobData> blob_data = 220 new webkit_blob::BlobData(uuid); 221 blob_data->AppendFile( 222 blob_info.file_path(), 0, blob_info.size(), blob_info.last_modified()); 223 scoped_ptr<webkit_blob::BlobDataHandle> blob_data_handle( 224 blob_storage_context->AddFinishedBlob(blob_data.get())); 225 dispatcher_host->HoldBlobDataHandle(uuid, blob_data_handle); 226 227 return uuid; 228} 229 230static bool CreateAllBlobs( 231 const std::vector<IndexedDBBlobInfo>& blob_info, 232 std::vector<IndexedDBMsg_BlobOrFileInfo>* blob_or_file_info, 233 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host) { 234 DCHECK_EQ(blob_info.size(), blob_or_file_info->size()); 235 size_t i; 236 if (!dispatcher_host->blob_storage_context()) 237 return false; 238 for (i = 0; i < blob_info.size(); ++i) { 239 (*blob_or_file_info)[i].uuid = 240 CreateBlobData(blob_info[i], 241 dispatcher_host, 242 dispatcher_host->blob_storage_context(), 243 dispatcher_host->Context()->TaskRunner()); 244 } 245 return true; 246} 247 248template <class ParamType, class MsgType> 249static void CreateBlobsAndSend( 250 ParamType* params, 251 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host, 252 const std::vector<IndexedDBBlobInfo>& blob_info, 253 std::vector<IndexedDBMsg_BlobOrFileInfo>* blob_or_file_info) { 254 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 255 if (CreateAllBlobs(blob_info, blob_or_file_info, dispatcher_host)) 256 dispatcher_host->Send(new MsgType(*params)); 257} 258 259static void BlobLookupForCursorPrefetch( 260 IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params* params, 261 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host, 262 const std::vector<IndexedDBValue>& values) { 263 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 264 DCHECK_EQ(values.size(), params->blob_or_file_infos.size()); 265 266 std::vector<IndexedDBValue>::const_iterator value_iter; 267 std::vector<std::vector<IndexedDBMsg_BlobOrFileInfo> >::iterator blob_iter; 268 for (value_iter = values.begin(), blob_iter = 269 params->blob_or_file_infos.begin(); value_iter != values.end(); 270 ++value_iter, ++blob_iter) { 271 if (!CreateAllBlobs(value_iter->blob_info, &*blob_iter, dispatcher_host)) 272 return; 273 } 274 dispatcher_host->Send( 275 new IndexedDBMsg_CallbacksSuccessCursorPrefetch(*params)); 276} 277 278static void FillInBlobData( 279 const std::vector<IndexedDBBlobInfo>& blob_info, 280 std::vector<IndexedDBMsg_BlobOrFileInfo>* blob_or_file_info) { 281 for (std::vector<IndexedDBBlobInfo>::const_iterator iter = blob_info.begin(); 282 iter != blob_info.end(); 283 ++iter) { 284 if (iter->is_file()) { 285 IndexedDBMsg_BlobOrFileInfo info; 286 info.is_file = true; 287 info.mime_type = iter->type(); 288 info.file_name = iter->file_name(); 289 info.file_path = iter->file_path().AsUTF16Unsafe(); 290 info.size = iter->size(); 291 info.last_modified = iter->last_modified().ToDoubleT(); 292 blob_or_file_info->push_back(info); 293 } else { 294 IndexedDBMsg_BlobOrFileInfo info; 295 info.mime_type = iter->type(); 296 info.size = iter->size(); 297 blob_or_file_info->push_back(info); 298 } 299 } 300} 301 302void IndexedDBCallbacks::RegisterBlobsAndSend( 303 const std::vector<IndexedDBBlobInfo>& blob_info, 304 const base::Closure& callback) { 305 std::vector<IndexedDBBlobInfo>::const_iterator iter; 306 for (iter = blob_info.begin(); iter != blob_info.end(); ++iter) { 307 if (!iter->mark_used_callback().is_null()) 308 iter->mark_used_callback().Run(); 309 } 310 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO)); 311 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, callback); 312} 313 314void IndexedDBCallbacks::OnSuccess(scoped_refptr<IndexedDBCursor> cursor, 315 const IndexedDBKey& key, 316 const IndexedDBKey& primary_key, 317 IndexedDBValue* value) { 318 DCHECK(dispatcher_host_.get()); 319 320 DCHECK_EQ(kNoCursor, ipc_cursor_id_); 321 DCHECK_EQ(kNoTransaction, host_transaction_id_); 322 DCHECK_EQ(kNoDatabase, ipc_database_id_); 323 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_); 324 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_); 325 326 int32 ipc_object_id = dispatcher_host_->Add(cursor.get()); 327 scoped_ptr<IndexedDBMsg_CallbacksSuccessIDBCursor_Params> params( 328 new IndexedDBMsg_CallbacksSuccessIDBCursor_Params()); 329 params->ipc_thread_id = ipc_thread_id_; 330 params->ipc_callbacks_id = ipc_callbacks_id_; 331 params->ipc_cursor_id = ipc_object_id; 332 params->key = key; 333 params->primary_key = primary_key; 334 if (value && !value->empty()) 335 std::swap(params->value, value->bits); 336 // TODO(alecflett): Avoid a copy here: the whole params object is 337 // being copied into the message. 338 if (!value || value->blob_info.empty()) { 339 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessIDBCursor(*params)); 340 } else { 341 IndexedDBMsg_CallbacksSuccessIDBCursor_Params* p = params.get(); 342 FillInBlobData(value->blob_info, &p->blob_or_file_info); 343 RegisterBlobsAndSend( 344 value->blob_info, 345 base::Bind( 346 CreateBlobsAndSend<IndexedDBMsg_CallbacksSuccessIDBCursor_Params, 347 IndexedDBMsg_CallbacksSuccessIDBCursor>, 348 base::Owned(params.release()), 349 dispatcher_host_, 350 value->blob_info, 351 base::Unretained(&p->blob_or_file_info))); 352 } 353 dispatcher_host_ = NULL; 354} 355 356void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& key, 357 const IndexedDBKey& primary_key, 358 IndexedDBValue* value) { 359 DCHECK(dispatcher_host_.get()); 360 361 DCHECK_NE(kNoCursor, ipc_cursor_id_); 362 DCHECK_EQ(kNoTransaction, host_transaction_id_); 363 DCHECK_EQ(kNoDatabase, ipc_database_id_); 364 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_); 365 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_); 366 367 IndexedDBCursor* idb_cursor = 368 dispatcher_host_->GetCursorFromId(ipc_cursor_id_); 369 370 DCHECK(idb_cursor); 371 if (!idb_cursor) 372 return; 373 374 scoped_ptr<IndexedDBMsg_CallbacksSuccessCursorContinue_Params> params( 375 new IndexedDBMsg_CallbacksSuccessCursorContinue_Params()); 376 params->ipc_thread_id = ipc_thread_id_; 377 params->ipc_callbacks_id = ipc_callbacks_id_; 378 params->ipc_cursor_id = ipc_cursor_id_; 379 params->key = key; 380 params->primary_key = primary_key; 381 if (value && !value->empty()) 382 std::swap(params->value, value->bits); 383 // TODO(alecflett): Avoid a copy here: the whole params object is 384 // being copied into the message. 385 if (!value || value->blob_info.empty()) { 386 dispatcher_host_->Send( 387 new IndexedDBMsg_CallbacksSuccessCursorContinue(*params)); 388 } else { 389 IndexedDBMsg_CallbacksSuccessCursorContinue_Params* p = params.get(); 390 FillInBlobData(value->blob_info, &p->blob_or_file_info); 391 RegisterBlobsAndSend( 392 value->blob_info, 393 base::Bind(CreateBlobsAndSend< 394 IndexedDBMsg_CallbacksSuccessCursorContinue_Params, 395 IndexedDBMsg_CallbacksSuccessCursorContinue>, 396 base::Owned(params.release()), 397 dispatcher_host_, 398 value->blob_info, 399 base::Unretained(&p->blob_or_file_info))); 400 } 401 dispatcher_host_ = NULL; 402} 403 404void IndexedDBCallbacks::OnSuccessWithPrefetch( 405 const std::vector<IndexedDBKey>& keys, 406 const std::vector<IndexedDBKey>& primary_keys, 407 std::vector<IndexedDBValue>& values) { 408 DCHECK_EQ(keys.size(), primary_keys.size()); 409 DCHECK_EQ(keys.size(), values.size()); 410 411 DCHECK(dispatcher_host_.get()); 412 413 DCHECK_NE(kNoCursor, ipc_cursor_id_); 414 DCHECK_EQ(kNoTransaction, host_transaction_id_); 415 DCHECK_EQ(kNoDatabase, ipc_database_id_); 416 DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_); 417 DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_); 418 419 std::vector<IndexedDBKey> msgKeys; 420 std::vector<IndexedDBKey> msgPrimaryKeys; 421 422 for (size_t i = 0; i < keys.size(); ++i) { 423 msgKeys.push_back(keys[i]); 424 msgPrimaryKeys.push_back(primary_keys[i]); 425 } 426 427 scoped_ptr<IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params> params( 428 new IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params()); 429 params->ipc_thread_id = ipc_thread_id_; 430 params->ipc_callbacks_id = ipc_callbacks_id_; 431 params->ipc_cursor_id = ipc_cursor_id_; 432 params->keys = msgKeys; 433 params->primary_keys = msgPrimaryKeys; 434 std::vector<std::string>& values_bits = params->values; 435 values_bits.resize(values.size()); 436 std::vector<std::vector<IndexedDBMsg_BlobOrFileInfo> >& values_blob_infos = 437 params->blob_or_file_infos; 438 values_blob_infos.resize(values.size()); 439 440 bool found_blob_info = false; 441 std::vector<IndexedDBValue>::iterator iter = values.begin(); 442 for (size_t i = 0; iter != values.end(); ++iter, ++i) { 443 values_bits[i].swap(iter->bits); 444 if (iter->blob_info.size()) { 445 found_blob_info = true; 446 FillInBlobData(iter->blob_info, &values_blob_infos[i]); 447 std::vector<IndexedDBBlobInfo>::const_iterator blob_iter; 448 for (blob_iter = iter->blob_info.begin(); 449 blob_iter != iter->blob_info.end(); 450 ++blob_iter) { 451 if (!blob_iter->mark_used_callback().is_null()) 452 blob_iter->mark_used_callback().Run(); 453 } 454 } 455 } 456 457 if (found_blob_info) { 458 BrowserThread::PostTask( 459 BrowserThread::IO, 460 FROM_HERE, 461 base::Bind(BlobLookupForCursorPrefetch, 462 base::Owned(params.release()), 463 dispatcher_host_, 464 values)); 465 } else { 466 dispatcher_host_->Send( 467 new IndexedDBMsg_CallbacksSuccessCursorPrefetch(*params.get())); 468 } 469 dispatcher_host_ = NULL; 470} 471 472void IndexedDBCallbacks::OnSuccess(IndexedDBValue* value, 473 const IndexedDBKey& key, 474 const IndexedDBKeyPath& key_path) { 475 DCHECK(dispatcher_host_.get()); 476 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_); 482 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)); 494 } else { 495 IndexedDBMsg_CallbacksSuccessValueWithKey_Params* p = params.get(); 496 FillInBlobData(value->blob_info, &p->blob_or_file_info); 497 RegisterBlobsAndSend( 498 value->blob_info, 499 base::Bind( 500 CreateBlobsAndSend<IndexedDBMsg_CallbacksSuccessValueWithKey_Params, 501 IndexedDBMsg_CallbacksSuccessValueWithKey>, 502 base::Owned(params.release()), 503 dispatcher_host_, 504 value->blob_info, 505 base::Unretained(&p->blob_or_file_info))); 506 } 507 dispatcher_host_ = NULL; 508} 509 510void 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_); 517 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)); 526 } else { 527 IndexedDBMsg_CallbacksSuccessValue_Params* p = params.get(); 528 FillInBlobData(value->blob_info, &p->blob_or_file_info); 529 RegisterBlobsAndSend( 530 value->blob_info, 531 base::Bind(CreateBlobsAndSend<IndexedDBMsg_CallbacksSuccessValue_Params, 532 IndexedDBMsg_CallbacksSuccessValue>, 533 base::Owned(params.release()), 534 dispatcher_host_, 535 value->blob_info, 536 base::Unretained(&p->blob_or_file_info))); 537 } 538 dispatcher_host_ = NULL; 539} 540 541void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& value) { 542 DCHECK(dispatcher_host_.get()); 543 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_); 549 550 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessIndexedDBKey( 551 ipc_thread_id_, ipc_callbacks_id_, value)); 552 dispatcher_host_ = NULL; 553} 554 555void IndexedDBCallbacks::OnSuccess(int64 value) { 556 DCHECK(dispatcher_host_.get()); 557 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_); 563 564 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessInteger( 565 ipc_thread_id_, ipc_callbacks_id_, value)); 566 dispatcher_host_ = NULL; 567} 568 569void IndexedDBCallbacks::OnSuccess() { 570 DCHECK(dispatcher_host_.get()); 571 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_); 577 578 dispatcher_host_->Send(new IndexedDBMsg_CallbacksSuccessUndefined( 579 ipc_thread_id_, ipc_callbacks_id_)); 580 dispatcher_host_ = NULL; 581} 582 583} // namespace content 584