OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/child/indexed_db/indexed_db_dispatcher.h" | 5 #include "content/child/indexed_db/indexed_db_dispatcher.h" |
6 | 6 |
7 #include "base/format_macros.h" | 7 #include "base/format_macros.h" |
8 #include "base/lazy_instance.h" | 8 #include "base/lazy_instance.h" |
9 #include "base/strings/stringprintf.h" | 9 #include "base/strings/stringprintf.h" |
10 #include "base/threading/thread_local.h" | 10 #include "base/threading/thread_local.h" |
11 #include "content/child/indexed_db/indexed_db_key_builders.h" | 11 #include "content/child/indexed_db/indexed_db_key_builders.h" |
12 #include "content/child/indexed_db/proxy_webidbcursor_impl.h" | 12 #include "content/child/indexed_db/proxy_webidbcursor_impl.h" |
13 #include "content/child/indexed_db/proxy_webidbdatabase_impl.h" | 13 #include "content/child/indexed_db/proxy_webidbdatabase_impl.h" |
14 #include "content/child/thread_safe_sender.h" | 14 #include "content/child/thread_safe_sender.h" |
15 #include "content/common/indexed_db/indexed_db_messages.h" | 15 #include "content/common/indexed_db/indexed_db_messages.h" |
16 #include "ipc/ipc_channel.h" | 16 #include "ipc/ipc_channel.h" |
17 #include "third_party/WebKit/public/platform/WebIDBDatabaseCallbacks.h" | 17 #include "third_party/WebKit/public/platform/WebIDBDatabaseCallbacks.h" |
18 #include "third_party/WebKit/public/platform/WebIDBDatabaseError.h" | 18 #include "third_party/WebKit/public/platform/WebIDBDatabaseError.h" |
19 #include "third_party/WebKit/public/platform/WebIDBDatabaseException.h" | 19 #include "third_party/WebKit/public/platform/WebIDBDatabaseException.h" |
20 | 20 |
| 21 using WebKit::WebBlobInfo; |
21 using WebKit::WebData; | 22 using WebKit::WebData; |
22 using WebKit::WebIDBCallbacks; | 23 using WebKit::WebIDBCallbacks; |
23 using WebKit::WebIDBDatabase; | 24 using WebKit::WebIDBDatabase; |
24 using WebKit::WebIDBDatabaseCallbacks; | 25 using WebKit::WebIDBDatabaseCallbacks; |
25 using WebKit::WebIDBDatabaseError; | 26 using WebKit::WebIDBDatabaseError; |
26 using WebKit::WebIDBKey; | 27 using WebKit::WebIDBKey; |
27 using WebKit::WebIDBMetadata; | 28 using WebKit::WebIDBMetadata; |
28 using WebKit::WebString; | 29 using WebKit::WebString; |
29 using WebKit::WebVector; | 30 using WebKit::WebVector; |
30 using base::ThreadLocalPointer; | 31 using base::ThreadLocalPointer; |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 params.key_range = key_range; | 317 params.key_range = key_range; |
317 params.key_only = key_only; | 318 params.key_only = key_only; |
318 Send(new IndexedDBHostMsg_DatabaseGet(params)); | 319 Send(new IndexedDBHostMsg_DatabaseGet(params)); |
319 } | 320 } |
320 | 321 |
321 void IndexedDBDispatcher::RequestIDBDatabasePut( | 322 void IndexedDBDispatcher::RequestIDBDatabasePut( |
322 int32 ipc_database_id, | 323 int32 ipc_database_id, |
323 int64 transaction_id, | 324 int64 transaction_id, |
324 int64 object_store_id, | 325 int64 object_store_id, |
325 const WebData& value, | 326 const WebData& value, |
| 327 const WebKit::WebVector<WebBlobInfo>& webBlobInfo, |
326 const IndexedDBKey& key, | 328 const IndexedDBKey& key, |
327 WebIDBDatabase::PutMode put_mode, | 329 WebIDBDatabase::PutMode put_mode, |
328 WebIDBCallbacks* callbacks, | 330 WebIDBCallbacks* callbacks, |
329 const WebVector<long long>& index_ids, | 331 const WebVector<long long>& index_ids, |
330 const WebVector<WebVector<WebIDBKey> >& index_keys) { | 332 const WebVector<WebVector<WebIDBKey> >& index_keys) { |
331 | 333 |
332 if (value.size() > kMaxIDBValueSizeInBytes) { | 334 if (value.size() > kMaxIDBValueSizeInBytes) { |
333 callbacks->onError(WebIDBDatabaseError( | 335 callbacks->onError(WebIDBDatabaseError( |
334 WebKit::WebIDBDatabaseExceptionUnknownError, | 336 WebKit::WebIDBDatabaseExceptionUnknownError, |
335 WebString::fromUTF8(base::StringPrintf( | 337 WebString::fromUTF8(base::StringPrintf( |
(...skipping 21 matching lines...) Expand all Loading... |
357 .assign(index_ids.data(), index_ids.data() + index_ids.size()); | 359 .assign(index_ids.data(), index_ids.data() + index_ids.size()); |
358 | 360 |
359 params.index_keys.resize(index_keys.size()); | 361 params.index_keys.resize(index_keys.size()); |
360 for (size_t i = 0; i < index_keys.size(); ++i) { | 362 for (size_t i = 0; i < index_keys.size(); ++i) { |
361 params.index_keys[i].resize(index_keys[i].size()); | 363 params.index_keys[i].resize(index_keys[i].size()); |
362 for (size_t j = 0; j < index_keys[i].size(); ++j) { | 364 for (size_t j = 0; j < index_keys[i].size(); ++j) { |
363 params.index_keys[i][j] = | 365 params.index_keys[i][j] = |
364 IndexedDBKey(IndexedDBKeyBuilder::Build(index_keys[i][j])); | 366 IndexedDBKey(IndexedDBKeyBuilder::Build(index_keys[i][j])); |
365 } | 367 } |
366 } | 368 } |
| 369 |
| 370 params.blob_or_file_info.resize(webBlobInfo.size()); |
| 371 for (size_t i = 0; i < webBlobInfo.size(); ++i) { |
| 372 const WebBlobInfo& info = webBlobInfo[i]; |
| 373 params.blob_or_file_info[i].is_file = info.isFile(); |
| 374 if (info.isFile()) { |
| 375 params.blob_or_file_info[i].file_path = info.filePath(); |
| 376 params.blob_or_file_info[i].file_name = info.fileName(); |
| 377 } else { |
| 378 params.blob_or_file_info[i].url = GURL(info.url()); |
| 379 params.blob_or_file_info[i].size = info.size(); |
| 380 } |
| 381 params.blob_or_file_info[i].mime_type = info.type(); |
| 382 } |
| 383 |
367 Send(new IndexedDBHostMsg_DatabasePut(params)); | 384 Send(new IndexedDBHostMsg_DatabasePut(params)); |
368 } | 385 } |
369 | 386 |
370 void IndexedDBDispatcher::RequestIDBDatabaseOpenCursor( | 387 void IndexedDBDispatcher::RequestIDBDatabaseOpenCursor( |
371 int32 ipc_database_id, | 388 int32 ipc_database_id, |
372 int64 transaction_id, | 389 int64 transaction_id, |
373 int64 object_store_id, | 390 int64 object_store_id, |
374 int64 index_id, | 391 int64 index_id, |
375 const IndexedDBKeyRange& key_range, | 392 const IndexedDBKeyRange& key_range, |
376 unsigned short direction, | 393 unsigned short direction, |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 int32 ipc_callbacks_id, | 501 int32 ipc_callbacks_id, |
485 const std::vector<string16>& value) { | 502 const std::vector<string16>& value) { |
486 DCHECK_EQ(ipc_thread_id, CurrentWorkerId()); | 503 DCHECK_EQ(ipc_thread_id, CurrentWorkerId()); |
487 WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id); | 504 WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id); |
488 if (!callbacks) | 505 if (!callbacks) |
489 return; | 506 return; |
490 callbacks->onSuccess(WebVector<WebString>(value)); | 507 callbacks->onSuccess(WebVector<WebString>(value)); |
491 pending_callbacks_.Remove(ipc_callbacks_id); | 508 pending_callbacks_.Remove(ipc_callbacks_id); |
492 } | 509 } |
493 | 510 |
494 void IndexedDBDispatcher::OnSuccessValue(int32 ipc_thread_id, | 511 static void LoadBlobInfo( |
495 int32 ipc_callbacks_id, | 512 WebData* web_value, |
496 const std::string& value) { | 513 const std::string& value, |
497 DCHECK_EQ(ipc_thread_id, CurrentWorkerId()); | 514 const std::vector<IndexedDBMsg_BlobOrFileInfo>& blob_info, |
498 WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id); | 515 WebKit::WebVector<WebBlobInfo>* web_blob_info) { |
| 516 |
| 517 if (value.size()) { |
| 518 web_value->assign(&*value.begin(), value.size()); |
| 519 WebKit::WebVector<WebBlobInfo> local_blob_info(blob_info.size()); |
| 520 for (size_t i = 0; i < blob_info.size(); ++i) { |
| 521 const IndexedDBMsg_BlobOrFileInfo& info = blob_info[i]; |
| 522 if (info.is_file) { |
| 523 local_blob_info[i] = |
| 524 WebBlobInfo(WebString::fromUTF8(info.url.spec()), |
| 525 info.file_path, info.file_name, info.mime_type, |
| 526 info.last_modified, info.size); |
| 527 } else { |
| 528 local_blob_info[i] = |
| 529 WebBlobInfo(WebString::fromUTF8(info.url.spec()), info.mime_type, |
| 530 info.size); |
| 531 } |
| 532 } |
| 533 web_blob_info->swap(local_blob_info); |
| 534 } |
| 535 } |
| 536 |
| 537 void IndexedDBDispatcher::OnSuccessValue( |
| 538 const IndexedDBMsg_CallbacksSuccessValue_Params& params) { |
| 539 DCHECK_EQ(params.ipc_thread_id, CurrentWorkerId()); |
| 540 WebIDBCallbacks* callbacks = |
| 541 pending_callbacks_.Lookup(params.ipc_callbacks_id); |
499 if (!callbacks) | 542 if (!callbacks) |
500 return; | 543 return; |
501 WebData web_value; | 544 WebData web_value; |
502 if (value.size()) | 545 WebVector<WebBlobInfo> web_blob_info; |
503 web_value.assign(&*value.begin(), value.size()); | 546 LoadBlobInfo(&web_value, params.value, params.blob_or_file_info, |
504 callbacks->onSuccess(web_value); | 547 &web_blob_info); |
505 pending_callbacks_.Remove(ipc_callbacks_id); | 548 callbacks->onSuccess(web_value, web_blob_info); |
| 549 pending_callbacks_.Remove(params.ipc_callbacks_id); |
506 } | 550 } |
507 | 551 |
508 void IndexedDBDispatcher::OnSuccessValueWithKey( | 552 void IndexedDBDispatcher::OnSuccessValueWithKey( |
509 int32 ipc_thread_id, | 553 const IndexedDBMsg_CallbacksSuccessValueWithKey_Params& params) { |
510 int32 ipc_callbacks_id, | 554 DCHECK_EQ(params.ipc_thread_id, CurrentWorkerId()); |
511 const std::string& value, | 555 WebIDBCallbacks* callbacks = |
512 const IndexedDBKey& primary_key, | 556 pending_callbacks_.Lookup(params.ipc_callbacks_id); |
513 const IndexedDBKeyPath& key_path) { | |
514 DCHECK_EQ(ipc_thread_id, CurrentWorkerId()); | |
515 WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id); | |
516 if (!callbacks) | 557 if (!callbacks) |
517 return; | 558 return; |
518 WebData web_value; | 559 WebData web_value; |
519 if (value.size()) | 560 WebVector<WebBlobInfo> web_blob_info; |
520 web_value.assign(&*value.begin(), value.size()); | 561 LoadBlobInfo(&web_value, params.value, params.blob_or_file_info, |
521 callbacks->onSuccess(web_value, | 562 &web_blob_info); |
522 WebIDBKeyBuilder::Build(primary_key), | 563 callbacks->onSuccess(web_value, web_blob_info, |
523 WebIDBKeyPathBuilder::Build(key_path)); | 564 WebIDBKeyBuilder::Build(params.primary_key), |
524 pending_callbacks_.Remove(ipc_callbacks_id); | 565 WebIDBKeyPathBuilder::Build(params.key_path)); |
| 566 pending_callbacks_.Remove(params.ipc_callbacks_id); |
525 } | 567 } |
526 | 568 |
527 void IndexedDBDispatcher::OnSuccessInteger(int32 ipc_thread_id, | 569 void IndexedDBDispatcher::OnSuccessInteger(int32 ipc_thread_id, |
528 int32 ipc_callbacks_id, | 570 int32 ipc_callbacks_id, |
529 int64 value) { | 571 int64 value) { |
530 DCHECK_EQ(ipc_thread_id, CurrentWorkerId()); | 572 DCHECK_EQ(ipc_thread_id, CurrentWorkerId()); |
531 WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id); | 573 WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id); |
532 if (!callbacks) | 574 if (!callbacks) |
533 return; | 575 return; |
534 callbacks->onSuccess(value); | 576 callbacks->onSuccess(value); |
(...skipping 11 matching lines...) Expand all Loading... |
546 } | 588 } |
547 | 589 |
548 void IndexedDBDispatcher::OnSuccessOpenCursor( | 590 void IndexedDBDispatcher::OnSuccessOpenCursor( |
549 const IndexedDBMsg_CallbacksSuccessIDBCursor_Params& p) { | 591 const IndexedDBMsg_CallbacksSuccessIDBCursor_Params& p) { |
550 DCHECK_EQ(p.ipc_thread_id, CurrentWorkerId()); | 592 DCHECK_EQ(p.ipc_thread_id, CurrentWorkerId()); |
551 int32 ipc_callbacks_id = p.ipc_callbacks_id; | 593 int32 ipc_callbacks_id = p.ipc_callbacks_id; |
552 int32 ipc_object_id = p.ipc_cursor_id; | 594 int32 ipc_object_id = p.ipc_cursor_id; |
553 const IndexedDBKey& key = p.key; | 595 const IndexedDBKey& key = p.key; |
554 const IndexedDBKey& primary_key = p.primary_key; | 596 const IndexedDBKey& primary_key = p.primary_key; |
555 WebData web_value; | 597 WebData web_value; |
556 if (p.value.size()) | 598 WebVector<WebBlobInfo> web_blob_info; |
557 web_value.assign(&*p.value.begin(), p.value.size()); | 599 LoadBlobInfo(&web_value, p.value, p.blob_or_file_info, |
| 600 &web_blob_info); |
558 | 601 |
559 WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id); | 602 WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id); |
560 if (!callbacks) | 603 if (!callbacks) |
561 return; | 604 return; |
562 | 605 |
563 RendererWebIDBCursorImpl* cursor = | 606 RendererWebIDBCursorImpl* cursor = |
564 new RendererWebIDBCursorImpl(ipc_object_id, thread_safe_sender_.get()); | 607 new RendererWebIDBCursorImpl(ipc_object_id, thread_safe_sender_.get()); |
565 cursors_[ipc_object_id] = cursor; | 608 cursors_[ipc_object_id] = cursor; |
566 callbacks->onSuccess(cursor, WebIDBKeyBuilder::Build(key), | 609 callbacks->onSuccess(cursor, WebIDBKeyBuilder::Build(key), |
567 WebIDBKeyBuilder::Build(primary_key), web_value); | 610 WebIDBKeyBuilder::Build(primary_key), web_value, |
| 611 web_blob_info); |
568 | 612 |
569 pending_callbacks_.Remove(ipc_callbacks_id); | 613 pending_callbacks_.Remove(ipc_callbacks_id); |
570 } | 614 } |
571 | 615 |
572 void IndexedDBDispatcher::OnSuccessCursorContinue( | 616 void IndexedDBDispatcher::OnSuccessCursorContinue( |
573 const IndexedDBMsg_CallbacksSuccessCursorContinue_Params& p) { | 617 const IndexedDBMsg_CallbacksSuccessCursorContinue_Params& p) { |
574 DCHECK_EQ(p.ipc_thread_id, CurrentWorkerId()); | 618 DCHECK_EQ(p.ipc_thread_id, CurrentWorkerId()); |
575 int32 ipc_callbacks_id = p.ipc_callbacks_id; | 619 int32 ipc_callbacks_id = p.ipc_callbacks_id; |
576 int32 ipc_cursor_id = p.ipc_cursor_id; | 620 int32 ipc_cursor_id = p.ipc_cursor_id; |
577 const IndexedDBKey& key = p.key; | 621 const IndexedDBKey& key = p.key; |
578 const IndexedDBKey& primary_key = p.primary_key; | 622 const IndexedDBKey& primary_key = p.primary_key; |
579 const std::string& value = p.value; | 623 const std::string& value = p.value; |
580 | 624 |
581 RendererWebIDBCursorImpl* cursor = cursors_[ipc_cursor_id]; | 625 RendererWebIDBCursorImpl* cursor = cursors_[ipc_cursor_id]; |
582 DCHECK(cursor); | 626 DCHECK(cursor); |
583 | 627 |
584 WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id); | 628 WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id); |
585 if (!callbacks) | 629 if (!callbacks) |
586 return; | 630 return; |
587 | 631 |
588 WebData web_value; | 632 WebData web_value; |
589 if (value.size()) | 633 WebVector<WebBlobInfo> web_blob_info; |
590 web_value.assign(&*value.begin(), value.size()); | 634 LoadBlobInfo(&web_value, value, p.blob_or_file_info, &web_blob_info); |
591 callbacks->onSuccess(WebIDBKeyBuilder::Build(key), | 635 callbacks->onSuccess(WebIDBKeyBuilder::Build(key), |
592 WebIDBKeyBuilder::Build(primary_key), web_value); | 636 WebIDBKeyBuilder::Build(primary_key), web_value, |
| 637 web_blob_info); |
593 | 638 |
594 pending_callbacks_.Remove(ipc_callbacks_id); | 639 pending_callbacks_.Remove(ipc_callbacks_id); |
595 } | 640 } |
596 | 641 |
597 void IndexedDBDispatcher::OnSuccessCursorPrefetch( | 642 void IndexedDBDispatcher::OnSuccessCursorPrefetch( |
598 const IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params& p) { | 643 const IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params& p) { |
599 DCHECK_EQ(p.ipc_thread_id, CurrentWorkerId()); | 644 DCHECK_EQ(p.ipc_thread_id, CurrentWorkerId()); |
600 int32 ipc_callbacks_id = p.ipc_callbacks_id; | 645 int32 ipc_callbacks_id = p.ipc_callbacks_id; |
601 int32 ipc_cursor_id = p.ipc_cursor_id; | 646 int32 ipc_cursor_id = p.ipc_cursor_id; |
602 const std::vector<IndexedDBKey>& keys = p.keys; | 647 const std::vector<IndexedDBKey>& keys = p.keys; |
603 const std::vector<IndexedDBKey>& primary_keys = p.primary_keys; | 648 const std::vector<IndexedDBKey>& primary_keys = p.primary_keys; |
604 std::vector<WebData> values(p.values.size()); | 649 std::vector<WebData> values(p.values.size()); |
| 650 DCHECK_EQ(p.values.size(), p.blob_or_file_infos.size()); |
| 651 std::vector<WebVector<WebBlobInfo> > blob_infos(p.blob_or_file_infos.size()); |
605 for (size_t i = 0; i < p.values.size(); ++i) { | 652 for (size_t i = 0; i < p.values.size(); ++i) { |
606 if (p.values[i].size()) | 653 LoadBlobInfo(&values[i], p.values[i], p.blob_or_file_infos[i], |
607 values[i].assign(&*p.values[i].begin(), p.values[i].size()); | 654 &blob_infos[i]); |
608 } | 655 } |
609 RendererWebIDBCursorImpl* cursor = cursors_[ipc_cursor_id]; | 656 RendererWebIDBCursorImpl* cursor = cursors_[ipc_cursor_id]; |
610 DCHECK(cursor); | 657 DCHECK(cursor); |
611 cursor->SetPrefetchData(keys, primary_keys, values); | 658 cursor->SetPrefetchData(keys, primary_keys, values, blob_infos); |
612 | 659 |
613 WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id); | 660 WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id); |
614 DCHECK(callbacks); | 661 DCHECK(callbacks); |
615 cursor->CachedContinue(callbacks); | 662 cursor->CachedContinue(callbacks); |
616 pending_callbacks_.Remove(ipc_callbacks_id); | 663 pending_callbacks_.Remove(ipc_callbacks_id); |
617 } | 664 } |
618 | 665 |
619 void IndexedDBDispatcher::OnIntBlocked(int32 ipc_thread_id, | 666 void IndexedDBDispatcher::OnIntBlocked(int32 ipc_thread_id, |
620 int32 ipc_callbacks_id, | 667 int32 ipc_callbacks_id, |
621 int64 existing_version) { | 668 int64 existing_version) { |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
713 int32 ipc_exception_cursor_id) { | 760 int32 ipc_exception_cursor_id) { |
714 typedef std::map<int32, RendererWebIDBCursorImpl*>::iterator Iterator; | 761 typedef std::map<int32, RendererWebIDBCursorImpl*>::iterator Iterator; |
715 for (Iterator i = cursors_.begin(); i != cursors_.end(); ++i) { | 762 for (Iterator i = cursors_.begin(); i != cursors_.end(); ++i) { |
716 if (i->first == ipc_exception_cursor_id) | 763 if (i->first == ipc_exception_cursor_id) |
717 continue; | 764 continue; |
718 i->second->ResetPrefetchCache(); | 765 i->second->ResetPrefetchCache(); |
719 } | 766 } |
720 } | 767 } |
721 | 768 |
722 } // namespace content | 769 } // namespace content |
OLD | NEW |