| 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 |