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

Unified Diff: content/browser/download/download_item_impl.cc

Issue 148133007: [Downloads] Always call DM::StartDownload() for explicit downloads. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix typos Created 4 years, 10 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/download/download_item_impl.cc
diff --git a/content/browser/download/download_item_impl.cc b/content/browser/download/download_item_impl.cc
index 028e6d5531ca7d85481b992b5e5990dadedc3f50..b2c6ada075507f2c7a7ed99ed228774aa2e0277a 100644
--- a/content/browser/download/download_item_impl.cc
+++ b/content/browser/download/download_item_impl.cc
@@ -192,7 +192,7 @@ DownloadItemImpl::DownloadItemImpl(DownloadItemImplDelegate* delegate,
bytes_per_sec_(0),
last_modified_time_(info.last_modified),
etag_(info.etag),
- last_reason_(DOWNLOAD_INTERRUPT_REASON_NONE),
+ last_reason_(info.result),
start_tick_(base::TimeTicks::Now()),
state_(INITIAL_INTERNAL),
danger_type_(DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS),
@@ -205,7 +205,7 @@ DownloadItemImpl::DownloadItemImpl(DownloadItemImplDelegate* delegate,
auto_opened_(false),
is_temporary_(!info.save_info->file_path.empty()),
all_data_saved_(false),
- destination_error_(content::DOWNLOAD_INTERRUPT_REASON_NONE),
+ destination_error_(DOWNLOAD_INTERRUPT_REASON_NONE),
opened_(false),
delegate_delayed_complete_(false),
bound_net_log_(bound_net_log),
@@ -295,6 +295,7 @@ void DownloadItemImpl::RemoveObserver(Observer* observer) {
void DownloadItemImpl::UpdateObservers() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DVLOG(20) << __FUNCTION__ << "()";
FOR_EACH_OBSERVER(Observer, observers_, OnDownloadUpdated(this));
}
@@ -318,7 +319,9 @@ void DownloadItemImpl::ValidateDangerousDownload() {
net::NetLog::TYPE_DOWNLOAD_ITEM_SAFETY_STATE_UPDATED,
base::Bind(&ItemCheckedNetLogCallback, GetDangerType()));
- UpdateObservers();
+ UpdateObservers(); // TODO(asanka): This is potentially unsafe. The download
+ // may not be in a consistent state or around at all after
+ // invoking observers. http://crbug.com/586610
MaybeCompleteDownload();
}
@@ -351,17 +354,22 @@ void DownloadItemImpl::Pause() {
return;
switch (state_) {
- case INITIAL_INTERNAL:
- case COMPLETING_INTERNAL:
+ case CANCELLED_INTERNAL:
case COMPLETE_INTERNAL:
+ case COMPLETING_INTERNAL:
+ case INITIAL_INTERNAL:
case INTERRUPTED_INTERNAL:
- case CANCELLED_INTERNAL:
+ case INTERRUPTED_TARGET_PENDING_INTERNAL:
case RESUMING_INTERNAL:
// No active request.
+ // TODO(asanka): In the case of RESUMING_INTERNAL, consider setting
+ // is_paused_ even if there's no request currently associated with this
+ // DII. When a request is assigned (due to a resumption, for example) we
+ // can honor the is_paused_ setting.
return;
- case TARGET_PENDING_INTERNAL:
case IN_PROGRESS_INTERNAL:
+ case TARGET_PENDING_INTERNAL:
request_handle_->PauseRequest();
is_paused_ = true;
UpdateObservers();
@@ -375,15 +383,14 @@ void DownloadItemImpl::Pause() {
void DownloadItemImpl::Resume() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DVLOG(20) << __FUNCTION__ << "() download = " << DebugString(true);
switch (state_) {
- case INITIAL_INTERNAL:
- case COMPLETING_INTERNAL:
+ case CANCELLED_INTERNAL: // Nothing to resume.
case COMPLETE_INTERNAL:
- case CANCELLED_INTERNAL:
- // Nothing to resume.
- case RESUMING_INTERNAL:
- // Resumption in progress.
- DCHECK(!is_paused_);
+ case COMPLETING_INTERNAL:
+ case INITIAL_INTERNAL:
+ case INTERRUPTED_TARGET_PENDING_INTERNAL:
+ case RESUMING_INTERNAL: // Resumption in progress.
return;
case TARGET_PENDING_INTERNAL:
@@ -398,6 +405,7 @@ void DownloadItemImpl::Resume() {
case INTERRUPTED_INTERNAL:
auto_resume_count_ = 0; // User input resets the counter.
ResumeInterruptedDownload();
+ UpdateObservers();
return;
case MAX_DOWNLOAD_INTERNAL_STATE:
@@ -411,6 +419,7 @@ void DownloadItemImpl::Cancel(bool user_cancel) {
DVLOG(20) << __FUNCTION__ << "() download = " << DebugString(true);
Interrupt(user_cancel ? DOWNLOAD_INTERRUPT_REASON_USER_CANCELED
: DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN);
+ UpdateObservers();
}
void DownloadItemImpl::Remove() {
@@ -419,6 +428,7 @@ void DownloadItemImpl::Remove() {
delegate_->AssertStateConsistent(this);
Interrupt(DOWNLOAD_INTERRUPT_REASON_USER_CANCELED);
+ UpdateObservers();
delegate_->AssertStateConsistent(this);
NotifyRemoved();
@@ -485,6 +495,7 @@ bool DownloadItemImpl::CanResume() const {
case COMPLETE_INTERNAL:
case CANCELLED_INTERNAL:
case RESUMING_INTERNAL:
+ case INTERRUPTED_TARGET_PENDING_INTERNAL:
return false;
case TARGET_PENDING_INTERNAL:
@@ -513,6 +524,7 @@ bool DownloadItemImpl::IsDone() const {
case COMPLETING_INTERNAL:
case RESUMING_INTERNAL:
case TARGET_PENDING_INTERNAL:
+ case INTERRUPTED_TARGET_PENDING_INTERNAL:
case TARGET_RESOLVED_INTERNAL:
case IN_PROGRESS_INTERNAL:
return false;
@@ -903,7 +915,6 @@ DownloadItemImpl::ResumeMode DownloadItemImpl::GetResumeMode() const {
case DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED:
case DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED:
case DOWNLOAD_INTERRUPT_REASON_NETWORK_SERVER_DOWN:
- case DOWNLOAD_INTERRUPT_REASON_NETWORK_INVALID_REQUEST:
case DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED:
case DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN:
case DOWNLOAD_INTERRUPT_REASON_CRASH:
@@ -922,6 +933,7 @@ DownloadItemImpl::ResumeMode DownloadItemImpl::GetResumeMode() const {
break;
case DOWNLOAD_INTERRUPT_REASON_NONE:
+ case DOWNLOAD_INTERRUPT_REASON_NETWORK_INVALID_REQUEST:
case DOWNLOAD_INTERRUPT_REASON_FILE_VIRUS_INFECTED:
case DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT:
case DOWNLOAD_INTERRUPT_REASON_USER_CANCELED:
@@ -937,7 +949,7 @@ DownloadItemImpl::ResumeMode DownloadItemImpl::GetResumeMode() const {
return mode;
}
-void DownloadItemImpl::MergeOriginInfoOnResume(
+void DownloadItemImpl::UpdateValidatorsOnResumption(
const DownloadCreateInfo& new_create_info) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK_EQ(RESUMING_INTERNAL, state_);
@@ -1022,7 +1034,8 @@ void DownloadItemImpl::MarkAsComplete() {
DCHECK(all_data_saved_);
end_time_ = base::Time::Now();
- TransitionTo(COMPLETE_INTERNAL, UPDATE_OBSERVERS);
+ TransitionTo(COMPLETE_INTERNAL);
+ UpdateObservers();
}
void DownloadItemImpl::DestinationUpdate(int64_t bytes_so_far,
@@ -1071,10 +1084,12 @@ void DownloadItemImpl::DestinationError(DownloadInterruptReason reason) {
// Postpone recognition of this error until after file name determination
// has completed and the intermediate file has been renamed to simplify
// resumption conditions.
- if (state_ != IN_PROGRESS_INTERNAL)
+ if (state_ == TARGET_PENDING_INTERNAL) {
destination_error_ = reason;
- else
- Interrupt(reason);
+ return;
+ }
+ Interrupt(reason);
+ UpdateObservers();
}
void DownloadItemImpl::DestinationCompleted(const std::string& final_hash) {
@@ -1131,25 +1146,65 @@ void DownloadItemImpl::Init(bool active,
// We're starting the download.
void DownloadItemImpl::Start(
scoped_ptr<DownloadFile> file,
- scoped_ptr<DownloadRequestHandleInterface> req_handle) {
+ scoped_ptr<DownloadRequestHandleInterface> req_handle,
+ const DownloadCreateInfo& new_create_info) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(!download_file_.get());
- DCHECK(file.get());
- DCHECK(req_handle.get());
DVLOG(20) << __FUNCTION__ << "() this=" << DebugString(true);
download_file_ = std::move(file);
request_handle_ = std::move(req_handle);
+ destination_error_ = DOWNLOAD_INTERRUPT_REASON_NONE;
if (state_ == CANCELLED_INTERNAL) {
// The download was in the process of resuming when it was cancelled. Don't
// proceed.
ReleaseDownloadFile(true);
- request_handle_->CancelRequest();
+ if (request_handle_)
+ request_handle_->CancelRequest();
return;
}
- TransitionTo(TARGET_PENDING_INTERNAL, UPDATE_OBSERVERS);
+ // The state could be one of the following:
+ //
+ // INITIAL_INTERNAL: A normal download attempt.
+ //
+ // RESUMING_INTERNAL: A resumption attempt. May or may not have been
+ // successful.
+ DCHECK(state_ == INITIAL_INTERNAL || state_ == RESUMING_INTERNAL);
+
+ // If the state_ is INITIAL_INTERNAL, then the target path must be empty.
+ DCHECK(state_ != INITIAL_INTERNAL || target_path_.empty());
+
+ // If a resumption attempted failed, or if the download was DOA, then the
+ // download should go back to being interrupted.
+ if (new_create_info.result != DOWNLOAD_INTERRUPT_REASON_NONE) {
+ DCHECK(!download_file_.get());
+
+ // Interrupted downloads also need a target path.
+ if (target_path_.empty()) {
+ TransitionTo(INTERRUPTED_TARGET_PENDING_INTERNAL);
+ destination_error_ = new_create_info.result;
+ DetermineDownloadTarget();
+ return;
+ }
+
+ // Otherwise, this was a resumption attempt which ended with an
+ // interruption. Continue with current target path.
+ TransitionTo(TARGET_RESOLVED_INTERNAL);
+ Interrupt(new_create_info.result);
+ UpdateObservers();
+ return;
+ }
+
+ // Successful download start.
+ DCHECK(download_file_.get());
+ DCHECK(request_handle_.get());
+
+ if (state_ == RESUMING_INTERNAL)
+ UpdateValidatorsOnResumption(new_create_info);
+
+ TransitionTo(TARGET_PENDING_INTERNAL);
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
@@ -1167,35 +1222,32 @@ void DownloadItemImpl::OnDownloadFileInitialized(
DVLOG(20) << __FUNCTION__
<< "() result:" << DownloadInterruptReasonToString(result);
if (result != DOWNLOAD_INTERRUPT_REASON_NONE) {
- // Transition out to TARGET_RESOLVED_INTERNAL since this DownloadItem is
- // skipping the download target determination process.
- TransitionTo(TARGET_RESOLVED_INTERNAL, DONT_UPDATE_OBSERVERS);
- Interrupt(result);
- // TODO(rdsmith/asanka): Arguably we should show this in the UI, but
- // it's not at all clear what to show--we haven't done filename
- // determination, so we don't know what name to display. OTOH,
- // the failure mode of not showing the DI if the file initialization
- // fails isn't a good one. Can we hack up a name based on the
- // URLRequest? We'll need to make sure that initialization happens
- // properly. Possibly the right thing is to have the UI handle
- // this case specially.
- return;
+ // Whoops. That didn't work. Proceed as an interrupted download.
+ destination_error_ = result;
+ TransitionTo(INTERRUPTED_TARGET_PENDING_INTERNAL);
}
+ DetermineDownloadTarget();
+}
+
+void DownloadItemImpl::DetermineDownloadTarget() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DVLOG(20) << __FUNCTION__ << "() " << DebugString(true);
+
delegate_->DetermineDownloadTarget(
this, base::Bind(&DownloadItemImpl::OnDownloadTargetDetermined,
weak_ptr_factory_.GetWeakPtr()));
}
-// Called by delegate_ when the download target path has been
-// determined.
+// Called by delegate_ when the download target path has been determined.
void DownloadItemImpl::OnDownloadTargetDetermined(
const base::FilePath& target_path,
TargetDisposition disposition,
DownloadDangerType danger_type,
const base::FilePath& intermediate_path) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK_EQ(state_, TARGET_PENDING_INTERNAL);
+ DCHECK(state_ == TARGET_PENDING_INTERNAL ||
+ state_ == INTERRUPTED_TARGET_PENDING_INTERNAL);
// If the |target_path| is empty, then we consider this download to be
// canceled.
@@ -1204,21 +1256,23 @@ void DownloadItemImpl::OnDownloadTargetDetermined(
return;
}
- // TODO(rdsmith,asanka): We are ignoring the possibility that the download
- // has been interrupted at this point until we finish the intermediate
- // rename and set the full path. That's dangerous, because we might race
- // with resumption, either manual (because the interrupt is visible to the
- // UI) or automatic. If we keep the "ignore an error on download until file
- // name determination complete" semantics, we need to make sure that the
- // error is kept completely invisible until that point.
-
- DVLOG(20) << __FUNCTION__ << " " << target_path.value() << " " << disposition
- << " " << danger_type << " " << DebugString(true);
+ DVLOG(20) << __FUNCTION__ << "() target_path:" << target_path.value()
+ << " disposition:" << disposition << " danger_type:" << danger_type
+ << " this:" << DebugString(true);
target_path_ = target_path;
target_disposition_ = disposition;
SetDangerType(danger_type);
+ // This was an interrupted download that was looking for a filename. Now that
+ // it has one, transition to interrupted.
+ if (state_ == INTERRUPTED_TARGET_PENDING_INTERNAL) {
+ Interrupt(destination_error_);
+ destination_error_ = DOWNLOAD_INTERRUPT_REASON_NONE;
+ UpdateObservers();
+ return;
+ }
+
// We want the intermediate and target paths to refer to the same directory so
// that they are both on the same device and subject to same
// space/permission/availability constraints.
@@ -1261,7 +1315,7 @@ void DownloadItemImpl::OnDownloadRenamedToIntermediateName(
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK_EQ(state_, TARGET_PENDING_INTERNAL);
DVLOG(20) << __FUNCTION__ << " download=" << DebugString(true);
- TransitionTo(TARGET_RESOLVED_INTERNAL, DONT_UPDATE_OBSERVERS);
+ TransitionTo(TARGET_RESOLVED_INTERNAL);
if (DOWNLOAD_INTERRUPT_REASON_NONE != destination_error_) {
// Process destination error. If both |reason| and |destination_error_|
@@ -1271,15 +1325,21 @@ void DownloadItemImpl::OnDownloadRenamedToIntermediateName(
SetFullPath(full_path);
Interrupt(destination_error_);
destination_error_ = DOWNLOAD_INTERRUPT_REASON_NONE;
+ UpdateObservers();
} else if (DOWNLOAD_INTERRUPT_REASON_NONE != reason) {
Interrupt(reason);
// All file errors result in file deletion above; no need to cleanup. The
// current_path_ should be empty. Resuming this download will force a
// restart and a re-doing of filename determination.
DCHECK(current_path_.empty());
+ UpdateObservers();
} else {
SetFullPath(full_path);
- TransitionTo(IN_PROGRESS_INTERNAL, UPDATE_OBSERVERS);
+ TransitionTo(IN_PROGRESS_INTERNAL);
+ // TODO(asanka): Calling UpdateObservers() prior to MaybeCompleteDownload()
+ // is not safe. The download could be in an underminate state after invoking
+ // observers. http://crbug.com/586610
+ UpdateObservers();
MaybeCompleteDownload();
}
}
@@ -1327,9 +1387,8 @@ void DownloadItemImpl::OnDownloadCompleting() {
// TODO(rdsmith/benjhayden): Remove as part of SavePackage integration.
if (is_save_package_download_) {
// Avoid doing anything on the file thread; there's nothing we control
- // there.
- // Strictly speaking, this skips giving the embedder a chance to open
- // the download. But on a save package download, there's no real
+ // there. Strictly speaking, this skips giving the embedder a chance to
+ // open the download. But on a save package download, there's no real
// concept of opening.
Completed();
return;
@@ -1370,6 +1429,7 @@ void DownloadItemImpl::OnDownloadRenamedToFinalName(
// All file errors should have resulted in in file deletion above. On
// resumption we will need to re-do filename determination.
DCHECK(current_path_.empty());
+ UpdateObservers();
return;
}
@@ -1389,7 +1449,7 @@ void DownloadItemImpl::OnDownloadRenamedToFinalName(
// point we're committed to complete the download. Cancels (or Interrupts,
// though it's not clear how they could happen) after this point will be
// ignored.
- TransitionTo(COMPLETING_INTERNAL, DONT_UPDATE_OBSERVERS);
+ TransitionTo(COMPLETING_INTERNAL);
if (delegate_->ShouldOpenDownload(
this, base::Bind(&DownloadItemImpl::DelayedDownloadOpened,
@@ -1415,7 +1475,7 @@ void DownloadItemImpl::Completed() {
DCHECK(all_data_saved_);
end_time_ = base::Time::Now();
- TransitionTo(COMPLETE_INTERNAL, UPDATE_OBSERVERS);
+ TransitionTo(COMPLETE_INTERNAL);
RecordDownloadCompleted(start_tick_, received_bytes_);
if (auto_opened_) {
@@ -1430,24 +1490,8 @@ void DownloadItemImpl::Completed() {
OpenDownload();
auto_opened_ = true;
- UpdateObservers();
- }
-}
-
-void DownloadItemImpl::OnResumeRequestStarted(
- DownloadItem* item,
- DownloadInterruptReason interrupt_reason) {
- // If |item| is not NULL, then Start() has been called already, and nothing
- // more needs to be done here.
- if (item) {
- DCHECK_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, interrupt_reason);
- DCHECK_EQ(static_cast<DownloadItem*>(this), item);
- return;
}
- // Otherwise, the request failed without passing through
- // DownloadResourceHandler::OnResponseStarted.
- DCHECK_NE(DOWNLOAD_INTERRUPT_REASON_NONE, interrupt_reason);
- Interrupt(interrupt_reason);
+ UpdateObservers();
}
// **** End of Download progression cascade
@@ -1482,9 +1526,10 @@ void DownloadItemImpl::Interrupt(DownloadInterruptReason reason) {
NOTREACHED();
return;
+ case INTERRUPTED_TARGET_PENDING_INTERNAL:
+ case IN_PROGRESS_INTERNAL:
case TARGET_PENDING_INTERNAL:
case TARGET_RESOLVED_INTERNAL:
- case IN_PROGRESS_INTERNAL:
// last_reason_ needs to be set for GetResumeMode() to work.
last_reason_ = reason;
@@ -1542,16 +1587,16 @@ void DownloadItemImpl::Interrupt(DownloadInterruptReason reason) {
}
RecordDownloadCount(CANCELLED_COUNT);
- TransitionTo(CANCELLED_INTERNAL, DONT_UPDATE_OBSERVERS);
- } else {
- RecordDownloadInterrupted(reason, received_bytes_, total_bytes_);
- if (!GetWebContents())
- RecordDownloadCount(INTERRUPTED_WITHOUT_WEBCONTENTS);
- TransitionTo(INTERRUPTED_INTERNAL, DONT_UPDATE_OBSERVERS);
- AutoResumeIfValid();
+ TransitionTo(CANCELLED_INTERNAL);
+ return;
}
- UpdateObservers();
+ RecordDownloadInterrupted(reason, received_bytes_, total_bytes_);
+ if (!GetWebContents())
+ RecordDownloadCount(INTERRUPTED_WITHOUT_WEBCONTENTS);
+
+ TransitionTo(INTERRUPTED_INTERNAL);
+ AutoResumeIfValid();
}
void DownloadItemImpl::ReleaseDownloadFile(bool destroy_file) {
@@ -1597,8 +1642,10 @@ bool DownloadItemImpl::IsDownloadReadyForCompletion(
if (IsDangerous())
return false;
- // Invariants for the IN_PROGRESS state. DCHECKs here verify that the
- // invariants are still true.
+ // Check for consistency before invoking delegate. Since there are no pending
+ // target determination calls and the download is in progress, both the target
+ // and current paths should be non-empty and they should point to the same
+ // directory.
DCHECK(!target_path_.empty());
DCHECK(!current_path_.empty());
DCHECK(target_path_.DirName() == current_path_.DirName());
@@ -1611,8 +1658,7 @@ bool DownloadItemImpl::IsDownloadReadyForCompletion(
return true;
}
-void DownloadItemImpl::TransitionTo(DownloadInternalState new_state,
- ShouldUpdateObservers notify_action) {
+void DownloadItemImpl::TransitionTo(DownloadInternalState new_state) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (state_ == new_state)
@@ -1634,6 +1680,7 @@ void DownloadItemImpl::TransitionTo(DownloadInternalState new_state,
case TARGET_PENDING_INTERNAL:
case TARGET_RESOLVED_INTERNAL:
+ case INTERRUPTED_TARGET_PENDING_INTERNAL:
break;
case IN_PROGRESS_INTERNAL:
@@ -1715,9 +1762,6 @@ void DownloadItemImpl::TransitionTo(DownloadInternalState new_state,
this, SRC_ACTIVE_DOWNLOAD,
&file_name));
}
-
- if (notify_action == UPDATE_OBSERVERS)
- UpdateObservers();
}
void DownloadItemImpl::SetDangerType(DownloadDangerType danger_type) {
@@ -1779,6 +1823,10 @@ void DownloadItemImpl::ResumeInterruptedDownload() {
if (state_ != INTERRUPTED_INTERNAL)
return;
+ // We are starting a new request. Shake off all pending operations.
+ DCHECK(!download_file_);
+ weak_ptr_factory_.InvalidateWeakPtrs();
+
// Reset the appropriate state if restarting.
ResumeMode mode = GetResumeMode();
if (mode == RESUME_MODE_IMMEDIATE_RESTART ||
@@ -1789,25 +1837,19 @@ void DownloadItemImpl::ResumeInterruptedDownload() {
etag_ = "";
}
- scoped_ptr<DownloadUrlParameters> download_params;
- if (GetWebContents()) {
- download_params =
- DownloadUrlParameters::FromWebContents(GetWebContents(), GetURL());
- } else {
- download_params = make_scoped_ptr(new DownloadUrlParameters(
- GetURL(), -1, -1, -1, GetBrowserContext()->GetResourceContext()));
- }
-
+ // Avoid using the WebContents even if it's still around. Resumption requests
+ // are consistently routed through the no-renderer code paths so that the
+ // request will not be dropped if the WebContents (and by extension, the
+ // associated renderer) goes away before a response is received.
+ scoped_ptr<DownloadUrlParameters> download_params(new DownloadUrlParameters(
+ GetURL(), -1, -1, -1, GetBrowserContext()->GetResourceContext()));
download_params->set_file_path(GetFullPath());
download_params->set_offset(GetReceivedBytes());
download_params->set_hash_state(GetHashState());
download_params->set_last_modified(GetLastModifiedTime());
download_params->set_etag(GetETag());
- download_params->set_callback(
- base::Bind(&DownloadItemImpl::OnResumeRequestStarted,
- weak_ptr_factory_.GetWeakPtr()));
- TransitionTo(RESUMING_INTERNAL, DONT_UPDATE_OBSERVERS);
+ TransitionTo(RESUMING_INTERNAL);
delegate_->ResumeInterruptedDownload(std::move(download_params), GetId());
// Just in case we were interrupted while paused.
is_paused_ = false;
@@ -1820,6 +1862,7 @@ DownloadItem::DownloadState DownloadItemImpl::InternalToExternalState(
case INITIAL_INTERNAL:
case TARGET_PENDING_INTERNAL:
case TARGET_RESOLVED_INTERNAL:
+ case INTERRUPTED_TARGET_PENDING_INTERNAL:
// TODO(asanka): Introduce an externally visible state to distinguish
// between the above states and IN_PROGRESS_INTERNAL. The latter (the
// state where the download is active and has a known target) is the state
@@ -1870,6 +1913,7 @@ bool DownloadItemImpl::IsValidSavePackageStateTransition(
switch (from) {
case INITIAL_INTERNAL:
case TARGET_PENDING_INTERNAL:
+ case INTERRUPTED_TARGET_PENDING_INTERNAL:
case TARGET_RESOLVED_INTERNAL:
case COMPLETING_INTERNAL:
case COMPLETE_INTERNAL:
@@ -1896,10 +1940,15 @@ bool DownloadItemImpl::IsValidStateTransition(DownloadInternalState from,
#if DCHECK_IS_ON()
switch (from) {
case INITIAL_INTERNAL:
- return to == TARGET_PENDING_INTERNAL || to == INTERRUPTED_INTERNAL;
+ return to == TARGET_PENDING_INTERNAL ||
+ to == INTERRUPTED_TARGET_PENDING_INTERNAL;
case TARGET_PENDING_INTERNAL:
- return to == TARGET_RESOLVED_INTERNAL || to == CANCELLED_INTERNAL;
+ return to == INTERRUPTED_TARGET_PENDING_INTERNAL ||
+ to == TARGET_RESOLVED_INTERNAL || to == CANCELLED_INTERNAL;
+
+ case INTERRUPTED_TARGET_PENDING_INTERNAL:
+ return to == INTERRUPTED_INTERNAL || to == CANCELLED_INTERNAL;
case TARGET_RESOLVED_INTERNAL:
return to == IN_PROGRESS_INTERNAL || to == INTERRUPTED_INTERNAL ||
@@ -1919,7 +1968,9 @@ bool DownloadItemImpl::IsValidStateTransition(DownloadInternalState from,
return to == RESUMING_INTERNAL || to == CANCELLED_INTERNAL;
case RESUMING_INTERNAL:
- return to == TARGET_PENDING_INTERNAL || to == CANCELLED_INTERNAL;
+ return to == TARGET_PENDING_INTERNAL ||
+ to == INTERRUPTED_TARGET_PENDING_INTERNAL ||
+ to == TARGET_RESOLVED_INTERNAL || to == CANCELLED_INTERNAL;
case CANCELLED_INTERNAL:
return false;
@@ -1940,6 +1991,8 @@ const char* DownloadItemImpl::DebugDownloadStateString(
return "INITIAL";
case TARGET_PENDING_INTERNAL:
return "TARGET_PENDING";
+ case INTERRUPTED_TARGET_PENDING_INTERNAL:
+ return "INTERRUPTED_TARGET_PENDING";
case TARGET_RESOLVED_INTERNAL:
return "TARGET_RESOLVED";
case IN_PROGRESS_INTERNAL:
« no previous file with comments | « content/browser/download/download_item_impl.h ('k') | content/browser/download/download_item_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698