Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // File method ordering: Methods in this file are in the same order as | 5 // File method ordering: Methods in this file are in the same order as |
| 6 // in download_item_impl.h, with the following exception: The public | 6 // in download_item_impl.h, with the following exception: The public |
| 7 // interface Start is placed in chronological order with the other | 7 // interface Start is placed in chronological order with the other |
| 8 // (private) routines that together define a DownloadItem's state | 8 // (private) routines that together define a DownloadItem's state |
| 9 // transitions as the download progresses. See "Download progression | 9 // transitions as the download progresses. See "Download progression |
| 10 // cascade" later in this file. | 10 // cascade" later in this file. |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 31 #include "base/format_macros.h" | 31 #include "base/format_macros.h" |
| 32 #include "base/logging.h" | 32 #include "base/logging.h" |
| 33 #include "base/metrics/histogram.h" | 33 #include "base/metrics/histogram.h" |
| 34 #include "base/stl_util.h" | 34 #include "base/stl_util.h" |
| 35 #include "base/strings/stringprintf.h" | 35 #include "base/strings/stringprintf.h" |
| 36 #include "base/strings/utf_string_conversions.h" | 36 #include "base/strings/utf_string_conversions.h" |
| 37 #include "content/browser/download/download_create_info.h" | 37 #include "content/browser/download/download_create_info.h" |
| 38 #include "content/browser/download/download_file.h" | 38 #include "content/browser/download/download_file.h" |
| 39 #include "content/browser/download/download_interrupt_reasons_impl.h" | 39 #include "content/browser/download/download_interrupt_reasons_impl.h" |
| 40 #include "content/browser/download/download_item_impl_delegate.h" | 40 #include "content/browser/download/download_item_impl_delegate.h" |
| 41 #include "content/browser/download/download_net_log_parameters.h" | |
| 41 #include "content/browser/download/download_request_handle.h" | 42 #include "content/browser/download/download_request_handle.h" |
| 42 #include "content/browser/download/download_stats.h" | 43 #include "content/browser/download/download_stats.h" |
| 43 #include "content/browser/renderer_host/render_view_host_impl.h" | 44 #include "content/browser/renderer_host/render_view_host_impl.h" |
| 44 #include "content/browser/web_contents/web_contents_impl.h" | 45 #include "content/browser/web_contents/web_contents_impl.h" |
| 45 #include "content/public/browser/browser_context.h" | 46 #include "content/public/browser/browser_context.h" |
| 46 #include "content/public/browser/browser_thread.h" | 47 #include "content/public/browser/browser_thread.h" |
| 47 #include "content/public/browser/content_browser_client.h" | 48 #include "content/public/browser/content_browser_client.h" |
| 48 #include "content/public/browser/download_danger_type.h" | 49 #include "content/public/browser/download_danger_type.h" |
| 49 #include "content/public/browser/download_interrupt_reasons.h" | 50 #include "content/public/browser/download_interrupt_reasons.h" |
| 50 #include "content/public/browser/download_url_parameters.h" | 51 #include "content/public/browser/download_url_parameters.h" |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 91 } | 92 } |
| 92 | 93 |
| 93 bool IsDownloadResumptionEnabled() { | 94 bool IsDownloadResumptionEnabled() { |
| 94 return base::FeatureList::IsEnabled(features::kDownloadResumption); | 95 return base::FeatureList::IsEnabled(features::kDownloadResumption); |
| 95 } | 96 } |
| 96 | 97 |
| 97 } // namespace | 98 } // namespace |
| 98 | 99 |
| 99 const uint32_t DownloadItem::kInvalidId = 0; | 100 const uint32_t DownloadItem::kInvalidId = 0; |
| 100 | 101 |
| 101 const char DownloadItem::kEmptyFileHash[] = ""; | |
| 102 | |
| 103 // The maximum number of attempts we will make to resume automatically. | 102 // The maximum number of attempts we will make to resume automatically. |
| 104 const int DownloadItemImpl::kMaxAutoResumeAttempts = 5; | 103 const int DownloadItemImpl::kMaxAutoResumeAttempts = 5; |
| 105 | 104 |
| 106 // Constructor for reading from the history service. | 105 // Constructor for reading from the history service. |
| 107 DownloadItemImpl::DownloadItemImpl(DownloadItemImplDelegate* delegate, | 106 DownloadItemImpl::DownloadItemImpl(DownloadItemImplDelegate* delegate, |
| 108 uint32_t download_id, | 107 uint32_t download_id, |
| 109 const base::FilePath& current_path, | 108 const base::FilePath& current_path, |
| 110 const base::FilePath& target_path, | 109 const base::FilePath& target_path, |
| 111 const std::vector<GURL>& url_chain, | 110 const std::vector<GURL>& url_chain, |
| 112 const GURL& referrer_url, | 111 const GURL& referrer_url, |
| 113 const std::string& mime_type, | 112 const std::string& mime_type, |
| 114 const std::string& original_mime_type, | 113 const std::string& original_mime_type, |
| 115 const base::Time& start_time, | 114 const base::Time& start_time, |
| 116 const base::Time& end_time, | 115 const base::Time& end_time, |
| 117 const std::string& etag, | 116 const std::string& etag, |
| 118 const std::string& last_modified, | 117 const std::string& last_modified, |
| 119 int64_t received_bytes, | 118 int64_t received_bytes, |
| 120 int64_t total_bytes, | 119 int64_t total_bytes, |
| 120 const std::string& hash, | |
| 121 DownloadItem::DownloadState state, | 121 DownloadItem::DownloadState state, |
| 122 DownloadDangerType danger_type, | 122 DownloadDangerType danger_type, |
| 123 DownloadInterruptReason interrupt_reason, | 123 DownloadInterruptReason interrupt_reason, |
| 124 bool opened, | 124 bool opened, |
| 125 const net::BoundNetLog& bound_net_log) | 125 const net::BoundNetLog& bound_net_log) |
| 126 : download_id_(download_id), | 126 : download_id_(download_id), |
| 127 current_path_(current_path), | |
| 128 target_path_(target_path), | 127 target_path_(target_path), |
| 129 url_chain_(url_chain), | 128 url_chain_(url_chain), |
| 130 referrer_url_(referrer_url), | 129 referrer_url_(referrer_url), |
| 131 mime_type_(mime_type), | 130 mime_type_(mime_type), |
| 132 original_mime_type_(original_mime_type), | 131 original_mime_type_(original_mime_type), |
| 133 total_bytes_(total_bytes), | 132 total_bytes_(total_bytes), |
| 134 received_bytes_(received_bytes), | |
| 135 last_modified_time_(last_modified), | |
| 136 etag_(etag), | |
| 137 last_reason_(interrupt_reason), | 133 last_reason_(interrupt_reason), |
| 138 start_tick_(base::TimeTicks()), | 134 start_tick_(base::TimeTicks()), |
| 139 state_(ExternalToInternalState(state)), | 135 state_(ExternalToInternalState(state)), |
| 140 danger_type_(danger_type), | 136 danger_type_(danger_type), |
| 141 start_time_(start_time), | 137 start_time_(start_time), |
| 142 end_time_(end_time), | 138 end_time_(end_time), |
| 143 delegate_(delegate), | 139 delegate_(delegate), |
| 140 opened_(opened), | |
| 141 current_path_(current_path), | |
| 142 received_bytes_(received_bytes), | |
| 144 all_data_saved_(state == COMPLETE), | 143 all_data_saved_(state == COMPLETE), |
| 145 opened_(opened), | 144 hash_(hash), |
| 145 last_modified_time_(last_modified), | |
| 146 etag_(etag), | |
| 146 bound_net_log_(bound_net_log), | 147 bound_net_log_(bound_net_log), |
| 147 weak_ptr_factory_(this) { | 148 weak_ptr_factory_(this) { |
| 148 delegate_->Attach(); | 149 delegate_->Attach(); |
| 149 DCHECK(state_ == COMPLETE_INTERNAL || state_ == INTERRUPTED_INTERNAL || | 150 DCHECK(state_ == COMPLETE_INTERNAL || state_ == INTERRUPTED_INTERNAL || |
| 150 state_ == CANCELLED_INTERNAL); | 151 state_ == CANCELLED_INTERNAL); |
| 151 Init(false /* not actively downloading */, SRC_HISTORY_IMPORT); | 152 Init(false /* not actively downloading */, SRC_HISTORY_IMPORT); |
| 152 } | 153 } |
| 153 | 154 |
| 154 // Constructing for a regular download: | 155 // Constructing for a regular download: |
| 155 DownloadItemImpl::DownloadItemImpl(DownloadItemImplDelegate* delegate, | 156 DownloadItemImpl::DownloadItemImpl(DownloadItemImplDelegate* delegate, |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 166 tab_referrer_url_(info.tab_referrer_url), | 167 tab_referrer_url_(info.tab_referrer_url), |
| 167 suggested_filename_(base::UTF16ToUTF8(info.save_info->suggested_name)), | 168 suggested_filename_(base::UTF16ToUTF8(info.save_info->suggested_name)), |
| 168 forced_file_path_(info.save_info->file_path), | 169 forced_file_path_(info.save_info->file_path), |
| 169 transition_type_(info.transition_type), | 170 transition_type_(info.transition_type), |
| 170 has_user_gesture_(info.has_user_gesture), | 171 has_user_gesture_(info.has_user_gesture), |
| 171 content_disposition_(info.content_disposition), | 172 content_disposition_(info.content_disposition), |
| 172 mime_type_(info.mime_type), | 173 mime_type_(info.mime_type), |
| 173 original_mime_type_(info.original_mime_type), | 174 original_mime_type_(info.original_mime_type), |
| 174 remote_address_(info.remote_address), | 175 remote_address_(info.remote_address), |
| 175 total_bytes_(info.total_bytes), | 176 total_bytes_(info.total_bytes), |
| 176 last_modified_time_(info.last_modified), | |
| 177 etag_(info.etag), | |
| 178 last_reason_(info.result), | 177 last_reason_(info.result), |
| 179 start_tick_(base::TimeTicks::Now()), | 178 start_tick_(base::TimeTicks::Now()), |
| 180 state_(INITIAL_INTERNAL), | 179 state_(INITIAL_INTERNAL), |
| 181 start_time_(info.start_time), | 180 start_time_(info.start_time), |
| 182 delegate_(delegate), | 181 delegate_(delegate), |
| 183 is_temporary_(!info.save_info->file_path.empty()), | 182 is_temporary_(!info.save_info->file_path.empty()), |
| 183 last_modified_time_(info.last_modified), | |
| 184 etag_(info.etag), | |
| 184 bound_net_log_(bound_net_log), | 185 bound_net_log_(bound_net_log), |
| 185 weak_ptr_factory_(this) { | 186 weak_ptr_factory_(this) { |
| 186 delegate_->Attach(); | 187 delegate_->Attach(); |
| 187 Init(true /* actively downloading */, SRC_ACTIVE_DOWNLOAD); | 188 Init(true /* actively downloading */, SRC_ACTIVE_DOWNLOAD); |
| 188 | 189 |
| 189 // Link the event sources. | 190 // Link the event sources. |
| 190 bound_net_log_.AddEvent( | 191 bound_net_log_.AddEvent( |
| 191 net::NetLog::TYPE_DOWNLOAD_URL_REQUEST, | 192 net::NetLog::TYPE_DOWNLOAD_URL_REQUEST, |
| 192 info.request_bound_net_log.source().ToEventParametersCallback()); | 193 info.request_bound_net_log.source().ToEventParametersCallback()); |
| 193 | 194 |
| 194 info.request_bound_net_log.AddEvent( | 195 info.request_bound_net_log.AddEvent( |
| 195 net::NetLog::TYPE_DOWNLOAD_STARTED, | 196 net::NetLog::TYPE_DOWNLOAD_STARTED, |
| 196 bound_net_log_.source().ToEventParametersCallback()); | 197 bound_net_log_.source().ToEventParametersCallback()); |
| 197 } | 198 } |
| 198 | 199 |
| 199 // Constructing for the "Save Page As..." feature: | 200 // Constructing for the "Save Page As..." feature: |
| 200 DownloadItemImpl::DownloadItemImpl( | 201 DownloadItemImpl::DownloadItemImpl( |
| 201 DownloadItemImplDelegate* delegate, | 202 DownloadItemImplDelegate* delegate, |
| 202 uint32_t download_id, | 203 uint32_t download_id, |
| 203 const base::FilePath& path, | 204 const base::FilePath& path, |
| 204 const GURL& url, | 205 const GURL& url, |
| 205 const std::string& mime_type, | 206 const std::string& mime_type, |
| 206 scoped_ptr<DownloadRequestHandleInterface> request_handle, | 207 scoped_ptr<DownloadRequestHandleInterface> request_handle, |
| 207 const net::BoundNetLog& bound_net_log) | 208 const net::BoundNetLog& bound_net_log) |
| 208 : is_save_package_download_(true), | 209 : is_save_package_download_(true), |
| 209 request_handle_(std::move(request_handle)), | 210 request_handle_(std::move(request_handle)), |
| 210 download_id_(download_id), | 211 download_id_(download_id), |
| 211 current_path_(path), | |
| 212 target_path_(path), | 212 target_path_(path), |
| 213 url_chain_(1, url), | 213 url_chain_(1, url), |
| 214 mime_type_(mime_type), | 214 mime_type_(mime_type), |
| 215 original_mime_type_(mime_type), | 215 original_mime_type_(mime_type), |
| 216 start_tick_(base::TimeTicks::Now()), | 216 start_tick_(base::TimeTicks::Now()), |
| 217 state_(IN_PROGRESS_INTERNAL), | 217 state_(IN_PROGRESS_INTERNAL), |
| 218 start_time_(base::Time::Now()), | 218 start_time_(base::Time::Now()), |
| 219 delegate_(delegate), | 219 delegate_(delegate), |
| 220 current_path_(path), | |
| 220 bound_net_log_(bound_net_log), | 221 bound_net_log_(bound_net_log), |
| 221 weak_ptr_factory_(this) { | 222 weak_ptr_factory_(this) { |
| 222 delegate_->Attach(); | 223 delegate_->Attach(); |
| 223 Init(true /* actively downloading */, SRC_SAVE_PAGE_AS); | 224 Init(true /* actively downloading */, SRC_SAVE_PAGE_AS); |
| 224 } | 225 } |
| 225 | 226 |
| 226 DownloadItemImpl::~DownloadItemImpl() { | 227 DownloadItemImpl::~DownloadItemImpl() { |
| 227 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 228 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 228 | 229 |
| 229 // Should always have been nuked before now, at worst in | 230 // Should always have been nuked before now, at worst in |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 364 | 365 |
| 365 case MAX_DOWNLOAD_INTERNAL_STATE: | 366 case MAX_DOWNLOAD_INTERNAL_STATE: |
| 366 case TARGET_RESOLVED_INTERNAL: | 367 case TARGET_RESOLVED_INTERNAL: |
| 367 NOTREACHED(); | 368 NOTREACHED(); |
| 368 } | 369 } |
| 369 } | 370 } |
| 370 | 371 |
| 371 void DownloadItemImpl::Cancel(bool user_cancel) { | 372 void DownloadItemImpl::Cancel(bool user_cancel) { |
| 372 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 373 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 373 DVLOG(20) << __FUNCTION__ << "() download = " << DebugString(true); | 374 DVLOG(20) << __FUNCTION__ << "() download = " << DebugString(true); |
| 374 Interrupt(user_cancel ? DOWNLOAD_INTERRUPT_REASON_USER_CANCELED | 375 InterruptAndDiscardPartialState( |
| 375 : DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN); | 376 user_cancel ? DOWNLOAD_INTERRUPT_REASON_USER_CANCELED |
| 377 : DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN); | |
| 376 UpdateObservers(); | 378 UpdateObservers(); |
| 377 } | 379 } |
| 378 | 380 |
| 379 void DownloadItemImpl::Remove() { | 381 void DownloadItemImpl::Remove() { |
| 380 DVLOG(20) << __FUNCTION__ << "() download = " << DebugString(true); | 382 DVLOG(20) << __FUNCTION__ << "() download = " << DebugString(true); |
| 381 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 383 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 382 | 384 |
| 383 delegate_->AssertStateConsistent(this); | 385 delegate_->AssertStateConsistent(this); |
| 384 Interrupt(DOWNLOAD_INTERRUPT_REASON_USER_CANCELED); | 386 InterruptAndDiscardPartialState(DOWNLOAD_INTERRUPT_REASON_USER_CANCELED); |
| 385 UpdateObservers(); | 387 UpdateObservers(); |
| 386 delegate_->AssertStateConsistent(this); | 388 delegate_->AssertStateConsistent(this); |
| 387 | 389 |
| 388 NotifyRemoved(); | 390 NotifyRemoved(); |
| 389 delegate_->DownloadRemoved(this); | 391 delegate_->DownloadRemoved(this); |
| 390 // We have now been deleted. | 392 // We have now been deleted. |
| 391 } | 393 } |
| 392 | 394 |
| 393 void DownloadItemImpl::OpenDownload() { | 395 void DownloadItemImpl::OpenDownload() { |
| 394 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 396 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 583 } | 585 } |
| 584 | 586 |
| 585 DownloadItem::TargetDisposition DownloadItemImpl::GetTargetDisposition() const { | 587 DownloadItem::TargetDisposition DownloadItemImpl::GetTargetDisposition() const { |
| 586 return target_disposition_; | 588 return target_disposition_; |
| 587 } | 589 } |
| 588 | 590 |
| 589 const std::string& DownloadItemImpl::GetHash() const { | 591 const std::string& DownloadItemImpl::GetHash() const { |
| 590 return hash_; | 592 return hash_; |
| 591 } | 593 } |
| 592 | 594 |
| 593 const std::string& DownloadItemImpl::GetHashState() const { | |
| 594 return hash_state_; | |
| 595 } | |
| 596 | |
| 597 bool DownloadItemImpl::GetFileExternallyRemoved() const { | 595 bool DownloadItemImpl::GetFileExternallyRemoved() const { |
| 598 return file_externally_removed_; | 596 return file_externally_removed_; |
| 599 } | 597 } |
| 600 | 598 |
| 601 void DownloadItemImpl::DeleteFile(const base::Callback<void(bool)>& callback) { | 599 void DownloadItemImpl::DeleteFile(const base::Callback<void(bool)>& callback) { |
| 602 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 600 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 603 if (GetState() != DownloadItem::COMPLETE) { | 601 if (GetState() != DownloadItem::COMPLETE) { |
| 604 // Pass a null WeakPtr so it doesn't call OnDownloadedFileRemoved. | 602 // Pass a null WeakPtr so it doesn't call OnDownloadedFileRemoved. |
| 605 BrowserThread::PostTask( | 603 BrowserThread::PostTask( |
| 606 BrowserThread::UI, FROM_HERE, | 604 BrowserThread::UI, FROM_HERE, |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 778 ++iter; | 776 ++iter; |
| 779 for ( ; verbose && (iter != last); ++iter) { | 777 for ( ; verbose && (iter != last); ++iter) { |
| 780 url_list += " ->\n\t"; | 778 url_list += " ->\n\t"; |
| 781 const GURL& next_url = *iter; | 779 const GURL& next_url = *iter; |
| 782 url_list += next_url.is_valid() ? next_url.spec() : "<invalid>"; | 780 url_list += next_url.is_valid() ? next_url.spec() : "<invalid>"; |
| 783 } | 781 } |
| 784 } | 782 } |
| 785 | 783 |
| 786 if (verbose) { | 784 if (verbose) { |
| 787 description += base::StringPrintf( | 785 description += base::StringPrintf( |
| 788 " total = %" PRId64 | 786 " total = %" PRId64 " received = %" PRId64 |
| 789 " received = %" PRId64 | |
| 790 " reason = %s" | 787 " reason = %s" |
| 791 " paused = %c" | 788 " paused = %c" |
| 792 " resume_mode = %s" | 789 " resume_mode = %s" |
| 793 " auto_resume_count = %d" | 790 " auto_resume_count = %d" |
| 794 " danger = %d" | 791 " danger = %d" |
| 795 " all_data_saved = %c" | 792 " all_data_saved = %c" |
| 796 " last_modified = '%s'" | 793 " last_modified = '%s'" |
| 797 " etag = '%s'" | 794 " etag = '%s'" |
| 798 " has_download_file = %s" | 795 " has_download_file = %s" |
| 799 " url_chain = \n\t\"%s\"\n\t" | 796 " url_chain = \n\t\"%s\"\n\t" |
| 800 " full_path = \"%" PRFilePath "\"\n\t" | 797 " current_path = \"%" PRFilePath |
| 798 "\"\n\t" | |
| 801 " target_path = \"%" PRFilePath "\"", | 799 " target_path = \"%" PRFilePath "\"", |
| 802 GetTotalBytes(), | 800 GetTotalBytes(), GetReceivedBytes(), |
| 803 GetReceivedBytes(), | |
| 804 DownloadInterruptReasonToString(last_reason_).c_str(), | 801 DownloadInterruptReasonToString(last_reason_).c_str(), |
| 805 IsPaused() ? 'T' : 'F', | 802 IsPaused() ? 'T' : 'F', DebugResumeModeString(GetResumeMode()), |
| 806 DebugResumeModeString(GetResumeMode()), | 803 auto_resume_count_, GetDangerType(), AllDataSaved() ? 'T' : 'F', |
| 807 auto_resume_count_, | 804 GetLastModifiedTime().c_str(), GetETag().c_str(), |
| 808 GetDangerType(), | 805 download_file_.get() ? "true" : "false", url_list.c_str(), |
| 809 AllDataSaved() ? 'T' : 'F', | 806 GetFullPath().value().c_str(), GetTargetFilePath().value().c_str()); |
| 810 GetLastModifiedTime().c_str(), | |
| 811 GetETag().c_str(), | |
| 812 download_file_.get() ? "true" : "false", | |
| 813 url_list.c_str(), | |
| 814 GetFullPath().value().c_str(), | |
| 815 GetTargetFilePath().value().c_str()); | |
| 816 } else { | 807 } else { |
| 817 description += base::StringPrintf(" url = \"%s\"", url_list.c_str()); | 808 description += base::StringPrintf(" url = \"%s\"", url_list.c_str()); |
| 818 } | 809 } |
| 819 | 810 |
| 820 description += " }"; | 811 description += " }"; |
| 821 | 812 |
| 822 return description; | 813 return description; |
| 823 } | 814 } |
| 824 | 815 |
| 825 DownloadItemImpl::ResumeMode DownloadItemImpl::GetResumeMode() const { | 816 DownloadItemImpl::ResumeMode DownloadItemImpl::GetResumeMode() const { |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 844 (auto_resume_count_ >= kMaxAutoResumeAttempts || is_paused_); | 835 (auto_resume_count_ >= kMaxAutoResumeAttempts || is_paused_); |
| 845 | 836 |
| 846 switch(last_reason_) { | 837 switch(last_reason_) { |
| 847 case DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR: | 838 case DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR: |
| 848 case DOWNLOAD_INTERRUPT_REASON_NETWORK_TIMEOUT: | 839 case DOWNLOAD_INTERRUPT_REASON_NETWORK_TIMEOUT: |
| 849 break; | 840 break; |
| 850 | 841 |
| 851 case DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE: | 842 case DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE: |
| 852 // The server disagreed with the file offset that we sent. | 843 // The server disagreed with the file offset that we sent. |
| 853 | 844 |
| 845 case DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH: | |
| 846 // The file on disk was found to not match the expected hash. Discard and | |
| 847 // start from beginning. | |
| 848 | |
| 854 case DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT: | 849 case DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT: |
| 855 // The [possibly persisted] file offset disagreed with the file on disk. | 850 // The [possibly persisted] file offset disagreed with the file on disk. |
| 856 | 851 |
| 857 // The intermediate stub is not usable and the server is resonding. Hence | 852 // The intermediate stub is not usable and the server is responding. Hence |
| 858 // retrying the request from the beginning is likely to work. | 853 // retrying the request from the beginning is likely to work. |
| 859 restart_required = true; | 854 restart_required = true; |
| 860 break; | 855 break; |
| 861 | 856 |
| 862 case DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED: | 857 case DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED: |
| 863 case DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED: | 858 case DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED: |
| 864 case DOWNLOAD_INTERRUPT_REASON_NETWORK_SERVER_DOWN: | 859 case DOWNLOAD_INTERRUPT_REASON_NETWORK_SERVER_DOWN: |
| 865 case DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED: | 860 case DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED: |
| 866 case DOWNLOAD_INTERRUPT_REASON_SERVER_UNREACHABLE: | 861 case DOWNLOAD_INTERRUPT_REASON_SERVER_UNREACHABLE: |
| 867 case DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN: | 862 case DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN: |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 939 // HTTP_PRECONDITION_FAILED), then the download will automatically retried as | 934 // HTTP_PRECONDITION_FAILED), then the download will automatically retried as |
| 940 // a full request rather than a partial. Full restarts clobber validators. | 935 // a full request rather than a partial. Full restarts clobber validators. |
| 941 int origin_state = 0; | 936 int origin_state = 0; |
| 942 if (chain_iter != new_create_info.url_chain.end()) | 937 if (chain_iter != new_create_info.url_chain.end()) |
| 943 origin_state |= ORIGIN_STATE_ON_RESUMPTION_ADDITIONAL_REDIRECTS; | 938 origin_state |= ORIGIN_STATE_ON_RESUMPTION_ADDITIONAL_REDIRECTS; |
| 944 if (etag_ != new_create_info.etag || | 939 if (etag_ != new_create_info.etag || |
| 945 last_modified_time_ != new_create_info.last_modified) | 940 last_modified_time_ != new_create_info.last_modified) |
| 946 origin_state |= ORIGIN_STATE_ON_RESUMPTION_VALIDATORS_CHANGED; | 941 origin_state |= ORIGIN_STATE_ON_RESUMPTION_VALIDATORS_CHANGED; |
| 947 if (content_disposition_ != new_create_info.content_disposition) | 942 if (content_disposition_ != new_create_info.content_disposition) |
| 948 origin_state |= ORIGIN_STATE_ON_RESUMPTION_CONTENT_DISPOSITION_CHANGED; | 943 origin_state |= ORIGIN_STATE_ON_RESUMPTION_CONTENT_DISPOSITION_CHANGED; |
| 949 RecordOriginStateOnResumption(new_create_info.save_info->offset != 0, | 944 RecordOriginStateOnResumption(received_bytes_ != 0, origin_state); |
| 950 origin_state); | |
| 951 | 945 |
| 952 url_chain_.insert( | 946 url_chain_.insert( |
| 953 url_chain_.end(), chain_iter, new_create_info.url_chain.end()); | 947 url_chain_.end(), chain_iter, new_create_info.url_chain.end()); |
| 954 etag_ = new_create_info.etag; | 948 etag_ = new_create_info.etag; |
| 955 last_modified_time_ = new_create_info.last_modified; | 949 last_modified_time_ = new_create_info.last_modified; |
| 956 content_disposition_ = new_create_info.content_disposition; | 950 content_disposition_ = new_create_info.content_disposition; |
| 957 | 951 |
| 958 // Don't update observers. This method is expected to be called just before a | 952 // Don't update observers. This method is expected to be called just before a |
| 959 // DownloadFile is created and Start() is called. The observers will be | 953 // DownloadFile is created and Start() is called. The observers will be |
| 960 // notified when the download transitions to the IN_PROGRESS state. | 954 // notified when the download transitions to the IN_PROGRESS state. |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 976 } | 970 } |
| 977 | 971 |
| 978 const net::BoundNetLog& DownloadItemImpl::GetBoundNetLog() const { | 972 const net::BoundNetLog& DownloadItemImpl::GetBoundNetLog() const { |
| 979 return bound_net_log_; | 973 return bound_net_log_; |
| 980 } | 974 } |
| 981 | 975 |
| 982 void DownloadItemImpl::SetTotalBytes(int64_t total_bytes) { | 976 void DownloadItemImpl::SetTotalBytes(int64_t total_bytes) { |
| 983 total_bytes_ = total_bytes; | 977 total_bytes_ = total_bytes; |
| 984 } | 978 } |
| 985 | 979 |
| 986 void DownloadItemImpl::OnAllDataSaved(const std::string& final_hash) { | 980 void DownloadItemImpl::OnAllDataSaved( |
| 981 int64_t total_bytes, | |
| 982 scoped_ptr<crypto::SecureHash> hash_state) { | |
| 987 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 983 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 988 DCHECK(!all_data_saved_); | 984 DCHECK(!all_data_saved_); |
| 989 all_data_saved_ = true; | 985 all_data_saved_ = true; |
| 986 SetTotalBytes(total_bytes); | |
| 987 UpdateProgress(total_bytes, 0); | |
| 988 hash_state_ = std::move(hash_state); | |
| 989 UpdatePrefixHash(); | |
| 990 hash_state_.reset(); | |
| 991 | |
| 990 DVLOG(20) << __FUNCTION__ << " download=" << DebugString(true); | 992 DVLOG(20) << __FUNCTION__ << " download=" << DebugString(true); |
| 991 | |
| 992 // Store final hash and null out intermediate serialized hash state. | |
| 993 hash_ = final_hash; | |
| 994 hash_state_ = ""; | |
| 995 | |
| 996 UpdateObservers(); | 993 UpdateObservers(); |
| 997 } | 994 } |
| 998 | 995 |
| 999 void DownloadItemImpl::MarkAsComplete() { | 996 void DownloadItemImpl::MarkAsComplete() { |
| 1000 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 997 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1001 | 998 |
| 1002 DCHECK(all_data_saved_); | 999 DCHECK(all_data_saved_); |
| 1003 end_time_ = base::Time::Now(); | 1000 end_time_ = base::Time::Now(); |
| 1004 TransitionTo(COMPLETE_INTERNAL); | 1001 TransitionTo(COMPLETE_INTERNAL); |
| 1005 UpdateObservers(); | 1002 UpdateObservers(); |
| 1006 } | 1003 } |
| 1007 | 1004 |
| 1008 void DownloadItemImpl::DestinationUpdate(int64_t bytes_so_far, | 1005 void DownloadItemImpl::DestinationUpdate(int64_t bytes_so_far, |
| 1009 int64_t bytes_per_sec, | 1006 int64_t bytes_per_sec) { |
| 1010 const std::string& hash_state) { | |
| 1011 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1007 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1012 // If the download is in any other state we don't expect any | 1008 // If the download is in any other state we don't expect any |
| 1013 // DownloadDestinationObserver callbacks. An interruption or a cancellation | 1009 // DownloadDestinationObserver callbacks. An interruption or a cancellation |
| 1014 // results in a call to ReleaseDownloadFile which invalidates the weak | 1010 // results in a call to ReleaseDownloadFile which invalidates the weak |
| 1015 // reference held by the DownloadFile and hence cuts off any pending | 1011 // reference held by the DownloadFile and hence cuts off any pending |
| 1016 // callbacks. | 1012 // callbacks. |
| 1017 DCHECK(state_ == TARGET_PENDING_INTERNAL || state_ == IN_PROGRESS_INTERNAL); | 1013 DCHECK(state_ == TARGET_PENDING_INTERNAL || state_ == IN_PROGRESS_INTERNAL); |
| 1014 | |
| 1015 // There must be no pending destination_error_. | |
| 1016 DCHECK_EQ(destination_error_, DOWNLOAD_INTERRUPT_REASON_NONE); | |
| 1017 | |
| 1018 DVLOG(20) << __FUNCTION__ << " so_far=" << bytes_so_far | 1018 DVLOG(20) << __FUNCTION__ << " so_far=" << bytes_so_far |
| 1019 << " per_sec=" << bytes_per_sec | 1019 << " per_sec=" << bytes_per_sec |
| 1020 << " download=" << DebugString(true); | 1020 << " download=" << DebugString(true); |
| 1021 | 1021 |
| 1022 bytes_per_sec_ = bytes_per_sec; | 1022 UpdateProgress(bytes_so_far, bytes_per_sec); |
| 1023 hash_state_ = hash_state; | |
| 1024 received_bytes_ = bytes_so_far; | |
| 1025 | |
| 1026 // If we've received more data than we were expecting (bad server info?), | |
| 1027 // revert to 'unknown size mode'. | |
| 1028 if (received_bytes_ > total_bytes_) | |
| 1029 total_bytes_ = 0; | |
| 1030 | |
| 1031 if (bound_net_log_.IsCapturing()) { | 1023 if (bound_net_log_.IsCapturing()) { |
| 1032 bound_net_log_.AddEvent( | 1024 bound_net_log_.AddEvent( |
| 1033 net::NetLog::TYPE_DOWNLOAD_ITEM_UPDATED, | 1025 net::NetLog::TYPE_DOWNLOAD_ITEM_UPDATED, |
| 1034 net::NetLog::Int64Callback("bytes_so_far", received_bytes_)); | 1026 net::NetLog::Int64Callback("bytes_so_far", received_bytes_)); |
| 1035 } | 1027 } |
| 1036 | 1028 |
| 1037 UpdateObservers(); | 1029 UpdateObservers(); |
| 1038 } | 1030 } |
| 1039 | 1031 |
| 1040 void DownloadItemImpl::DestinationError(DownloadInterruptReason reason) { | 1032 void DownloadItemImpl::DestinationError( |
| 1033 DownloadInterruptReason reason, | |
| 1034 int64_t bytes_so_far, | |
| 1035 scoped_ptr<crypto::SecureHash> secure_hash) { | |
| 1041 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1036 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1042 // If the download is in any other state we don't expect any | 1037 // If the download is in any other state we don't expect any |
| 1043 // DownloadDestinationObserver callbacks. An interruption or a cancellation | 1038 // DownloadDestinationObserver callbacks. An interruption or a cancellation |
| 1044 // results in a call to ReleaseDownloadFile which invalidates the weak | 1039 // results in a call to ReleaseDownloadFile which invalidates the weak |
| 1045 // reference held by the DownloadFile and hence cuts off any pending | 1040 // reference held by the DownloadFile and hence cuts off any pending |
| 1046 // callbacks. | 1041 // callbacks. |
| 1047 DCHECK(state_ == TARGET_PENDING_INTERNAL || state_ == IN_PROGRESS_INTERNAL); | 1042 DCHECK(state_ == TARGET_PENDING_INTERNAL || state_ == IN_PROGRESS_INTERNAL); |
| 1048 DVLOG(20) << __FUNCTION__ | 1043 DVLOG(20) << __FUNCTION__ |
| 1049 << "() reason:" << DownloadInterruptReasonToString(reason); | 1044 << "() reason:" << DownloadInterruptReasonToString(reason); |
| 1050 | 1045 |
| 1051 // Postpone recognition of this error until after file name determination | 1046 // Postpone recognition of this error until after file name determination |
| 1052 // has completed and the intermediate file has been renamed to simplify | 1047 // has completed and the intermediate file has been renamed to simplify |
| 1053 // resumption conditions. | 1048 // resumption conditions. |
| 1054 if (state_ == TARGET_PENDING_INTERNAL) { | 1049 if (state_ == TARGET_PENDING_INTERNAL) { |
| 1050 received_bytes_ = bytes_so_far; | |
| 1051 hash_state_ = std::move(secure_hash); | |
| 1055 destination_error_ = reason; | 1052 destination_error_ = reason; |
| 1056 return; | 1053 return; |
| 1057 } | 1054 } |
| 1058 Interrupt(reason); | 1055 InterruptWithPartialState(bytes_so_far, std::move(secure_hash), reason); |
| 1059 UpdateObservers(); | 1056 UpdateObservers(); |
| 1060 } | 1057 } |
| 1061 | 1058 |
| 1062 void DownloadItemImpl::DestinationCompleted(const std::string& final_hash) { | 1059 void DownloadItemImpl::DestinationCompleted( |
| 1060 int64_t total_bytes, | |
| 1061 scoped_ptr<crypto::SecureHash> secure_hash) { | |
| 1063 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1062 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1064 // If the download is in any other state we don't expect any | 1063 // If the download is in any other state we don't expect any |
| 1065 // DownloadDestinationObserver callbacks. An interruption or a cancellation | 1064 // DownloadDestinationObserver callbacks. An interruption or a cancellation |
| 1066 // results in a call to ReleaseDownloadFile which invalidates the weak | 1065 // results in a call to ReleaseDownloadFile which invalidates the weak |
| 1067 // reference held by the DownloadFile and hence cuts off any pending | 1066 // reference held by the DownloadFile and hence cuts off any pending |
| 1068 // callbacks. | 1067 // callbacks. |
| 1069 DCHECK(state_ == TARGET_PENDING_INTERNAL || state_ == IN_PROGRESS_INTERNAL); | 1068 DCHECK(state_ == TARGET_PENDING_INTERNAL || state_ == IN_PROGRESS_INTERNAL); |
| 1070 DVLOG(20) << __FUNCTION__ << " download=" << DebugString(true); | 1069 DVLOG(20) << __FUNCTION__ << " download=" << DebugString(true); |
| 1071 | 1070 |
| 1072 OnAllDataSaved(final_hash); | 1071 OnAllDataSaved(total_bytes, std::move(secure_hash)); |
| 1073 MaybeCompleteDownload(); | 1072 MaybeCompleteDownload(); |
| 1074 } | 1073 } |
| 1075 | 1074 |
| 1076 // **** Download progression cascade | 1075 // **** Download progression cascade |
| 1077 | 1076 |
| 1078 void DownloadItemImpl::Init(bool active, | 1077 void DownloadItemImpl::Init(bool active, |
| 1079 DownloadType download_type) { | 1078 DownloadType download_type) { |
| 1080 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1079 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1081 | 1080 |
| 1082 if (active) | 1081 if (active) |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1141 DCHECK(state_ == INITIAL_INTERNAL || state_ == RESUMING_INTERNAL); | 1140 DCHECK(state_ == INITIAL_INTERNAL || state_ == RESUMING_INTERNAL); |
| 1142 | 1141 |
| 1143 // If the state_ is INITIAL_INTERNAL, then the target path must be empty. | 1142 // If the state_ is INITIAL_INTERNAL, then the target path must be empty. |
| 1144 DCHECK(state_ != INITIAL_INTERNAL || target_path_.empty()); | 1143 DCHECK(state_ != INITIAL_INTERNAL || target_path_.empty()); |
| 1145 | 1144 |
| 1146 // If a resumption attempted failed, or if the download was DOA, then the | 1145 // If a resumption attempted failed, or if the download was DOA, then the |
| 1147 // download should go back to being interrupted. | 1146 // download should go back to being interrupted. |
| 1148 if (new_create_info.result != DOWNLOAD_INTERRUPT_REASON_NONE) { | 1147 if (new_create_info.result != DOWNLOAD_INTERRUPT_REASON_NONE) { |
| 1149 DCHECK(!download_file_.get()); | 1148 DCHECK(!download_file_.get()); |
| 1150 | 1149 |
| 1150 // Download requests that are interrupted by Start() should result in a | |
| 1151 // DownloadCreateInfo with an intact DownloadSaveInfo. | |
| 1152 DCHECK(new_create_info.save_info); | |
| 1153 | |
| 1154 int64_t offset = new_create_info.save_info->offset; | |
| 1155 scoped_ptr<crypto::SecureHash> hash_state = | |
| 1156 make_scoped_ptr(new_create_info.save_info->hash_state | |
| 1157 ? new_create_info.save_info->hash_state->Clone() | |
| 1158 : nullptr); | |
| 1159 | |
| 1151 // Interrupted downloads also need a target path. | 1160 // Interrupted downloads also need a target path. |
| 1152 if (target_path_.empty()) { | 1161 if (target_path_.empty()) { |
| 1162 received_bytes_ = offset; | |
| 1163 hash_state_ = std::move(hash_state); | |
| 1164 destination_error_ = new_create_info.result; | |
| 1153 TransitionTo(INTERRUPTED_TARGET_PENDING_INTERNAL); | 1165 TransitionTo(INTERRUPTED_TARGET_PENDING_INTERNAL); |
| 1154 destination_error_ = new_create_info.result; | |
| 1155 DetermineDownloadTarget(); | 1166 DetermineDownloadTarget(); |
| 1156 return; | 1167 return; |
| 1157 } | 1168 } |
| 1158 | 1169 |
| 1159 // Otherwise, this was a resumption attempt which ended with an | 1170 // Otherwise, this was a resumption attempt which ended with an |
| 1160 // interruption. Continue with current target path. | 1171 // interruption. Continue with current target path. |
| 1161 TransitionTo(TARGET_RESOLVED_INTERNAL); | 1172 TransitionTo(TARGET_RESOLVED_INTERNAL); |
| 1162 Interrupt(new_create_info.result); | 1173 InterruptWithPartialState(offset, std::move(hash_state), |
| 1174 new_create_info.result); | |
| 1163 UpdateObservers(); | 1175 UpdateObservers(); |
| 1164 return; | 1176 return; |
| 1165 } | 1177 } |
| 1166 | 1178 |
| 1167 // Successful download start. | 1179 // Successful download start. |
| 1168 DCHECK(download_file_.get()); | 1180 DCHECK(download_file_.get()); |
| 1169 DCHECK(request_handle_.get()); | 1181 DCHECK(request_handle_.get()); |
| 1170 | 1182 |
| 1171 if (state_ == RESUMING_INTERNAL) | 1183 if (state_ == RESUMING_INTERNAL) |
| 1172 UpdateValidatorsOnResumption(new_create_info); | 1184 UpdateValidatorsOnResumption(new_create_info); |
| 1173 | 1185 |
| 1174 TransitionTo(TARGET_PENDING_INTERNAL); | 1186 TransitionTo(TARGET_PENDING_INTERNAL); |
| 1175 | 1187 |
| 1176 BrowserThread::PostTask( | 1188 BrowserThread::PostTask( |
| 1177 BrowserThread::FILE, FROM_HERE, | 1189 BrowserThread::FILE, FROM_HERE, |
| 1178 base::Bind(&DownloadFile::Initialize, | 1190 base::Bind(&DownloadFile::Initialize, |
| 1179 // Safe because we control download file lifetime. | 1191 // Safe because we control download file lifetime. |
| 1180 base::Unretained(download_file_.get()), | 1192 base::Unretained(download_file_.get()), |
| 1181 base::Bind(&DownloadItemImpl::OnDownloadFileInitialized, | 1193 base::Bind(&DownloadItemImpl::OnDownloadFileInitialized, |
| 1182 weak_ptr_factory_.GetWeakPtr()))); | 1194 weak_ptr_factory_.GetWeakPtr()))); |
| 1183 } | 1195 } |
| 1184 | 1196 |
| 1185 void DownloadItemImpl::OnDownloadFileInitialized( | 1197 void DownloadItemImpl::OnDownloadFileInitialized( |
| 1186 DownloadInterruptReason result) { | 1198 DownloadInterruptReason result) { |
| 1187 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1199 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1188 DCHECK_EQ(state_, TARGET_PENDING_INTERNAL); | 1200 DCHECK_EQ(state_, TARGET_PENDING_INTERNAL); |
| 1189 DVLOG(20) << __FUNCTION__ | 1201 DVLOG(20) << __FUNCTION__ |
| 1190 << "() result:" << DownloadInterruptReasonToString(result); | 1202 << "() result:" << DownloadInterruptReasonToString(result); |
| 1191 if (result != DOWNLOAD_INTERRUPT_REASON_NONE) { | 1203 if (result != DOWNLOAD_INTERRUPT_REASON_NONE) { |
| 1192 // Whoops. That didn't work. Proceed as an interrupted download. | 1204 // Whoops. That didn't work. Proceed as an interrupted download, but reset |
| 1205 // the partial state. Currently, the partial stub cannot be recovered if the | |
| 1206 // download file initialization fails. | |
| 1207 received_bytes_ = 0; | |
| 1208 hash_state_.reset(); | |
|
svaldez
2016/03/09 19:27:34
Reset hash_?
asanka
2016/03/10 16:48:08
Done.
| |
| 1193 destination_error_ = result; | 1209 destination_error_ = result; |
| 1194 TransitionTo(INTERRUPTED_TARGET_PENDING_INTERNAL); | 1210 TransitionTo(INTERRUPTED_TARGET_PENDING_INTERNAL); |
| 1195 } | 1211 } |
| 1196 | 1212 |
| 1197 DetermineDownloadTarget(); | 1213 DetermineDownloadTarget(); |
| 1198 } | 1214 } |
| 1199 | 1215 |
| 1200 void DownloadItemImpl::DetermineDownloadTarget() { | 1216 void DownloadItemImpl::DetermineDownloadTarget() { |
| 1201 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1217 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1202 DVLOG(20) << __FUNCTION__ << "() " << DebugString(true); | 1218 DVLOG(20) << __FUNCTION__ << "() " << DebugString(true); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 1227 << " disposition:" << disposition << " danger_type:" << danger_type | 1243 << " disposition:" << disposition << " danger_type:" << danger_type |
| 1228 << " this:" << DebugString(true); | 1244 << " this:" << DebugString(true); |
| 1229 | 1245 |
| 1230 target_path_ = target_path; | 1246 target_path_ = target_path; |
| 1231 target_disposition_ = disposition; | 1247 target_disposition_ = disposition; |
| 1232 SetDangerType(danger_type); | 1248 SetDangerType(danger_type); |
| 1233 | 1249 |
| 1234 // This was an interrupted download that was looking for a filename. Now that | 1250 // This was an interrupted download that was looking for a filename. Now that |
| 1235 // it has one, transition to interrupted. | 1251 // it has one, transition to interrupted. |
| 1236 if (state_ == INTERRUPTED_TARGET_PENDING_INTERNAL) { | 1252 if (state_ == INTERRUPTED_TARGET_PENDING_INTERNAL) { |
| 1237 Interrupt(destination_error_); | 1253 InterruptWithPartialState(received_bytes_, std::move(hash_state_), |
| 1254 destination_error_); | |
| 1238 destination_error_ = DOWNLOAD_INTERRUPT_REASON_NONE; | 1255 destination_error_ = DOWNLOAD_INTERRUPT_REASON_NONE; |
| 1239 UpdateObservers(); | 1256 UpdateObservers(); |
| 1240 return; | 1257 return; |
| 1241 } | 1258 } |
| 1242 | 1259 |
| 1243 // We want the intermediate and target paths to refer to the same directory so | 1260 // We want the intermediate and target paths to refer to the same directory so |
| 1244 // that they are both on the same device and subject to same | 1261 // that they are both on the same device and subject to same |
| 1245 // space/permission/availability constraints. | 1262 // space/permission/availability constraints. |
| 1246 DCHECK(intermediate_path.DirName() == target_path.DirName()); | 1263 DCHECK(intermediate_path.DirName() == target_path.DirName()); |
| 1247 | 1264 |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 1275 base::Unretained(download_file_.get()), | 1292 base::Unretained(download_file_.get()), |
| 1276 intermediate_path, callback)); | 1293 intermediate_path, callback)); |
| 1277 } | 1294 } |
| 1278 | 1295 |
| 1279 void DownloadItemImpl::OnDownloadRenamedToIntermediateName( | 1296 void DownloadItemImpl::OnDownloadRenamedToIntermediateName( |
| 1280 DownloadInterruptReason reason, | 1297 DownloadInterruptReason reason, |
| 1281 const base::FilePath& full_path) { | 1298 const base::FilePath& full_path) { |
| 1282 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1299 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1283 DCHECK_EQ(state_, TARGET_PENDING_INTERNAL); | 1300 DCHECK_EQ(state_, TARGET_PENDING_INTERNAL); |
| 1284 DVLOG(20) << __FUNCTION__ << " download=" << DebugString(true); | 1301 DVLOG(20) << __FUNCTION__ << " download=" << DebugString(true); |
| 1302 | |
| 1285 TransitionTo(TARGET_RESOLVED_INTERNAL); | 1303 TransitionTo(TARGET_RESOLVED_INTERNAL); |
| 1286 | 1304 |
| 1305 // If the intermediate rename fails while there's also a destination_error_, | |
| 1306 // then the former is considered the critical error since it requires | |
| 1307 // discarding the partial state. | |
| 1308 if (DOWNLOAD_INTERRUPT_REASON_NONE != reason) { | |
| 1309 // TODO(asanka): Even though the rename failed, it may still be possible to | |
| 1310 // recover the partial state from the 'before' name. | |
| 1311 InterruptAndDiscardPartialState(reason); | |
| 1312 UpdateObservers(); | |
| 1313 return; | |
| 1314 } | |
| 1315 | |
| 1287 if (DOWNLOAD_INTERRUPT_REASON_NONE != destination_error_) { | 1316 if (DOWNLOAD_INTERRUPT_REASON_NONE != destination_error_) { |
| 1288 // Process destination error. If both |reason| and |destination_error_| | 1317 SetFullPath(full_path); |
| 1289 // refer to actual errors, we want to use the |destination_error_| as the | 1318 InterruptWithPartialState(received_bytes_, std::move(hash_state_), |
| 1290 // argument to the Interrupt() routine, as it happened first. | 1319 destination_error_); |
| 1291 if (reason == DOWNLOAD_INTERRUPT_REASON_NONE) | |
| 1292 SetFullPath(full_path); | |
| 1293 Interrupt(destination_error_); | |
| 1294 destination_error_ = DOWNLOAD_INTERRUPT_REASON_NONE; | 1320 destination_error_ = DOWNLOAD_INTERRUPT_REASON_NONE; |
| 1295 UpdateObservers(); | 1321 UpdateObservers(); |
| 1296 } else if (DOWNLOAD_INTERRUPT_REASON_NONE != reason) { | 1322 return; |
| 1297 Interrupt(reason); | |
| 1298 // All file errors result in file deletion above; no need to cleanup. The | |
| 1299 // current_path_ should be empty. Resuming this download will force a | |
| 1300 // restart and a re-doing of filename determination. | |
| 1301 DCHECK(current_path_.empty()); | |
| 1302 UpdateObservers(); | |
| 1303 } else { | |
| 1304 SetFullPath(full_path); | |
| 1305 TransitionTo(IN_PROGRESS_INTERNAL); | |
| 1306 // TODO(asanka): Calling UpdateObservers() prior to MaybeCompleteDownload() | |
| 1307 // is not safe. The download could be in an underminate state after invoking | |
| 1308 // observers. http://crbug.com/586610 | |
| 1309 UpdateObservers(); | |
| 1310 MaybeCompleteDownload(); | |
| 1311 } | 1323 } |
| 1324 | |
| 1325 SetFullPath(full_path); | |
| 1326 TransitionTo(IN_PROGRESS_INTERNAL); | |
| 1327 // TODO(asanka): Calling UpdateObservers() prior to MaybeCompleteDownload() is | |
| 1328 // not safe. The download could be in an underminate state after invoking | |
| 1329 // observers. http://crbug.com/586610 | |
| 1330 UpdateObservers(); | |
| 1331 MaybeCompleteDownload(); | |
| 1312 } | 1332 } |
| 1313 | 1333 |
| 1314 // When SavePackage downloads MHTML to GData (see | 1334 // When SavePackage downloads MHTML to GData (see |
| 1315 // SavePackageFilePickerChromeOS), GData calls MaybeCompleteDownload() like it | 1335 // SavePackageFilePickerChromeOS), GData calls MaybeCompleteDownload() like it |
| 1316 // does for non-SavePackage downloads, but SavePackage downloads never satisfy | 1336 // does for non-SavePackage downloads, but SavePackage downloads never satisfy |
| 1317 // IsDownloadReadyForCompletion(). GDataDownloadObserver manually calls | 1337 // IsDownloadReadyForCompletion(). GDataDownloadObserver manually calls |
| 1318 // DownloadItem::UpdateObservers() when the upload completes so that SavePackage | 1338 // DownloadItem::UpdateObservers() when the upload completes so that SavePackage |
| 1319 // notices that the upload has completed and runs its normal Finish() pathway. | 1339 // notices that the upload has completed and runs its normal Finish() pathway. |
| 1320 // MaybeCompleteDownload() is never the mechanism by which SavePackage completes | 1340 // MaybeCompleteDownload() is never the mechanism by which SavePackage completes |
| 1321 // downloads. SavePackage always uses its own Finish() to mark downloads | 1341 // downloads. SavePackage always uses its own Finish() to mark downloads |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1363 | 1383 |
| 1364 DCHECK(download_file_.get()); | 1384 DCHECK(download_file_.get()); |
| 1365 // Unilaterally rename; even if it already has the right name, | 1385 // Unilaterally rename; even if it already has the right name, |
| 1366 // we need theannotation. | 1386 // we need theannotation. |
| 1367 DownloadFile::RenameCompletionCallback callback = | 1387 DownloadFile::RenameCompletionCallback callback = |
| 1368 base::Bind(&DownloadItemImpl::OnDownloadRenamedToFinalName, | 1388 base::Bind(&DownloadItemImpl::OnDownloadRenamedToFinalName, |
| 1369 weak_ptr_factory_.GetWeakPtr()); | 1389 weak_ptr_factory_.GetWeakPtr()); |
| 1370 BrowserThread::PostTask( | 1390 BrowserThread::PostTask( |
| 1371 BrowserThread::FILE, FROM_HERE, | 1391 BrowserThread::FILE, FROM_HERE, |
| 1372 base::Bind(&DownloadFile::RenameAndAnnotate, | 1392 base::Bind(&DownloadFile::RenameAndAnnotate, |
| 1373 base::Unretained(download_file_.get()), | 1393 base::Unretained(download_file_.get()), GetTargetFilePath(), |
| 1374 GetTargetFilePath(), callback)); | 1394 delegate_->GetApplicationClientIdForFileScanning(), GetURL(), |
| 1395 GetReferrerUrl(), callback)); | |
| 1375 } | 1396 } |
| 1376 | 1397 |
| 1377 void DownloadItemImpl::OnDownloadRenamedToFinalName( | 1398 void DownloadItemImpl::OnDownloadRenamedToFinalName( |
| 1378 DownloadInterruptReason reason, | 1399 DownloadInterruptReason reason, |
| 1379 const base::FilePath& full_path) { | 1400 const base::FilePath& full_path) { |
| 1380 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1401 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1381 DCHECK(!is_save_package_download_); | 1402 DCHECK(!is_save_package_download_); |
| 1382 | 1403 |
| 1383 // If a cancel or interrupt hit, we'll cancel the DownloadFile, which | 1404 // If a cancel or interrupt hit, we'll cancel the DownloadFile, which |
| 1384 // will result in deleting the file on the file thread. So we don't | 1405 // will result in deleting the file on the file thread. So we don't |
| 1385 // care about the name having been changed. | 1406 // care about the name having been changed. |
| 1386 if (state_ != IN_PROGRESS_INTERNAL) | 1407 if (state_ != IN_PROGRESS_INTERNAL) |
| 1387 return; | 1408 return; |
| 1388 | 1409 |
| 1389 DVLOG(20) << __FUNCTION__ << "()" | 1410 DVLOG(20) << __FUNCTION__ << "()" |
| 1390 << " full_path = \"" << full_path.value() << "\"" | 1411 << " full_path = \"" << full_path.value() << "\"" |
| 1391 << " " << DebugString(false); | 1412 << " " << DebugString(false); |
| 1392 | 1413 |
| 1393 if (DOWNLOAD_INTERRUPT_REASON_NONE != reason) { | 1414 if (DOWNLOAD_INTERRUPT_REASON_NONE != reason) { |
| 1394 Interrupt(reason); | 1415 // Failure to perform the final rename is considered fatal. TODO(asanka): It |
| 1395 | 1416 // may not be, in which case we should figure out whether we can recover the |
| 1396 // All file errors should have resulted in in file deletion above. On | 1417 // state. |
| 1397 // resumption we will need to re-do filename determination. | 1418 InterruptAndDiscardPartialState(reason); |
| 1398 DCHECK(current_path_.empty()); | |
| 1399 UpdateObservers(); | 1419 UpdateObservers(); |
| 1400 return; | 1420 return; |
| 1401 } | 1421 } |
| 1402 | 1422 |
| 1403 DCHECK(target_path_ == full_path); | 1423 DCHECK(target_path_ == full_path); |
| 1404 | 1424 |
| 1405 if (full_path != current_path_) { | 1425 if (full_path != current_path_) { |
| 1406 // full_path is now the current and target file path. | 1426 // full_path is now the current and target file path. |
| 1407 DCHECK(!full_path.empty()); | 1427 DCHECK(!full_path.empty()); |
| 1408 SetFullPath(full_path); | 1428 SetFullPath(full_path); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1456 if (!IsTemporary()) | 1476 if (!IsTemporary()) |
| 1457 OpenDownload(); | 1477 OpenDownload(); |
| 1458 | 1478 |
| 1459 auto_opened_ = true; | 1479 auto_opened_ = true; |
| 1460 } | 1480 } |
| 1461 UpdateObservers(); | 1481 UpdateObservers(); |
| 1462 } | 1482 } |
| 1463 | 1483 |
| 1464 // **** End of Download progression cascade | 1484 // **** End of Download progression cascade |
| 1465 | 1485 |
| 1466 // An error occurred somewhere. | 1486 void DownloadItemImpl::InterruptAndDiscardPartialState( |
| 1467 void DownloadItemImpl::Interrupt(DownloadInterruptReason reason) { | 1487 DownloadInterruptReason reason) { |
| 1488 InterruptWithPartialState(0, scoped_ptr<crypto::SecureHash>(), reason); | |
| 1489 } | |
| 1490 | |
| 1491 void DownloadItemImpl::InterruptWithPartialState( | |
| 1492 int64_t bytes_so_far, | |
| 1493 scoped_ptr<crypto::SecureHash> hash_state, | |
| 1494 DownloadInterruptReason reason) { | |
| 1468 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1495 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1469 DCHECK_NE(DOWNLOAD_INTERRUPT_REASON_NONE, reason); | 1496 DCHECK_NE(DOWNLOAD_INTERRUPT_REASON_NONE, reason); |
| 1470 DVLOG(20) << __FUNCTION__ | 1497 DVLOG(20) << __FUNCTION__ |
| 1471 << "() reason:" << DownloadInterruptReasonToString(reason) | 1498 << "() reason:" << DownloadInterruptReasonToString(reason) |
| 1499 << " bytes_so_far:" << bytes_so_far | |
| 1500 << " hash_state:" << (hash_state ? "Valid" : "Invalid") | |
| 1472 << " this=" << DebugString(true); | 1501 << " this=" << DebugString(true); |
| 1473 | 1502 |
| 1474 // Somewhat counter-intuitively, it is possible for us to receive an | 1503 // Somewhat counter-intuitively, it is possible for us to receive an |
| 1475 // interrupt after we've already been interrupted. The generation of | 1504 // interrupt after we've already been interrupted. The generation of |
| 1476 // interrupts from the file thread Renames and the generation of | 1505 // interrupts from the file thread Renames and the generation of |
| 1477 // interrupts from disk writes go through two different mechanisms (driven | 1506 // interrupts from disk writes go through two different mechanisms (driven |
| 1478 // by rename requests from UI thread and by write requests from IO thread, | 1507 // by rename requests from UI thread and by write requests from IO thread, |
| 1479 // respectively), and since we choose not to keep state on the File thread, | 1508 // respectively), and since we choose not to keep state on the File thread, |
| 1480 // this is the place where the races collide. It's also possible for | 1509 // this is the place where the races collide. It's also possible for |
| 1481 // interrupts to race with cancels. | 1510 // interrupts to race with cancels. |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1502 | 1531 |
| 1503 if (download_file_) { | 1532 if (download_file_) { |
| 1504 ResumeMode resume_mode = GetResumeMode(); | 1533 ResumeMode resume_mode = GetResumeMode(); |
| 1505 ReleaseDownloadFile(resume_mode != RESUME_MODE_IMMEDIATE_CONTINUE && | 1534 ReleaseDownloadFile(resume_mode != RESUME_MODE_IMMEDIATE_CONTINUE && |
| 1506 resume_mode != RESUME_MODE_USER_CONTINUE); | 1535 resume_mode != RESUME_MODE_USER_CONTINUE); |
| 1507 } | 1536 } |
| 1508 break; | 1537 break; |
| 1509 | 1538 |
| 1510 case RESUMING_INTERNAL: | 1539 case RESUMING_INTERNAL: |
| 1511 case INTERRUPTED_INTERNAL: | 1540 case INTERRUPTED_INTERNAL: |
| 1541 DCHECK(!download_file_); | |
| 1512 // The first non-cancel interrupt reason wins in cases where multiple | 1542 // The first non-cancel interrupt reason wins in cases where multiple |
| 1513 // things go wrong. | 1543 // things go wrong. |
| 1514 if (reason != DOWNLOAD_INTERRUPT_REASON_USER_CANCELED && | 1544 if (reason != DOWNLOAD_INTERRUPT_REASON_USER_CANCELED && |
| 1515 reason != DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN) | 1545 reason != DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN) |
| 1516 return; | 1546 return; |
| 1517 | 1547 |
| 1518 last_reason_ = reason; | 1548 last_reason_ = reason; |
| 1519 if (!current_path_.empty()) { | 1549 if (!current_path_.empty()) { |
| 1520 // There is no download file and this is transitioning from INTERRUPTED | 1550 // There is no download file and this is transitioning from INTERRUPTED |
| 1521 // to CANCELLED. The intermediate file is no longer usable, and should | 1551 // to CANCELLED. The intermediate file is no longer usable, and should |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1533 // through another round of downloading when we resume. There's a potential | 1563 // through another round of downloading when we resume. There's a potential |
| 1534 // problem here in the abstract, as if we did download all the data and then | 1564 // problem here in the abstract, as if we did download all the data and then |
| 1535 // run into a continuable error, on resumption we won't download any more | 1565 // run into a continuable error, on resumption we won't download any more |
| 1536 // data. However, a) there are currently no continuable errors that can occur | 1566 // data. However, a) there are currently no continuable errors that can occur |
| 1537 // after we download all the data, and b) if there were, that would probably | 1567 // after we download all the data, and b) if there were, that would probably |
| 1538 // simply result in a null range request, which would generate a | 1568 // simply result in a null range request, which would generate a |
| 1539 // DestinationCompleted() notification from the DownloadFile, which would | 1569 // DestinationCompleted() notification from the DownloadFile, which would |
| 1540 // behave properly with setting all_data_saved_ to false here. | 1570 // behave properly with setting all_data_saved_ to false here. |
| 1541 all_data_saved_ = false; | 1571 all_data_saved_ = false; |
| 1542 | 1572 |
| 1573 if (current_path_.empty()) { | |
| 1574 hash_state_.reset(); | |
| 1575 hash_.clear(); | |
| 1576 received_bytes_ = 0; | |
| 1577 } else { | |
| 1578 UpdateProgress(bytes_so_far, 0); | |
| 1579 hash_state_ = std::move(hash_state); | |
| 1580 UpdatePrefixHash(); | |
| 1581 } | |
| 1582 | |
| 1543 if (request_handle_) | 1583 if (request_handle_) |
| 1544 request_handle_->CancelRequest(); | 1584 request_handle_->CancelRequest(); |
| 1545 | 1585 |
| 1546 if (reason == DOWNLOAD_INTERRUPT_REASON_USER_CANCELED || | 1586 if (reason == DOWNLOAD_INTERRUPT_REASON_USER_CANCELED || |
| 1547 reason == DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN) { | 1587 reason == DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN) { |
| 1548 if (IsDangerous()) { | 1588 if (IsDangerous()) { |
| 1549 RecordDangerousDownloadDiscard( | 1589 RecordDangerousDownloadDiscard( |
| 1550 reason == DOWNLOAD_INTERRUPT_REASON_USER_CANCELED | 1590 reason == DOWNLOAD_INTERRUPT_REASON_USER_CANCELED |
| 1551 ? DOWNLOAD_DISCARD_DUE_TO_USER_ACTION | 1591 ? DOWNLOAD_DISCARD_DUE_TO_USER_ACTION |
| 1552 : DOWNLOAD_DISCARD_DUE_TO_SHUTDOWN, | 1592 : DOWNLOAD_DISCARD_DUE_TO_SHUTDOWN, |
| 1553 GetDangerType(), GetTargetFilePath()); | 1593 GetDangerType(), GetTargetFilePath()); |
| 1554 } | 1594 } |
| 1555 | 1595 |
| 1556 RecordDownloadCount(CANCELLED_COUNT); | 1596 RecordDownloadCount(CANCELLED_COUNT); |
| 1557 TransitionTo(CANCELLED_INTERNAL); | 1597 TransitionTo(CANCELLED_INTERNAL); |
| 1558 return; | 1598 return; |
| 1559 } | 1599 } |
| 1560 | 1600 |
| 1561 RecordDownloadInterrupted(reason, received_bytes_, total_bytes_); | 1601 RecordDownloadInterrupted(reason, received_bytes_, total_bytes_); |
| 1562 if (!GetWebContents()) | 1602 if (!GetWebContents()) |
| 1563 RecordDownloadCount(INTERRUPTED_WITHOUT_WEBCONTENTS); | 1603 RecordDownloadCount(INTERRUPTED_WITHOUT_WEBCONTENTS); |
| 1564 | 1604 |
| 1565 TransitionTo(INTERRUPTED_INTERNAL); | 1605 TransitionTo(INTERRUPTED_INTERNAL); |
| 1566 AutoResumeIfValid(); | 1606 AutoResumeIfValid(); |
| 1567 } | 1607 } |
| 1568 | 1608 |
| 1609 void DownloadItemImpl::UpdateProgress(int64_t bytes_so_far, | |
| 1610 int64_t bytes_per_sec) { | |
| 1611 received_bytes_ = bytes_so_far; | |
| 1612 bytes_per_sec_ = bytes_per_sec; | |
| 1613 | |
| 1614 // If we've received more data than we were expecting (bad server info?), | |
| 1615 // revert to 'unknown size mode'. | |
| 1616 if (received_bytes_ > total_bytes_) | |
| 1617 total_bytes_ = 0; | |
| 1618 } | |
| 1619 | |
| 1620 void DownloadItemImpl::UpdatePrefixHash() { | |
| 1621 if (!hash_state_) { | |
| 1622 hash_.clear(); | |
| 1623 return; | |
| 1624 } | |
| 1625 | |
| 1626 scoped_ptr<crypto::SecureHash> clone(hash_state_->Clone()); | |
| 1627 std::vector<char> hash_value(clone->GetHashLength()); | |
| 1628 clone->Finish(&hash_value.front(), hash_value.size()); | |
| 1629 hash_.assign(hash_value.begin(), hash_value.end()); | |
| 1630 } | |
| 1631 | |
| 1569 void DownloadItemImpl::ReleaseDownloadFile(bool destroy_file) { | 1632 void DownloadItemImpl::ReleaseDownloadFile(bool destroy_file) { |
| 1570 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1633 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1571 DVLOG(20) << __FUNCTION__ << "() destroy_file:" << destroy_file; | 1634 DVLOG(20) << __FUNCTION__ << "() destroy_file:" << destroy_file; |
| 1572 | 1635 |
| 1573 if (destroy_file) { | 1636 if (destroy_file) { |
| 1574 BrowserThread::PostTask( | 1637 BrowserThread::PostTask( |
| 1575 BrowserThread::FILE, FROM_HERE, | 1638 BrowserThread::FILE, FROM_HERE, |
| 1576 // Will be deleted at end of task execution. | 1639 // Will be deleted at end of task execution. |
| 1577 base::Bind(&DownloadFileCancel, base::Passed(&download_file_))); | 1640 base::Bind(&DownloadFileCancel, base::Passed(&download_file_))); |
| 1578 // Avoid attempting to reuse the intermediate file by clearing out | 1641 // Avoid attempting to reuse the intermediate file by clearing out |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1674 base::Bind(&ItemCompletingNetLogCallback, received_bytes_, &hash_)); | 1737 base::Bind(&ItemCompletingNetLogCallback, received_bytes_, &hash_)); |
| 1675 break; | 1738 break; |
| 1676 | 1739 |
| 1677 case COMPLETE_INTERNAL: | 1740 case COMPLETE_INTERNAL: |
| 1678 bound_net_log_.AddEvent( | 1741 bound_net_log_.AddEvent( |
| 1679 net::NetLog::TYPE_DOWNLOAD_ITEM_FINISHED, | 1742 net::NetLog::TYPE_DOWNLOAD_ITEM_FINISHED, |
| 1680 base::Bind(&ItemFinishedNetLogCallback, auto_opened_)); | 1743 base::Bind(&ItemFinishedNetLogCallback, auto_opened_)); |
| 1681 break; | 1744 break; |
| 1682 | 1745 |
| 1683 case INTERRUPTED_INTERNAL: | 1746 case INTERRUPTED_INTERNAL: |
| 1684 bound_net_log_.AddEvent( | 1747 bound_net_log_.AddEvent(net::NetLog::TYPE_DOWNLOAD_ITEM_INTERRUPTED, |
| 1685 net::NetLog::TYPE_DOWNLOAD_ITEM_INTERRUPTED, | 1748 base::Bind(&ItemInterruptedNetLogCallback, |
| 1686 base::Bind(&ItemInterruptedNetLogCallback, last_reason_, | 1749 last_reason_, received_bytes_)); |
| 1687 received_bytes_, &hash_state_)); | |
| 1688 break; | 1750 break; |
| 1689 | 1751 |
| 1690 case RESUMING_INTERNAL: | 1752 case RESUMING_INTERNAL: |
| 1691 bound_net_log_.AddEvent( | 1753 bound_net_log_.AddEvent(net::NetLog::TYPE_DOWNLOAD_ITEM_RESUMED, |
| 1692 net::NetLog::TYPE_DOWNLOAD_ITEM_RESUMED, | 1754 base::Bind(&ItemResumingNetLogCallback, false, |
| 1693 base::Bind(&ItemResumingNetLogCallback, false, last_reason_, | 1755 last_reason_, received_bytes_)); |
| 1694 received_bytes_, &hash_state_)); | |
| 1695 break; | 1756 break; |
| 1696 | 1757 |
| 1697 case CANCELLED_INTERNAL: | 1758 case CANCELLED_INTERNAL: |
| 1698 bound_net_log_.AddEvent( | 1759 bound_net_log_.AddEvent( |
| 1699 net::NetLog::TYPE_DOWNLOAD_ITEM_CANCELED, | 1760 net::NetLog::TYPE_DOWNLOAD_ITEM_CANCELED, |
| 1700 base::Bind(&ItemCanceledNetLogCallback, received_bytes_, | 1761 base::Bind(&ItemCanceledNetLogCallback, received_bytes_)); |
| 1701 &hash_state_)); | |
| 1702 break; | 1762 break; |
| 1703 | 1763 |
| 1704 case MAX_DOWNLOAD_INTERNAL_STATE: | 1764 case MAX_DOWNLOAD_INTERNAL_STATE: |
| 1705 NOTREACHED(); | 1765 NOTREACHED(); |
| 1706 break; | 1766 break; |
| 1707 } | 1767 } |
| 1708 | 1768 |
| 1709 DVLOG(20) << " " << __FUNCTION__ << "()" | 1769 DVLOG(20) << " " << __FUNCTION__ << "()" |
| 1710 << " from:" << DebugDownloadStateString(old_state) | 1770 << " from:" << DebugDownloadStateString(old_state) |
| 1711 << " to:" << DebugDownloadStateString(state_) | 1771 << " to:" << DebugDownloadStateString(state_) |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1792 | 1852 |
| 1793 // We are starting a new request. Shake off all pending operations. | 1853 // We are starting a new request. Shake off all pending operations. |
| 1794 DCHECK(!download_file_); | 1854 DCHECK(!download_file_); |
| 1795 weak_ptr_factory_.InvalidateWeakPtrs(); | 1855 weak_ptr_factory_.InvalidateWeakPtrs(); |
| 1796 | 1856 |
| 1797 // Reset the appropriate state if restarting. | 1857 // Reset the appropriate state if restarting. |
| 1798 ResumeMode mode = GetResumeMode(); | 1858 ResumeMode mode = GetResumeMode(); |
| 1799 if (mode == RESUME_MODE_IMMEDIATE_RESTART || | 1859 if (mode == RESUME_MODE_IMMEDIATE_RESTART || |
| 1800 mode == RESUME_MODE_USER_RESTART) { | 1860 mode == RESUME_MODE_USER_RESTART) { |
| 1801 received_bytes_ = 0; | 1861 received_bytes_ = 0; |
| 1802 hash_state_ = ""; | 1862 last_modified_time_.clear(); |
| 1803 last_modified_time_ = ""; | 1863 etag_.clear(); |
| 1804 etag_ = ""; | 1864 hash_.clear(); |
| 1865 hash_state_.reset(); | |
| 1805 } | 1866 } |
| 1806 | 1867 |
| 1807 // Avoid using the WebContents even if it's still around. Resumption requests | 1868 // Avoid using the WebContents even if it's still around. Resumption requests |
| 1808 // are consistently routed through the no-renderer code paths so that the | 1869 // are consistently routed through the no-renderer code paths so that the |
| 1809 // request will not be dropped if the WebContents (and by extension, the | 1870 // request will not be dropped if the WebContents (and by extension, the |
| 1810 // associated renderer) goes away before a response is received. | 1871 // associated renderer) goes away before a response is received. |
| 1811 scoped_ptr<DownloadUrlParameters> download_params(new DownloadUrlParameters( | 1872 scoped_ptr<DownloadUrlParameters> download_params(new DownloadUrlParameters( |
| 1812 GetURL(), -1, -1, -1, GetBrowserContext()->GetResourceContext())); | 1873 GetURL(), -1, -1, -1, GetBrowserContext()->GetResourceContext())); |
| 1813 download_params->set_file_path(GetFullPath()); | 1874 download_params->set_file_path(GetFullPath()); |
| 1814 download_params->set_offset(GetReceivedBytes()); | 1875 download_params->set_offset(GetReceivedBytes()); |
| 1815 download_params->set_hash_state(GetHashState()); | |
| 1816 download_params->set_last_modified(GetLastModifiedTime()); | 1876 download_params->set_last_modified(GetLastModifiedTime()); |
| 1817 download_params->set_etag(GetETag()); | 1877 download_params->set_etag(GetETag()); |
| 1878 download_params->set_prefix_hash(hash_); | |
| 1879 download_params->set_hash_state(std::move(hash_state_)); | |
| 1818 | 1880 |
| 1819 TransitionTo(RESUMING_INTERNAL); | 1881 TransitionTo(RESUMING_INTERNAL); |
| 1820 delegate_->ResumeInterruptedDownload(std::move(download_params), GetId()); | 1882 delegate_->ResumeInterruptedDownload(std::move(download_params), GetId()); |
| 1821 // Just in case we were interrupted while paused. | 1883 // Just in case we were interrupted while paused. |
| 1822 is_paused_ = false; | 1884 is_paused_ = false; |
| 1823 } | 1885 } |
| 1824 | 1886 |
| 1825 // static | 1887 // static |
| 1826 DownloadItem::DownloadState DownloadItemImpl::InternalToExternalState( | 1888 DownloadItem::DownloadState DownloadItemImpl::InternalToExternalState( |
| 1827 DownloadInternalState internal_state) { | 1889 DownloadInternalState internal_state) { |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1992 case RESUME_MODE_USER_CONTINUE: | 2054 case RESUME_MODE_USER_CONTINUE: |
| 1993 return "USER_CONTINUE"; | 2055 return "USER_CONTINUE"; |
| 1994 case RESUME_MODE_USER_RESTART: | 2056 case RESUME_MODE_USER_RESTART: |
| 1995 return "USER_RESTART"; | 2057 return "USER_RESTART"; |
| 1996 } | 2058 } |
| 1997 NOTREACHED() << "Unknown resume mode " << mode; | 2059 NOTREACHED() << "Unknown resume mode " << mode; |
| 1998 return "unknown"; | 2060 return "unknown"; |
| 1999 } | 2061 } |
| 2000 | 2062 |
| 2001 } // namespace content | 2063 } // namespace content |
| OLD | NEW |