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