Index: chrome/browser/download/download_file_manager.cc |
diff --git a/chrome/browser/download/download_file_manager.cc b/chrome/browser/download/download_file_manager.cc |
index fc94314139d4c9eeec00764dc0e32fd13bb8a4c2..ef545b5f7f51f5408357b8311b2d8c352ed4712b 100644 |
--- a/chrome/browser/download/download_file_manager.cc |
+++ b/chrome/browser/download/download_file_manager.cc |
@@ -78,36 +78,53 @@ void DownloadFileManager::CreateDownloadFile( |
DownloadCreateInfo* info, DownloadManager* download_manager) { |
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); |
- scoped_ptr<DownloadFile> download_file( |
- new DownloadFile(info, download_manager)); |
- if (!download_file->Initialize()) { |
- ChromeThread::PostTask( |
- ChromeThread::IO, FROM_HERE, |
- NewRunnableFunction(&download_util::CancelDownloadRequest, |
- resource_dispatcher_host_, |
- info->child_id, |
- info->request_id)); |
- delete info; |
- return; |
+ // See if we are reusing a download ID. |
+ DownloadFile* download_file = NULL; |
+ if (info->download_id != -1) { |
+ DownloadFileMap::iterator item = downloads_.find(info->download_id); |
Paweł Hajdan Jr.
2010/10/01 09:03:55
This is wrong, as said (and I think fixed) in http
|
+ if (item != downloads_.end()) { |
+ download_file = item->second; |
+ download_file->ReOpen(); |
+ } |
+ } |
+ if (!download_file) { |
+ download_file = new DownloadFile(info, download_manager); |
+ if (!download_file->Initialize()) { |
+ ChromeThread::PostTask( |
+ ChromeThread::IO, |
+ FROM_HERE, |
+ NewRunnableFunction(&download_util::CancelDownloadRequest, |
+ resource_dispatcher_host_, |
+ info->child_id, |
+ info->request_id)); |
+ delete info; |
+ return; |
+ } |
+ |
+ DCHECK(GetDownloadFile(info->download_id) == NULL); |
+ downloads_[info->download_id] = download_file; |
} |
- DCHECK(GetDownloadFile(info->download_id) == NULL); |
- downloads_[info->download_id] = download_file.release(); |
// TODO(phajdan.jr): fix the duplication of path info below. |
info->path = info->save_info.file_path; |
// The file is now ready, we can un-pause the request and start saving data. |
ChromeThread::PostTask( |
- ChromeThread::IO, FROM_HERE, |
- NewRunnableMethod(this, &DownloadFileManager::ResumeDownloadRequest, |
- info->child_id, info->request_id)); |
+ ChromeThread::IO, |
+ FROM_HERE, |
+ NewRunnableMethod(this, |
+ &DownloadFileManager::ResumeDownloadRequest, |
+ info->child_id, |
+ info->request_id)); |
StartUpdateTimer(); |
ChromeThread::PostTask( |
- ChromeThread::UI, FROM_HERE, |
+ ChromeThread::UI, |
+ FROM_HERE, |
NewRunnableMethod(download_manager, |
- &DownloadManager::StartDownload, info)); |
+ &DownloadManager::StartDownload, |
+ info)); |
} |
void DownloadFileManager::ResumeDownloadRequest(int child_id, int request_id) { |
@@ -179,6 +196,19 @@ void DownloadFileManager::StartDownload(DownloadCreateInfo* info) { |
info, manager)); |
} |
+int DownloadFileManager::GetDownloadId(const GURL& url, |
+ const FilePath& path) const { |
+ FilePath crpath = download_util::GetCrDownloadPath(path); |
+ DownloadFileMap::const_iterator it = downloads_.begin(); |
+ DownloadFileMap::const_iterator last = downloads_.end(); |
+ for (; it != last; ++it) { |
+ const DownloadFile* download = it->second; |
+ if (download && (download->MatchesUrlAndPath(url, crpath))) |
+ return download->id(); |
+ } |
+ return -1; |
+} |
+ |
// We don't forward an update to the UI thread here, since we want to throttle |
// the UI update rate via a periodic timer. If the user has cancelled the |
// download (in the UI thread), we may receive a few more updates before the IO |
@@ -202,27 +232,38 @@ void DownloadFileManager::UpdateDownload(int id, DownloadBuffer* buffer) { |
} |
} |
-void DownloadFileManager::OnResponseCompleted(int id, DownloadBuffer* buffer) { |
+void DownloadFileManager::OnResponseCompleted( |
+ int id, |
+ DownloadBuffer* buffer, |
+ int os_error, |
+ const std::string& security_info) { |
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); |
delete buffer; |
- DownloadFileMap::iterator it = downloads_.find(id); |
- if (it != downloads_.end()) { |
- DownloadFile* download = it->second; |
+ DownloadFile* download = GetDownloadFile(id); |
+ if (download) { |
+ // Closes the file. In the case of an error, it closes the temporary |
+ // (.crdownload) one; otherwise it closes the original download file name. |
+ DCHECK(!os_error == |
+ !download_util::IsCrDownloadPath(download->full_path())); |
download->Finish(); |
DownloadManager* download_manager = download->GetDownloadManager(); |
if (download_manager) { |
ChromeThread::PostTask( |
- ChromeThread::UI, FROM_HERE, |
+ ChromeThread::UI, |
+ FROM_HERE, |
NewRunnableMethod( |
- download_manager, &DownloadManager::OnAllDataSaved, |
- id, download->bytes_so_far())); |
+ download_manager, |
+ &DownloadManager::OnResponseCompleted, |
+ id, |
+ download->bytes_so_far(), |
+ os_error)); |
} |
// We need to keep the download around until the UI thread has finalized |
// the name. |
if (download->path_renamed()) { |
- downloads_.erase(it); |
+ downloads_.erase(downloads_.find(id)); |
delete download; |
} |
} |
@@ -278,8 +319,7 @@ void DownloadFileManager::OnDownloadManagerShutdown(DownloadManager* manager) { |
// The DownloadManager in the UI thread has provided an intermediate .crdownload |
// name for the download specified by 'id'. Rename the in progress download. |
void DownloadFileManager::OnIntermediateDownloadName( |
- int id, const FilePath& full_path, DownloadManager* download_manager) |
-{ |
+ int id, const FilePath& full_path, DownloadManager* download_manager) { |
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); |
DownloadFileMap::iterator it = downloads_.find(id); |
if (it == downloads_.end()) |