Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(66)

Side by Side Diff: content/browser/download/download_manager.cc

Issue 7646025: Detect file system errors during downloads. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed comment. Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "base/callback.h" 7 #include "base/callback.h"
8 #include "base/file_util.h" 8 #include "base/file_util.h"
9 #include "base/i18n/case_conversion.h" 9 #include "base/i18n/case_conversion.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 if (download->IsInProgress()) { 383 if (download->IsInProgress()) {
384 download->Update(size); 384 download->Update(size);
385 UpdateDownloadProgress(); // Reflect size updates. 385 UpdateDownloadProgress(); // Reflect size updates.
386 download_history_->UpdateEntry(download); 386 download_history_->UpdateEntry(download);
387 } 387 }
388 } 388 }
389 } 389 }
390 390
391 void DownloadManager::OnResponseCompleted(int32 download_id, 391 void DownloadManager::OnResponseCompleted(int32 download_id,
392 int64 size, 392 int64 size,
393 int os_error,
394 const std::string& hash) { 393 const std::string& hash) {
395 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
396 // ERR_CONNECTION_CLOSED is allowed since a number of servers in the wild
397 // advertise a larger Content-Length than the amount of bytes in the message
398 // body, and then close the connection. Other browsers - IE8, Firefox 4.0.1,
399 // and Safari 5.0.4 - treat the download as complete in this case, so we
400 // follow their lead.
401 if (os_error == 0 || os_error == net::ERR_CONNECTION_CLOSED) {
402 OnAllDataSaved(download_id, size, hash);
403 } else {
404 OnDownloadError(download_id, size, os_error);
405 }
406 }
407
408 void DownloadManager::OnAllDataSaved(int32 download_id,
409 int64 size,
410 const std::string& hash) {
411 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id 394 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id
412 << " size = " << size; 395 << " size = " << size;
413 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 396 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
414 397
415 // If it's not in active_downloads_, that means it was cancelled; just 398 // If it's not in active_downloads_, that means it was cancelled; just
416 // ignore the notification. 399 // ignore the notification.
417 if (active_downloads_.count(download_id) == 0) 400 if (active_downloads_.count(download_id) == 0)
418 return; 401 return;
419 402
420 DownloadItem* download = active_downloads_[download_id]; 403 DownloadItem* download = active_downloads_[download_id];
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 file_manager_, &DownloadFileManager::CompleteDownload, download_id)); 525 file_manager_, &DownloadFileManager::CompleteDownload, download_id));
543 526
544 if (uniquifier) 527 if (uniquifier)
545 item->set_path_uniquifier(uniquifier); 528 item->set_path_uniquifier(uniquifier);
546 529
547 item->OnDownloadRenamedToFinalName(full_path); 530 item->OnDownloadRenamedToFinalName(full_path);
548 download_history_->UpdateDownloadPath(item, full_path); 531 download_history_->UpdateDownloadPath(item, full_path);
549 } 532 }
550 533
551 void DownloadManager::DownloadCancelled(int32 download_id) { 534 void DownloadManager::DownloadCancelled(int32 download_id) {
552 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 535 DownloadItem* download = GetActiveDownload(download_id);
553 DownloadMap::iterator it = in_progress_.find(download_id); 536
554 if (it == in_progress_.end()) 537 // A cancel at the right time could remove the download from the
538 // |active_downloads_| map before we get here.
539 if (!download)
555 return; 540 return;
556 DownloadItem* download = it->second;
557 541
558 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id 542 VLOG(20) << __FUNCTION__ << "()"
559 << " download = " << download->DebugString(true); 543 << " download = " << download->DebugString(true);
560 544
561 // Clean up will happen when the history system create callback runs if we 545 RemoveFromActiveList(download);
562 // don't have a valid db_handle yet.
563 if (download->db_handle() != DownloadHistory::kUninitializedHandle) {
564 in_progress_.erase(it);
565 active_downloads_.erase(download_id);
566 UpdateDownloadProgress(); // Reflect removal from in_progress_.
567 download_history_->UpdateEntry(download);
568 }
569 546
570 DownloadCancelledInternal(download_id, download->request_handle()); 547 DownloadCancelledInternal(download_id, download->request_handle());
571 } 548 }
572 549
550 void DownloadManager::OnDownloadError(int32 download_id,
551 int64 size,
552 int error) {
553 DownloadItem* download = GetActiveDownload(download_id);
554 if (!download)
555 return;
556
557 VLOG(20) << __FUNCTION__ << "()" << " Error " << error
558 << " at offset " << download->received_bytes()
559 << " size = " << size
560 << " download = " << download->DebugString(true);
561
562 RemoveFromActiveList(download);
563 download->Interrupted(size, error);
564 DownloadCancelledInternal(download_id, download->request_handle());
565 }
566
573 void DownloadManager::DownloadCancelledInternal( 567 void DownloadManager::DownloadCancelledInternal(
574 int download_id, const DownloadRequestHandle& request_handle) { 568 int download_id, const DownloadRequestHandle& request_handle) {
575 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 569 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
576 request_handle.CancelRequest(); 570 request_handle.CancelRequest();
577 571
578 BrowserThread::PostTask( 572 BrowserThread::PostTask(
579 BrowserThread::FILE, FROM_HERE, 573 BrowserThread::FILE, FROM_HERE,
580 NewRunnableMethod( 574 NewRunnableMethod(
581 file_manager_, &DownloadFileManager::CancelDownload, download_id)); 575 file_manager_, &DownloadFileManager::CancelDownload, download_id));
582 } 576 }
583 577
584 void DownloadManager::OnDownloadError(int32 download_id, 578 DownloadItem* DownloadManager::GetActiveDownload(int32 download_id) {
585 int64 size,
586 int os_error) {
587 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 579 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
588 DownloadMap::iterator it = active_downloads_.find(download_id); 580 DownloadMap::iterator it = active_downloads_.find(download_id);
589 // A cancel at the right time could remove the download from the
590 // |active_downloads_| map before we get here.
591 if (it == active_downloads_.end()) 581 if (it == active_downloads_.end())
592 return; 582 return NULL;
593 583
594 DownloadItem* download = it->second; 584 DownloadItem* download = it->second;
595 585
596 VLOG(20) << __FUNCTION__ << "()" << " Error " << os_error 586 DCHECK(download);
597 << " at offset " << download->received_bytes() 587 DCHECK_EQ(download_id, download->id());
598 << " for download = " << download->DebugString(true);
599 588
600 download->Interrupted(size, os_error); 589 return download;
590 }
601 591
602 // TODO(ahendrickson) - Remove this when we add resuming of interrupted 592 void DownloadManager::RemoveFromActiveList(DownloadItem* download) {
603 // downloads, as we will keep the download item around in that case. 593 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
604 // 594 DCHECK(download);
595
605 // Clean up will happen when the history system create callback runs if we 596 // Clean up will happen when the history system create callback runs if we
606 // don't have a valid db_handle yet. 597 // don't have a valid db_handle yet.
607 if (download->db_handle() != DownloadHistory::kUninitializedHandle) { 598 if (download->db_handle() != DownloadHistory::kUninitializedHandle) {
608 in_progress_.erase(download_id); 599 in_progress_.erase(download->id());
609 active_downloads_.erase(download_id); 600 active_downloads_.erase(download->id());
610 UpdateDownloadProgress(); // Reflect removal from in_progress_. 601 UpdateDownloadProgress(); // Reflect removal from in_progress_.
611 download_history_->UpdateEntry(download); 602 download_history_->UpdateEntry(download);
612 } 603 }
613
614 BrowserThread::PostTask(
615 BrowserThread::FILE, FROM_HERE,
616 NewRunnableMethod(
617 file_manager_, &DownloadFileManager::CancelDownload, download_id));
618 } 604 }
619 605
620 void DownloadManager::UpdateDownloadProgress() { 606 void DownloadManager::UpdateDownloadProgress() {
621 delegate_->DownloadProgressUpdated(); 607 delegate_->DownloadProgressUpdated();
622 } 608 }
623 609
624 int DownloadManager::RemoveDownloadItems( 610 int DownloadManager::RemoveDownloadItems(
625 const DownloadVector& pending_deletes) { 611 const DownloadVector& pending_deletes) {
626 if (pending_deletes.empty()) 612 if (pending_deletes.empty())
627 return 0; 613 return 0;
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
800 int32 download_id = *id_ptr; 786 int32 download_id = *id_ptr;
801 delete id_ptr; 787 delete id_ptr;
802 788
803 DownloadItem* download = GetActiveDownloadItem(download_id); 789 DownloadItem* download = GetActiveDownloadItem(download_id);
804 if (!download) 790 if (!download)
805 return; 791 return;
806 792
807 VLOG(20) << __FUNCTION__ << "()" 793 VLOG(20) << __FUNCTION__ << "()"
808 << " download = " << download->DebugString(true); 794 << " download = " << download->DebugString(true);
809 795
796 // TODO(ahendrickson) -- This currently has no effect, as the download is
797 // not put on the active list until the file selection is complete. Need
798 // to put it on the active list earlier in the process.
799 RemoveFromActiveList(download);
800
810 DownloadCancelledInternal(download_id, download->request_handle()); 801 DownloadCancelledInternal(download_id, download->request_handle());
811 } 802 }
812 803
813 // Operations posted to us from the history service ---------------------------- 804 // Operations posted to us from the history service ----------------------------
814 805
815 // The history service has retrieved all download entries. 'entries' contains 806 // The history service has retrieved all download entries. 'entries' contains
816 // 'DownloadHistoryInfo's in sorted order (by ascending start_time). 807 // 'DownloadHistoryInfo's in sorted order (by ascending start_time).
817 void DownloadManager::OnQueryDownloadEntriesComplete( 808 void DownloadManager::OnQueryDownloadEntriesComplete(
818 std::vector<DownloadHistoryInfo>* entries) { 809 std::vector<DownloadHistoryInfo>* entries) {
819 for (size_t i = 0; i < entries->size(); ++i) { 810 for (size_t i = 0; i < entries->size(); ++i) {
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
1070 Source<DownloadManager>(this), 1061 Source<DownloadManager>(this),
1071 Details<DownloadItem>(download)); 1062 Details<DownloadItem>(download));
1072 } 1063 }
1073 } 1064 }
1074 1065
1075 int32 DownloadManager::GetNextSavePageId() { 1066 int32 DownloadManager::GetNextSavePageId() {
1076 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1067 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1077 return next_save_page_id_++; 1068 return next_save_page_id_++;
1078 } 1069 }
1079 1070
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698