| 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) {
|
|
|