Chromium Code Reviews| 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()) |