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

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

Issue 14955002: [Resumption 6/11] Add a RESUMING_INTERNAL state to DownloadItem. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 7 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 fa530c8d98abbf5b7b8276963796b43a39d71396..b4a8e042d0f9246fbd9fcdf322882e6577e59a35 100644
--- a/content/browser/download/download_item_impl.cc
+++ b/content/browser/download/download_item_impl.cc
@@ -309,33 +309,39 @@ void DownloadItemImpl::Pause() {
void DownloadItemImpl::Resume() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ switch (state_) {
+ case IN_PROGRESS_INTERNAL:
+ if (!is_paused_)
+ return;
+ request_handle_->ResumeRequest();
+ is_paused_ = false;
+ UpdateObservers();
+ return;
- // Ignore irrelevant states.
- if (state_ == COMPLETE_INTERNAL ||
- state_ == COMPLETING_INTERNAL ||
- state_ == CANCELLED_INTERNAL ||
- (state_ == IN_PROGRESS_INTERNAL && !is_paused_))
- return;
+ case COMPLETING_INTERNAL:
+ case COMPLETE_INTERNAL:
+ case CANCELLED_INTERNAL:
+ case RESUMING_INTERNAL:
+ return;
- if (state_ == INTERRUPTED_INTERNAL) {
- auto_resume_count_ = 0; // User input resets the counter.
- ResumeInterruptedDownload();
- return;
- }
- DCHECK_EQ(IN_PROGRESS_INTERNAL, state_);
+ case INTERRUPTED_INTERNAL:
+ auto_resume_count_ = 0; // User input resets the counter.
+ ResumeInterruptedDownload();
+ return;
- request_handle_->ResumeRequest();
- is_paused_ = false;
- UpdateObservers();
+ case MAX_DOWNLOAD_INTERNAL_STATE:
+ NOTREACHED();
+ }
}
void DownloadItemImpl::Cancel(bool user_cancel) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
VLOG(20) << __FUNCTION__ << "() download = " << DebugString(true);
- if (state_ != IN_PROGRESS_INTERNAL && state_ != INTERRUPTED_INTERNAL) {
- // Small downloads might be complete before this method has
- // a chance to run.
+ if (state_ != IN_PROGRESS_INTERNAL &&
+ state_ != INTERRUPTED_INTERNAL &&
+ state_ != RESUMING_INTERNAL) {
+ // Small downloads might be complete before this method has a chance to run.
return;
}
@@ -352,7 +358,7 @@ void DownloadItemImpl::Cancel(bool user_cancel) {
if (!is_save_package_download_ && download_file_)
ReleaseDownloadFile(true);
- if (state_ != INTERRUPTED_INTERNAL) {
+ if (state_ == IN_PROGRESS_INTERNAL) {
// Cancel the originating URL request unless it's already been cancelled
// by interrupt.
request_handle_->CancelRequest();
@@ -1048,6 +1054,14 @@ void DownloadItemImpl::Start(
download_file_ = file.Pass();
request_handle_ = req_handle.Pass();
+ if (IsCancelled()) {
+ // The download was in the process of resuming when it was cancelled. Don't
+ // proceed.
+ ReleaseDownloadFile(true);
+ request_handle_->CancelRequest();
Randy Smith (Not in Mondays) 2013/05/09 01:00:57 Is there a reason to do this here, rather than abo
asanka 2013/05/09 16:54:33 I may be misreading this comment. The code is try
Randy Smith (Not in Mondays) 2013/05/10 15:00:30 Whoops; the key thing I was spacing on was the las
+ return;
+ }
+
TransitionTo(IN_PROGRESS_INTERNAL);
last_reason_ = DOWNLOAD_INTERRUPT_REASON_NONE;
@@ -1331,6 +1345,25 @@ void DownloadItemImpl::Completed() {
}
}
+void DownloadItemImpl::OnResumeRequestStarted(DownloadItem* item,
+ net::Error error) {
+ // If |item| is not NULL, then Start() has been called already, and nothing
+ // more needs to be done here.
+ if (item) {
+ DCHECK_EQ(net::OK, error);
+ DCHECK_EQ(static_cast<DownloadItem*>(this), item);
+ return;
+ }
+ // Otherwise, the request failed without passing through
+ // DownloadResourceHandler::OnResponseStarted.
+ if (error == net::OK)
+ error = net::ERR_FAILED;
+ DownloadInterruptReason reason =
+ ConvertNetErrorToInterruptReason(error, DOWNLOAD_INTERRUPT_FROM_NETWORK);
+ DCHECK_NE(DOWNLOAD_INTERRUPT_REASON_NONE, reason);
+ Interrupt(reason);
+}
+
// **** End of Download progression cascade
// An error occurred somewhere.
@@ -1347,7 +1380,7 @@ void DownloadItemImpl::Interrupt(DownloadInterruptReason reason) {
// interrupts to race with cancels.
// Whatever happens, the first one to hit the UI thread wins.
- if (state_ != IN_PROGRESS_INTERNAL)
+ if (state_ != IN_PROGRESS_INTERNAL && state_ != RESUMING_INTERNAL)
Randy Smith (Not in Mondays) 2013/05/09 01:00:57 Why should an interrupt fail in RESUMING_INTERNAL
asanka 2013/05/09 16:54:33 RESUMING_INTERNAL -> INTERRUPTED_INTERNAL happens
Randy Smith (Not in Mondays) 2013/05/10 15:00:30 Got it. It was interrupts happening before we got
return;
last_reason_ = reason;
@@ -1560,7 +1593,7 @@ void DownloadItemImpl::ResumeInterruptedDownload() {
return;
// If we're not interrupted, ignore the request; our caller is drunk.
- if (!IsInterrupted())
+ if (state_ != INTERRUPTED_INTERNAL)
return;
// If we can't get a web contents, we can't resume the download.
@@ -1589,11 +1622,15 @@ void DownloadItemImpl::ResumeInterruptedDownload() {
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()));
delegate_->ResumeInterruptedDownload(download_params.Pass(), GetGlobalId());
-
// Just in case we were interrupted while paused.
is_paused_ = false;
+
+ TransitionTo(RESUMING_INTERNAL);
}
// static
@@ -1610,29 +1647,32 @@ DownloadItem::DownloadState DownloadItemImpl::InternalToExternalState(
return CANCELLED;
case INTERRUPTED_INTERNAL:
return INTERRUPTED;
- default:
- NOTREACHED();
+ case RESUMING_INTERNAL:
+ return INTERRUPTED;
+ case MAX_DOWNLOAD_INTERNAL_STATE:
+ break;
}
+ NOTREACHED();
return MAX_DOWNLOAD_STATE;
}
// static
DownloadItemImpl::DownloadInternalState
DownloadItemImpl::ExternalToInternalState(
- DownloadState external_state) {
- switch (external_state) {
- case IN_PROGRESS:
- return IN_PROGRESS_INTERNAL;
- case COMPLETE:
- return COMPLETE_INTERNAL;
- case CANCELLED:
- return CANCELLED_INTERNAL;
- case INTERRUPTED:
- return INTERRUPTED_INTERNAL;
- default:
- NOTREACHED();
- }
- return MAX_DOWNLOAD_INTERNAL_STATE;
+ DownloadState external_state) {
+ switch (external_state) {
+ case IN_PROGRESS:
+ return IN_PROGRESS_INTERNAL;
+ case COMPLETE:
+ return COMPLETE_INTERNAL;
+ case CANCELLED:
+ return CANCELLED_INTERNAL;
+ case INTERRUPTED:
+ return INTERRUPTED_INTERNAL;
+ default:
+ NOTREACHED();
+ }
+ return MAX_DOWNLOAD_INTERNAL_STATE;
}
benjhayden 2013/05/09 14:49:51 Thanks for fixing the above lines, please also ded
asanka 2013/05/09 16:54:33 Ah thanks! Missed that one.
const char* DownloadItemImpl::DebugDownloadStateString(
@@ -1648,10 +1688,13 @@ const char* DownloadItemImpl::DebugDownloadStateString(
return "CANCELLED";
case INTERRUPTED_INTERNAL:
return "INTERRUPTED";
- default:
- NOTREACHED() << "Unknown download state " << state;
- return "unknown";
+ case RESUMING_INTERNAL:
+ return "RESUMING";
+ case MAX_DOWNLOAD_INTERNAL_STATE:
+ break;
};
+ NOTREACHED() << "Unknown download state " << state;
+ return "unknown";
}
const char* DownloadItemImpl::DebugResumeModeString(ResumeMode mode) {

Powered by Google App Engine
This is Rietveld 408576698