Index: content/browser/download/download_manager_impl.cc |
diff --git a/content/browser/download/download_manager_impl.cc b/content/browser/download/download_manager_impl.cc |
index 6099eca4cf8befcdd88d2f9e95ca982b51be9192..8f668bc54cf4b24a98e1d4c3220c3e8cdb89dc72 100644 |
--- a/content/browser/download/download_manager_impl.cc |
+++ b/content/browser/download/download_manager_impl.cc |
@@ -39,6 +39,7 @@ |
#include "content/public/browser/render_process_host.h" |
#include "content/public/browser/resource_context.h" |
#include "content/public/browser/web_contents_delegate.h" |
+#include "content/public/common/referrer.h" |
#include "net/base/load_flags.h" |
#include "net/base/upload_data.h" |
#include "net/url_request/url_request_context.h" |
@@ -47,7 +48,8 @@ |
namespace content { |
namespace { |
-void BeginDownload(scoped_ptr<DownloadUrlParameters> params) { |
+void BeginDownload(scoped_ptr<DownloadUrlParameters> params, |
+ DownloadId download_id) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
// ResourceDispatcherHost{Base} is-not-a URLRequest::Delegate, and |
// DownloadUrlParameters can-not include resource_dispatcher_host_impl.h, so |
@@ -101,6 +103,9 @@ void BeginDownload(scoped_ptr<DownloadUrlParameters> params) { |
params->render_view_host_routing_id(), |
params->prefer_cache(), |
save_info.Pass(), |
+ params->last_modified(), |
+ params->etag(), |
+ download_id, |
params->callback()); |
} |
@@ -171,10 +176,8 @@ class DownloadItemFactoryImpl : public DownloadItemFactory { |
virtual DownloadItemImpl* CreateActiveItem( |
DownloadItemImplDelegate* delegate, |
const DownloadCreateInfo& info, |
- scoped_ptr<DownloadRequestHandleInterface> request_handle, |
const net::BoundNetLog& bound_net_log) OVERRIDE { |
- return new DownloadItemImpl(delegate, info, request_handle.Pass(), |
- bound_net_log); |
+ return new DownloadItemImpl(delegate, info, bound_net_log); |
} |
virtual DownloadItemImpl* CreateSavePageItem( |
@@ -344,9 +347,6 @@ DownloadItem* DownloadManagerImpl::StartDownload( |
scoped_ptr<ByteStreamReader> stream) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- net::BoundNetLog bound_net_log = |
- net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); |
- |
FilePath default_download_directory; |
if (delegate_) { |
FilePath website_save_directory; // Unused |
@@ -358,8 +358,8 @@ DownloadItem* DownloadManagerImpl::StartDownload( |
// We create the DownloadItem before the DownloadFile because the |
// DownloadItem already needs to handle a state in which there is |
// no associated DownloadFile (history downloads, !IN_PROGRESS downloads) |
- DownloadItemImpl* download = |
- CreateDownloadItem(info.get(), bound_net_log); |
+ DownloadItemImpl* download = CreateDownloadItem(info.get()); |
+ net::BoundNetLog bound_net_log = download->GetBoundNetLog(); |
scoped_ptr<DownloadFile> download_file( |
file_factory_->CreateFile( |
info->save_info.Pass(), default_download_directory, |
@@ -367,7 +367,9 @@ DownloadItem* DownloadManagerImpl::StartDownload( |
delegate_->GenerateFileHash(), |
stream.Pass(), bound_net_log, |
download->DestinationObserverAsWeakPtr())); |
- download->Start(download_file.Pass()); |
+ scoped_ptr<DownloadRequestHandleInterface> req_handle( |
+ new DownloadRequestHandle(info->request_handle)); |
+ download->Start(download_file.Pass(), req_handle.Pass()); |
// Delay notification until after Start() so that download_file is bound |
// to download and all the usual setters (e.g. Cancel) work. |
@@ -420,19 +422,40 @@ BrowserContext* DownloadManagerImpl::GetBrowserContext() const { |
} |
DownloadItemImpl* DownloadManagerImpl::CreateDownloadItem( |
- DownloadCreateInfo* info, const net::BoundNetLog& bound_net_log) { |
+ DownloadCreateInfo* info) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
if (!info->download_id.IsValid()) |
info->download_id = GetNextId(); |
- DownloadItemImpl* download = item_factory_->CreateActiveItem( |
- this, *info, |
- scoped_ptr<DownloadRequestHandleInterface>( |
- new DownloadRequestHandle(info->request_handle)).Pass(), |
- bound_net_log); |
- DCHECK(!ContainsKey(downloads_, download->GetId())); |
- downloads_[download->GetId()] = download; |
+ int32 download_id = info->download_id.local(); |
+ DownloadItemImpl* download = NULL; |
+ bool resuming = ContainsKey(downloads_, download_id); |
+ if (resuming) { |
+ download = downloads_[download_id]; |
+ DCHECK(download != NULL); |
+ DCHECK(download->IsInProgress()); |
+ } |
+ |
+ if (download) { |
+ // Reuse an interrupted |DownloadItem|. |
+ DCHECK(download->IsInterrupted()); |
+ } else { |
+ // Create a new |DownloadItem|. |
+ // |bound_net_log| will be used for logging the both the download item's and |
+ // the download file's events. |
+ net::BoundNetLog bound_net_log = |
+ net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); |
+ download = item_factory_->CreateActiveItem(this, *info, bound_net_log); |
+ |
+ DCHECK(!ContainsKey(downloads_, download->GetId())); |
+ downloads_[download->GetId()] = download; |
+ } |
+ |
+ DVLOG(20) << __FUNCTION__ << "()" |
+ << " info " << info->DebugString() |
+ << " download " << download->DebugString(true); |
+ |
DCHECK(!ContainsKey(active_downloads_, download->GetId())); |
active_downloads_[download->GetId()] = download; |
@@ -486,8 +509,17 @@ void DownloadManagerImpl::DownloadCompleted(DownloadItemImpl* download) { |
void DownloadManagerImpl::CancelDownload(int32 download_id) { |
// A cancel at the right time could remove the download from the |
// |active_downloads_| map before we get here. |
- if (ContainsKey(active_downloads_, download_id)) |
- active_downloads_[download_id]->Cancel(true); |
+ if (!ContainsKey(active_downloads_, download_id)) |
+ return; |
+ |
+ DownloadItem* download = active_downloads_[download_id]; |
+ |
+ VLOG(20) << __FUNCTION__ << "() download = " << download->DebugString(true); |
+ |
+ if (!download->IsInProgress()) |
+ return; |
+ |
+ download->Cancel(true); |
} |
void DownloadManagerImpl::DownloadStopped(DownloadItemImpl* download) { |
@@ -502,6 +534,18 @@ void DownloadManagerImpl::DownloadStopped(DownloadItemImpl* download) { |
AssertStateConsistent(download); |
} |
+// Resume a download of a specific URL. We send the request to the |
+// ResourceDispatcherHost, and let it send us responses like a regular |
+// download. |
+void DownloadManagerImpl::ResumeInterruptedDownload( |
+ scoped_ptr<content::DownloadUrlParameters> params, |
+ content::DownloadId id) { |
+ BrowserThread::PostTask( |
+ BrowserThread::IO, |
+ FROM_HERE, |
+ base::Bind(&BeginDownload, base::Passed(params.Pass()), id)); |
+} |
+ |
void DownloadManagerImpl::RemoveFromActiveList(DownloadItemImpl* download) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
DCHECK(download); |
@@ -587,8 +631,12 @@ void DownloadManagerImpl::DownloadUrl( |
DCHECK(params->prefer_cache()); |
DCHECK(params->method() == "POST"); |
} |
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( |
- &BeginDownload, base::Passed(params.Pass()))); |
+ BrowserThread::PostTask( |
+ BrowserThread::IO, FROM_HERE, |
+ base::Bind( |
+ &BeginDownload, |
+ base::Passed(params.Pass()), |
+ DownloadId())); |
} |
void DownloadManagerImpl::AddObserver(Observer* observer) { |