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

Side by Side Diff: chrome/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: 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 "chrome/browser/download/download_manager.h" 5 #include "chrome/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 593 matching lines...) Expand 10 before | Expand all | Expand 10 after
604 if (download->IsInProgress()) { 604 if (download->IsInProgress()) {
605 download->Update(size); 605 download->Update(size);
606 UpdateAppIcon(); // Reflect size updates. 606 UpdateAppIcon(); // Reflect size updates.
607 download_history_->UpdateEntry(download); 607 download_history_->UpdateEntry(download);
608 } 608 }
609 } 609 }
610 } 610 }
611 611
612 void DownloadManager::OnResponseCompleted(int32 download_id, 612 void DownloadManager::OnResponseCompleted(int32 download_id,
613 int64 size, 613 int64 size,
614 int os_error,
615 const std::string& hash) { 614 const std::string& hash) {
616 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
617 // ERR_CONNECTION_CLOSED is allowed since a number of servers in the wild
618 // advertise a larger Content-Length than the amount of bytes in the message
619 // body, and then close the connection. Other browsers - IE8, Firefox 4.0.1,
620 // and Safari 5.0.4 - treat the download as complete in this case, so we
621 // follow their lead.
622 if (os_error == 0 || os_error == net::ERR_CONNECTION_CLOSED) {
623 OnAllDataSaved(download_id, size, hash);
624 } else {
625 OnDownloadError(download_id, size, os_error);
626 }
627 }
628
629 void DownloadManager::OnAllDataSaved(int32 download_id,
630 int64 size,
631 const std::string& hash) {
632 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id 615 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id
633 << " size = " << size; 616 << " size = " << size;
634 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 617 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
635 618
636 // If it's not in active_downloads_, that means it was cancelled; just 619 // If it's not in active_downloads_, that means it was cancelled; just
637 // ignore the notification. 620 // ignore the notification.
638 if (active_downloads_.count(download_id) == 0) 621 if (active_downloads_.count(download_id) == 0)
639 return; 622 return;
640 623
641 DownloadItem* download = active_downloads_[download_id]; 624 DownloadItem* download = active_downloads_[download_id];
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
798 file_manager_, &DownloadFileManager::CompleteDownload, download_id)); 781 file_manager_, &DownloadFileManager::CompleteDownload, download_id));
799 782
800 if (uniquifier) 783 if (uniquifier)
801 item->set_path_uniquifier(uniquifier); 784 item->set_path_uniquifier(uniquifier);
802 785
803 item->OnDownloadRenamedToFinalName(full_path); 786 item->OnDownloadRenamedToFinalName(full_path);
804 download_history_->UpdateDownloadPath(item, full_path); 787 download_history_->UpdateDownloadPath(item, full_path);
805 } 788 }
806 789
807 void DownloadManager::DownloadCancelled(int32 download_id) { 790 void DownloadManager::DownloadCancelled(int32 download_id) {
808 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 791 DownloadItem* download = GetActiveDownload(download_id);
809 DownloadMap::iterator it = in_progress_.find(download_id); 792
810 if (it == in_progress_.end()) 793 // A cancel at the right time could remove the download from the
794 // |active_downloads_| map before we get here.
795 if (!download)
811 return; 796 return;
812 DownloadItem* download = it->second;
813 797
814 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id 798 RemoveFromActiveList(download);
815 << " download = " << download->DebugString(true);
816
817 // Clean up will happen when the history system create callback runs if we
818 // don't have a valid db_handle yet.
819 if (download->db_handle() != DownloadHistory::kUninitializedHandle) {
820 in_progress_.erase(it);
821 active_downloads_.erase(download_id);
822 UpdateAppIcon(); // Reflect removal from in_progress_.
823 download_history_->UpdateEntry(download);
824 }
825 799
826 DownloadCancelledInternal(download_id, download->request_handle()); 800 DownloadCancelledInternal(download_id, download->request_handle());
827 } 801 }
802
803 void DownloadManager::OnDownloadError(int32 download_id,
804 int64 size,
805 int error) {
806 DownloadItem* download = GetActiveDownload(download_id);
807
cbentzel 2011/08/16 15:50:36 Nit: extra new line.
ahendrickson 2011/08/18 21:52:01 Done.
808 if (!download)
809 return;
810
811 VLOG(20) << __FUNCTION__ << "()" << " Error " << error
812 << " at offset " << download->received_bytes()
813 << " size = " << size;
814
815 RemoveFromActiveList(download);
816
cbentzel 2011/08/16 15:50:36 Nit: extra new line
ahendrickson 2011/08/18 21:52:01 Done.
817 download->Interrupted(size, error);
818
cbentzel 2011/08/16 15:50:36 Nit: extra new line
ahendrickson 2011/08/18 21:52:01 Done.
819 DownloadCancelledInternal(download_id, download->request_handle());
820 }
828 821
829 void DownloadManager::DownloadCancelledInternal( 822 void DownloadManager::DownloadCancelledInternal(
830 int download_id, const DownloadRequestHandle& request_handle) { 823 int download_id, const DownloadRequestHandle& request_handle) {
831 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 824 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
832 request_handle.CancelRequest(); 825 request_handle.CancelRequest();
833 826
834 BrowserThread::PostTask( 827 BrowserThread::PostTask(
835 BrowserThread::FILE, FROM_HERE, 828 BrowserThread::FILE, FROM_HERE,
836 NewRunnableMethod( 829 NewRunnableMethod(
837 file_manager_, &DownloadFileManager::CancelDownload, download_id)); 830 file_manager_, &DownloadFileManager::CancelDownload, download_id));
838 } 831 }
839 832
840 void DownloadManager::OnDownloadError(int32 download_id, 833 DownloadItem* DownloadManager::GetActiveDownload(int32 download_id) {
841 int64 size,
842 int os_error) {
843 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 834 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
844 DownloadMap::iterator it = active_downloads_.find(download_id); 835 DownloadMap::iterator it = active_downloads_.find(download_id);
845 // A cancel at the right time could remove the download from the
846 // |active_downloads_| map before we get here.
847 if (it == active_downloads_.end()) 836 if (it == active_downloads_.end())
848 return; 837 return NULL;
849 838
850 DownloadItem* download = it->second; 839 DownloadItem* download = it->second;
851 840
852 VLOG(20) << __FUNCTION__ << "()" << " Error " << os_error 841 DCHECK(download);
853 << " at offset " << download->received_bytes() 842 DCHECK_EQ(download_id, download->id());
854 << " for download = " << download->DebugString(true);
855 843
856 download->Interrupted(size, os_error); 844 VLOG(20) << __FUNCTION__ << "()"
845 << " download = " << download->DebugString(true);
857 846
858 // TODO(ahendrickson) - Remove this when we add resuming of interrupted 847 return download;
859 // downloads, as we will keep the download item around in that case. 848 }
860 // 849
850 void DownloadManager::RemoveFromActiveList(DownloadItem* download) {
851 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
852 DCHECK(download);
853
861 // Clean up will happen when the history system create callback runs if we 854 // Clean up will happen when the history system create callback runs if we
862 // don't have a valid db_handle yet. 855 // don't have a valid db_handle yet.
863 if (download->db_handle() != DownloadHistory::kUninitializedHandle) { 856 if (download->db_handle() != DownloadHistory::kUninitializedHandle) {
864 in_progress_.erase(download_id); 857 in_progress_.erase(download->id());
865 active_downloads_.erase(download_id); 858 active_downloads_.erase(download->id());
866 UpdateAppIcon(); // Reflect removal from in_progress_. 859 UpdateAppIcon(); // Reflect removal from in_progress_.
867 download_history_->UpdateEntry(download); 860 download_history_->UpdateEntry(download);
868 } 861 }
869
870 BrowserThread::PostTask(
871 BrowserThread::FILE, FROM_HERE,
872 NewRunnableMethod(
873 file_manager_, &DownloadFileManager::CancelDownload, download_id));
874 } 862 }
875 863
876 void DownloadManager::UpdateAppIcon() { 864 void DownloadManager::UpdateAppIcon() {
877 if (status_updater_) 865 if (status_updater_)
878 status_updater_->Update(); 866 status_updater_->Update();
879 } 867 }
880 868
881 int DownloadManager::RemoveDownloadItems( 869 int DownloadManager::RemoveDownloadItems(
882 const DownloadVector& pending_deletes) { 870 const DownloadVector& pending_deletes) {
883 if (pending_deletes.empty()) 871 if (pending_deletes.empty())
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
1069 int32 download_id = *id_ptr; 1057 int32 download_id = *id_ptr;
1070 delete id_ptr; 1058 delete id_ptr;
1071 1059
1072 DownloadItem* download = GetActiveDownloadItem(download_id); 1060 DownloadItem* download = GetActiveDownloadItem(download_id);
1073 if (!download) 1061 if (!download)
1074 return; 1062 return;
1075 1063
1076 VLOG(20) << __FUNCTION__ << "()" 1064 VLOG(20) << __FUNCTION__ << "()"
1077 << " download = " << download->DebugString(true); 1065 << " download = " << download->DebugString(true);
1078 1066
1067 // TODO(ahendrickson) -- This currently has no effect.
1068 RemoveFromActiveList(download);
1069
1079 DownloadCancelledInternal(download_id, download->request_handle()); 1070 DownloadCancelledInternal(download_id, download->request_handle());
1080 } 1071 }
1081 1072
1082 // TODO(phajdan.jr): This is apparently not being exercised in tests. 1073 // TODO(phajdan.jr): This is apparently not being exercised in tests.
1083 bool DownloadManager::IsDangerousFile(const DownloadItem& download, 1074 bool DownloadManager::IsDangerousFile(const DownloadItem& download,
1084 const DownloadStateInfo& state, 1075 const DownloadStateInfo& state,
1085 bool visited_referrer_before) { 1076 bool visited_referrer_before) {
1086 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1077 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1087 1078
1088 bool auto_open = ShouldOpenFileBasedOnExtension(state.suggested_path); 1079 bool auto_open = ShouldOpenFileBasedOnExtension(state.suggested_path);
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
1366 Source<DownloadManager>(this), 1357 Source<DownloadManager>(this),
1367 Details<DownloadItem>(download)); 1358 Details<DownloadItem>(download));
1368 } 1359 }
1369 } 1360 }
1370 1361
1371 int32 DownloadManager::GetNextSavePageId() { 1362 int32 DownloadManager::GetNextSavePageId() {
1372 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1363 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1373 return next_save_page_id_++; 1364 return next_save_page_id_++;
1374 } 1365 }
1375 1366
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698