OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/browser/download/download_manager.h" | 5 #include "content/browser/download/download_manager.h" |
6 | 6 |
7 #include <iterator> | 7 #include <iterator> |
8 | 8 |
9 #include "base/callback.h" | 9 #include "base/callback.h" |
10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 if (download->IsInProgress()) { | 343 if (download->IsInProgress()) { |
344 download->Update(size); | 344 download->Update(size); |
345 UpdateDownloadProgress(); // Reflect size updates. | 345 UpdateDownloadProgress(); // Reflect size updates. |
346 delegate_->UpdateItemInPersistentStore(download); | 346 delegate_->UpdateItemInPersistentStore(download); |
347 } | 347 } |
348 } | 348 } |
349 } | 349 } |
350 | 350 |
351 void DownloadManager::OnResponseCompleted(int32 download_id, | 351 void DownloadManager::OnResponseCompleted(int32 download_id, |
352 int64 size, | 352 int64 size, |
353 int os_error, | |
354 const std::string& hash) { | 353 const std::string& hash) { |
355 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
356 // ERR_CONNECTION_CLOSED is allowed since a number of servers in the wild | |
357 // advertise a larger Content-Length than the amount of bytes in the message | |
358 // body, and then close the connection. Other browsers - IE8, Firefox 4.0.1, | |
359 // and Safari 5.0.4 - treat the download as complete in this case, so we | |
360 // follow their lead. | |
361 if (os_error == 0 || os_error == net::ERR_CONNECTION_CLOSED) { | |
362 OnAllDataSaved(download_id, size, hash); | |
363 } else { | |
364 OnDownloadError(download_id, size, os_error); | |
365 } | |
366 } | |
367 | |
368 void DownloadManager::OnAllDataSaved(int32 download_id, | |
369 int64 size, | |
370 const std::string& hash) { | |
371 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id | 354 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id |
372 << " size = " << size; | 355 << " size = " << size; |
373 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 356 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
374 | 357 |
375 // If it's not in active_downloads_, that means it was cancelled; just | 358 // If it's not in active_downloads_, that means it was cancelled; just |
376 // ignore the notification. | 359 // ignore the notification. |
377 if (active_downloads_.count(download_id) == 0) | 360 if (active_downloads_.count(download_id) == 0) |
378 return; | 361 return; |
379 | 362 |
380 DownloadItem* download = active_downloads_[download_id]; | 363 DownloadItem* download = active_downloads_[download_id]; |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
503 file_manager_, &DownloadFileManager::CompleteDownload, download_id)); | 486 file_manager_, &DownloadFileManager::CompleteDownload, download_id)); |
504 | 487 |
505 if (uniquifier) | 488 if (uniquifier) |
506 item->set_path_uniquifier(uniquifier); | 489 item->set_path_uniquifier(uniquifier); |
507 | 490 |
508 item->OnDownloadRenamedToFinalName(full_path); | 491 item->OnDownloadRenamedToFinalName(full_path); |
509 delegate_->UpdatePathForItemInPersistentStore(item, full_path); | 492 delegate_->UpdatePathForItemInPersistentStore(item, full_path); |
510 } | 493 } |
511 | 494 |
512 void DownloadManager::CancelDownload(int32 download_id) { | 495 void DownloadManager::CancelDownload(int32 download_id) { |
513 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 496 DownloadItem* download = GetActiveDownload(download_id); |
514 DownloadItem* download = GetDownloadItem(download_id); | 497 // A cancel at the right time could remove the download from the |
| 498 // |active_downloads_| map before we get here. |
515 if (!download) | 499 if (!download) |
516 return; | 500 return; |
517 | 501 |
518 download->Cancel(true); | 502 download->Cancel(true); |
519 } | 503 } |
520 | 504 |
521 void DownloadManager::DownloadCancelledInternal(DownloadItem* download) { | 505 void DownloadManager::DownloadCancelledInternal(DownloadItem* download) { |
522 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 506 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
523 int download_id = download->id(); | |
524 | 507 |
525 VLOG(20) << __FUNCTION__ << "()" | 508 VLOG(20) << __FUNCTION__ << "()" |
526 << " download = " << download->DebugString(true); | 509 << " download = " << download->DebugString(true); |
527 | 510 |
528 // Clean up will happen when the history system create callback runs if we | 511 RemoveFromActiveList(download); |
529 // don't have a valid db_handle yet. | 512 // This function is called from the DownloadItem, so DI state |
530 if (download->db_handle() != DownloadItem::kUninitializedHandle) { | 513 // should already have been updated. |
531 in_progress_.erase(download_id); | 514 AssertQueueStateConsistent(download); |
532 active_downloads_.erase(download_id); | |
533 UpdateDownloadProgress(); // Reflect removal from in_progress_. | |
534 delegate_->UpdateItemInPersistentStore(download); | |
535 | |
536 // This function is called from the DownloadItem, so DI state | |
537 // should already have been updated. | |
538 AssertQueueStateConsistent(download); | |
539 } | |
540 | 515 |
541 download->OffThreadCancel(file_manager_); | 516 download->OffThreadCancel(file_manager_); |
542 } | 517 } |
543 | 518 |
544 void DownloadManager::OnDownloadError(int32 download_id, | 519 void DownloadManager::OnDownloadError(int32 download_id, |
545 int64 size, | 520 int64 size, |
546 int os_error) { | 521 int error) { |
| 522 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 523 |
| 524 DownloadItem* download = GetActiveDownload(download_id); |
| 525 if (!download) |
| 526 return; |
| 527 |
| 528 VLOG(20) << __FUNCTION__ << "()" << " Error " << error |
| 529 << " at offset " << download->received_bytes() |
| 530 << " size = " << size |
| 531 << " download = " << download->DebugString(true); |
| 532 |
| 533 RemoveFromActiveList(download); |
| 534 download->Interrupted(size, error); |
| 535 download->OffThreadCancel(file_manager_); |
| 536 } |
| 537 |
| 538 DownloadItem* DownloadManager::GetActiveDownload(int32 download_id) { |
547 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 539 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
548 DownloadMap::iterator it = active_downloads_.find(download_id); | 540 DownloadMap::iterator it = active_downloads_.find(download_id); |
549 // A cancel at the right time could remove the download from the | |
550 // |active_downloads_| map before we get here. | |
551 if (it == active_downloads_.end()) | 541 if (it == active_downloads_.end()) |
552 return; | 542 return NULL; |
553 | 543 |
554 DownloadItem* download = it->second; | 544 DownloadItem* download = it->second; |
555 | 545 |
556 VLOG(20) << __FUNCTION__ << "()" << " Error " << os_error | 546 DCHECK(download); |
557 << " at offset " << download->received_bytes() | 547 DCHECK_EQ(download_id, download->id()); |
558 << " for download = " << download->DebugString(true); | |
559 | 548 |
560 download->Interrupted(size, os_error); | 549 return download; |
| 550 } |
561 | 551 |
562 // TODO(ahendrickson) - Remove this when we add resuming of interrupted | 552 void DownloadManager::RemoveFromActiveList(DownloadItem* download) { |
563 // downloads, as we will keep the download item around in that case. | 553 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
564 // | 554 DCHECK(download); |
| 555 |
565 // Clean up will happen when the history system create callback runs if we | 556 // Clean up will happen when the history system create callback runs if we |
566 // don't have a valid db_handle yet. | 557 // don't have a valid db_handle yet. |
567 if (download->db_handle() != DownloadItem::kUninitializedHandle) { | 558 if (download->db_handle() != DownloadItem::kUninitializedHandle) { |
568 in_progress_.erase(download_id); | 559 in_progress_.erase(download->id()); |
569 active_downloads_.erase(download_id); | 560 active_downloads_.erase(download->id()); |
570 UpdateDownloadProgress(); // Reflect removal from in_progress_. | 561 UpdateDownloadProgress(); // Reflect removal from in_progress_. |
571 delegate_->UpdateItemInPersistentStore(download); | 562 delegate_->UpdateItemInPersistentStore(download); |
572 } | 563 } |
573 | |
574 BrowserThread::PostTask( | |
575 BrowserThread::FILE, FROM_HERE, | |
576 NewRunnableMethod( | |
577 file_manager_, &DownloadFileManager::CancelDownload, download_id)); | |
578 } | 564 } |
579 | 565 |
580 void DownloadManager::UpdateDownloadProgress() { | 566 void DownloadManager::UpdateDownloadProgress() { |
581 delegate_->DownloadProgressUpdated(); | 567 delegate_->DownloadProgressUpdated(); |
582 } | 568 } |
583 | 569 |
584 int DownloadManager::RemoveDownloadItems( | 570 int DownloadManager::RemoveDownloadItems( |
585 const DownloadVector& pending_deletes) { | 571 const DownloadVector& pending_deletes) { |
586 if (pending_deletes.empty()) | 572 if (pending_deletes.empty()) |
587 return 0; | 573 return 0; |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
756 int32 download_id = *id_ptr; | 742 int32 download_id = *id_ptr; |
757 delete id_ptr; | 743 delete id_ptr; |
758 | 744 |
759 DownloadItem* download = GetActiveDownloadItem(download_id); | 745 DownloadItem* download = GetActiveDownloadItem(download_id); |
760 if (!download) | 746 if (!download) |
761 return; | 747 return; |
762 | 748 |
763 VLOG(20) << __FUNCTION__ << "()" | 749 VLOG(20) << __FUNCTION__ << "()" |
764 << " download = " << download->DebugString(true); | 750 << " download = " << download->DebugString(true); |
765 | 751 |
| 752 // TODO(ahendrickson) -- This currently has no effect, as the download is |
| 753 // not put on the active list until the file selection is complete. Need |
| 754 // to put it on the active list earlier in the process. |
| 755 RemoveFromActiveList(download); |
| 756 |
766 download->OffThreadCancel(file_manager_); | 757 download->OffThreadCancel(file_manager_); |
767 } | 758 } |
768 | 759 |
769 // Operations posted to us from the history service ---------------------------- | 760 // Operations posted to us from the history service ---------------------------- |
770 | 761 |
771 // The history service has retrieved all download entries. 'entries' contains | 762 // The history service has retrieved all download entries. 'entries' contains |
772 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time). | 763 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time). |
773 void DownloadManager::OnPersistentStoreQueryComplete( | 764 void DownloadManager::OnPersistentStoreQueryComplete( |
774 std::vector<DownloadPersistentStoreInfo>* entries) { | 765 std::vector<DownloadPersistentStoreInfo>* entries) { |
775 // TODO(rdsmith): Remove this and related logic when | 766 // TODO(rdsmith): Remove this and related logic when |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1015 DCHECK(ContainsKey(save_page_downloads_, download->id())); | 1006 DCHECK(ContainsKey(save_page_downloads_, download->id())); |
1016 save_page_downloads_.erase(download->id()); | 1007 save_page_downloads_.erase(download->id()); |
1017 | 1008 |
1018 if (download->IsComplete()) | 1009 if (download->IsComplete()) |
1019 NotificationService::current()->Notify( | 1010 NotificationService::current()->Notify( |
1020 content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED, | 1011 content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED, |
1021 Source<DownloadManager>(this), | 1012 Source<DownloadManager>(this), |
1022 Details<DownloadItem>(download)); | 1013 Details<DownloadItem>(download)); |
1023 } | 1014 } |
1024 } | 1015 } |
OLD | NEW |