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

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: Merged with trunk. 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 RemoveFromActiveList(download);
559 << " download = " << download->DebugString(true);
560
561 // Clean up will happen when the history system create callback runs if we
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 543
570 DownloadCancelledInternal(download_id, download->request_handle()); 544 DownloadCancelledInternal(download_id, download->request_handle());
571 } 545 }
572 546
547 void DownloadManager::OnDownloadError(int32 download_id,
548 int64 size,
549 int error) {
550 DownloadItem* download = GetActiveDownload(download_id);
551 if (!download)
552 return;
553
554 VLOG(20) << __FUNCTION__ << "()" << " Error " << error
555 << " at offset " << download->received_bytes()
556 << " size = " << size;
557
558 RemoveFromActiveList(download);
559 download->Interrupted(size, error);
560 DownloadCancelledInternal(download_id, download->request_handle());
561 }
562
573 void DownloadManager::DownloadCancelledInternal( 563 void DownloadManager::DownloadCancelledInternal(
574 int download_id, const DownloadRequestHandle& request_handle) { 564 int download_id, const DownloadRequestHandle& request_handle) {
575 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 565 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
576 request_handle.CancelRequest(); 566 request_handle.CancelRequest();
577 567
578 BrowserThread::PostTask( 568 BrowserThread::PostTask(
579 BrowserThread::FILE, FROM_HERE, 569 BrowserThread::FILE, FROM_HERE,
580 NewRunnableMethod( 570 NewRunnableMethod(
581 file_manager_, &DownloadFileManager::CancelDownload, download_id)); 571 file_manager_, &DownloadFileManager::CancelDownload, download_id));
582 } 572 }
583 573
584 void DownloadManager::OnDownloadError(int32 download_id, 574 DownloadItem* DownloadManager::GetActiveDownload(int32 download_id) {
585 int64 size,
586 int os_error) {
587 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 575 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
588 DownloadMap::iterator it = active_downloads_.find(download_id); 576 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()) 577 if (it == active_downloads_.end())
592 return; 578 return NULL;
593 579
594 DownloadItem* download = it->second; 580 DownloadItem* download = it->second;
595 581
596 VLOG(20) << __FUNCTION__ << "()" << " Error " << os_error 582 DCHECK(download);
597 << " at offset " << download->received_bytes() 583 DCHECK_EQ(download_id, download->id());
598 << " for download = " << download->DebugString(true);
599 584
600 download->Interrupted(size, os_error); 585 VLOG(20) << __FUNCTION__ << "()"
586 << " download = " << download->DebugString(true);
Randy Smith (Not in Mondays) 2011/08/19 20:09:13 It's up to you, but logging inside of "GetActiveDo
ahendrickson 2011/08/22 14:53:30 Done.
601 587
602 // TODO(ahendrickson) - Remove this when we add resuming of interrupted 588 return download;
603 // downloads, as we will keep the download item around in that case. 589 }
604 // 590
591 void DownloadManager::RemoveFromActiveList(DownloadItem* download) {
592 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
593 DCHECK(download);
594
605 // Clean up will happen when the history system create callback runs if we 595 // Clean up will happen when the history system create callback runs if we
606 // don't have a valid db_handle yet. 596 // don't have a valid db_handle yet.
607 if (download->db_handle() != DownloadHistory::kUninitializedHandle) { 597 if (download->db_handle() != DownloadHistory::kUninitializedHandle) {
608 in_progress_.erase(download_id); 598 in_progress_.erase(download->id());
609 active_downloads_.erase(download_id); 599 active_downloads_.erase(download->id());
610 UpdateDownloadProgress(); // Reflect removal from in_progress_. 600 UpdateDownloadProgress(); // Reflect removal from in_progress_.
611 download_history_->UpdateEntry(download); 601 download_history_->UpdateEntry(download);
612 } 602 }
613
614 BrowserThread::PostTask(
615 BrowserThread::FILE, FROM_HERE,
616 NewRunnableMethod(
617 file_manager_, &DownloadFileManager::CancelDownload, download_id));
618 } 603 }
619 604
620 void DownloadManager::UpdateDownloadProgress() { 605 void DownloadManager::UpdateDownloadProgress() {
621 delegate_->DownloadProgressUpdated(); 606 delegate_->DownloadProgressUpdated();
622 } 607 }
623 608
624 int DownloadManager::RemoveDownloadItems( 609 int DownloadManager::RemoveDownloadItems(
625 const DownloadVector& pending_deletes) { 610 const DownloadVector& pending_deletes) {
626 if (pending_deletes.empty()) 611 if (pending_deletes.empty())
627 return 0; 612 return 0;
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
800 int32 download_id = *id_ptr; 785 int32 download_id = *id_ptr;
801 delete id_ptr; 786 delete id_ptr;
802 787
803 DownloadItem* download = GetActiveDownloadItem(download_id); 788 DownloadItem* download = GetActiveDownloadItem(download_id);
804 if (!download) 789 if (!download)
805 return; 790 return;
806 791
807 VLOG(20) << __FUNCTION__ << "()" 792 VLOG(20) << __FUNCTION__ << "()"
808 << " download = " << download->DebugString(true); 793 << " download = " << download->DebugString(true);
809 794
795 // TODO(ahendrickson) -- This currently has no effect.
Randy Smith (Not in Mondays) 2011/08/19 20:09:13 Could you enhance this comment to answer the quest
ahendrickson 2011/08/22 14:53:30 Done.
796 RemoveFromActiveList(download);
797
810 DownloadCancelledInternal(download_id, download->request_handle()); 798 DownloadCancelledInternal(download_id, download->request_handle());
811 } 799 }
812 800
813 // Operations posted to us from the history service ---------------------------- 801 // Operations posted to us from the history service ----------------------------
814 802
815 // The history service has retrieved all download entries. 'entries' contains 803 // The history service has retrieved all download entries. 'entries' contains
816 // 'DownloadHistoryInfo's in sorted order (by ascending start_time). 804 // 'DownloadHistoryInfo's in sorted order (by ascending start_time).
817 void DownloadManager::OnQueryDownloadEntriesComplete( 805 void DownloadManager::OnQueryDownloadEntriesComplete(
818 std::vector<DownloadHistoryInfo>* entries) { 806 std::vector<DownloadHistoryInfo>* entries) {
819 for (size_t i = 0; i < entries->size(); ++i) { 807 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), 1058 Source<DownloadManager>(this),
1071 Details<DownloadItem>(download)); 1059 Details<DownloadItem>(download));
1072 } 1060 }
1073 } 1061 }
1074 1062
1075 int32 DownloadManager::GetNextSavePageId() { 1063 int32 DownloadManager::GetNextSavePageId() {
1076 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1064 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1077 return next_save_page_id_++; 1065 return next_save_page_id_++;
1078 } 1066 }
1079 1067
OLDNEW
« content/browser/download/download_manager.h ('K') | « content/browser/download/download_manager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698