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 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 destination_error_(content::DOWNLOAD_INTERRUPT_REASON_NONE), | 144 destination_error_(content::DOWNLOAD_INTERRUPT_REASON_NONE), |
145 opened_(opened), | 145 opened_(opened), |
146 delegate_delayed_complete_(false), | 146 delegate_delayed_complete_(false), |
147 bound_net_log_(bound_net_log), | 147 bound_net_log_(bound_net_log), |
148 weak_ptr_factory_(this) { | 148 weak_ptr_factory_(this) { |
149 delegate_->Attach(); | 149 delegate_->Attach(); |
150 DCHECK_NE(IN_PROGRESS_INTERNAL, state_); | 150 DCHECK_NE(IN_PROGRESS_INTERNAL, state_); |
151 Init(false /* not actively downloading */, SRC_HISTORY_IMPORT); | 151 Init(false /* not actively downloading */, SRC_HISTORY_IMPORT); |
152 } | 152 } |
153 | 153 |
154 // Constructing for a regular download: | 154 // Constructing for a regular download (also includes SavePackage downloads): |
155 DownloadItemImpl::DownloadItemImpl( | 155 DownloadItemImpl::DownloadItemImpl(DownloadItemImplDelegate* delegate, |
156 DownloadItemImplDelegate* delegate, | 156 uint32 download_id, |
157 uint32 download_id, | 157 const DownloadCreateInfo& info, |
158 const DownloadCreateInfo& info, | 158 const net::BoundNetLog& bound_net_log) |
159 const net::BoundNetLog& bound_net_log) | 159 : is_save_package_download_(info.is_save_package_download), |
160 : is_save_package_download_(false), | |
161 download_id_(download_id), | 160 download_id_(download_id), |
162 target_disposition_( | 161 target_disposition_((info.save_info->prompt_for_save_location) |
163 (info.save_info->prompt_for_save_location) ? | 162 ? TARGET_DISPOSITION_PROMPT |
164 TARGET_DISPOSITION_PROMPT : TARGET_DISPOSITION_OVERWRITE), | 163 : TARGET_DISPOSITION_OVERWRITE), |
165 url_chain_(info.url_chain), | 164 url_chain_(info.url_chain), |
166 referrer_url_(info.referrer_url), | 165 referrer_url_(info.referrer_url), |
167 suggested_filename_(UTF16ToUTF8(info.save_info->suggested_name)), | 166 suggested_filename_(UTF16ToUTF8(info.save_info->suggested_name)), |
168 forced_file_path_(info.save_info->file_path), | 167 forced_file_path_(info.save_info->file_path), |
169 transition_type_(info.transition_type), | 168 transition_type_(info.transition_type), |
170 has_user_gesture_(info.has_user_gesture), | 169 has_user_gesture_(info.has_user_gesture), |
| 170 route_id_(info.route_id), |
171 content_disposition_(info.content_disposition), | 171 content_disposition_(info.content_disposition), |
172 mime_type_(info.mime_type), | 172 mime_type_(info.mime_type), |
173 original_mime_type_(info.original_mime_type), | 173 original_mime_type_(info.original_mime_type), |
174 remote_address_(info.remote_address), | 174 remote_address_(info.remote_address), |
175 total_bytes_(info.total_bytes), | 175 total_bytes_(info.total_bytes), |
176 received_bytes_(0), | 176 received_bytes_(0), |
177 bytes_per_sec_(0), | 177 bytes_per_sec_(0), |
178 last_modified_time_(info.last_modified), | 178 last_modified_time_(info.last_modified), |
179 etag_(info.etag), | 179 etag_(info.etag), |
180 last_reason_(DOWNLOAD_INTERRUPT_REASON_NONE), | 180 last_reason_(DOWNLOAD_INTERRUPT_REASON_NONE), |
181 start_tick_(base::TimeTicks::Now()), | 181 start_tick_(base::TimeTicks::Now()), |
182 state_(IN_PROGRESS_INTERNAL), | 182 state_(IN_PROGRESS_INTERNAL), |
183 danger_type_(DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS), | 183 danger_type_(DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS), |
184 start_time_(info.start_time), | 184 start_time_(info.start_time), |
185 delegate_(delegate), | 185 delegate_(delegate), |
186 is_paused_(false), | 186 is_paused_(false), |
187 auto_resume_count_(0), | 187 auto_resume_count_(0), |
188 open_when_complete_(false), | 188 open_when_complete_(false), |
189 file_externally_removed_(false), | 189 file_externally_removed_(false), |
190 auto_opened_(false), | 190 auto_opened_(false), |
191 is_temporary_(!info.save_info->file_path.empty()), | 191 is_temporary_(!info.save_info->file_path.empty()), |
192 all_data_saved_(false), | 192 all_data_saved_(false), |
193 destination_error_(content::DOWNLOAD_INTERRUPT_REASON_NONE), | 193 destination_error_(content::DOWNLOAD_INTERRUPT_REASON_NONE), |
194 opened_(false), | 194 opened_(false), |
195 delegate_delayed_complete_(false), | 195 delegate_delayed_complete_(false), |
196 bound_net_log_(bound_net_log), | 196 bound_net_log_(bound_net_log), |
197 weak_ptr_factory_(this) { | 197 weak_ptr_factory_(this) { |
198 delegate_->Attach(); | 198 delegate_->Attach(); |
199 Init(true /* actively downloading */, SRC_ACTIVE_DOWNLOAD); | 199 Init(true /* actively downloading */, |
| 200 is_save_package_download_ ? SRC_SAVE_PAGE_AS : SRC_ACTIVE_DOWNLOAD); |
200 | 201 |
201 // Link the event sources. | 202 if (is_save_package_download_) { |
202 bound_net_log_.AddEvent( | 203 current_path_ = info.save_info->file_path; |
203 net::NetLog::TYPE_DOWNLOAD_URL_REQUEST, | 204 target_path_ = current_path_; |
204 info.request_bound_net_log.source().ToEventParametersCallback()); | 205 } else { |
| 206 // Link the event sources. |
| 207 bound_net_log_.AddEvent( |
| 208 net::NetLog::TYPE_DOWNLOAD_URL_REQUEST, |
| 209 info.request_bound_net_log.source().ToEventParametersCallback()); |
205 | 210 |
206 info.request_bound_net_log.AddEvent( | 211 info.request_bound_net_log.AddEvent( |
207 net::NetLog::TYPE_DOWNLOAD_STARTED, | 212 net::NetLog::TYPE_DOWNLOAD_STARTED, |
208 bound_net_log_.source().ToEventParametersCallback()); | 213 bound_net_log_.source().ToEventParametersCallback()); |
209 } | 214 } |
210 | |
211 // Constructing for the "Save Page As..." feature: | |
212 DownloadItemImpl::DownloadItemImpl( | |
213 DownloadItemImplDelegate* delegate, | |
214 uint32 download_id, | |
215 const base::FilePath& path, | |
216 const GURL& url, | |
217 const std::string& mime_type, | |
218 scoped_ptr<DownloadRequestHandleInterface> request_handle, | |
219 const net::BoundNetLog& bound_net_log) | |
220 : is_save_package_download_(true), | |
221 request_handle_(request_handle.Pass()), | |
222 download_id_(download_id), | |
223 current_path_(path), | |
224 target_path_(path), | |
225 target_disposition_(TARGET_DISPOSITION_OVERWRITE), | |
226 url_chain_(1, url), | |
227 referrer_url_(GURL()), | |
228 transition_type_(PAGE_TRANSITION_LINK), | |
229 has_user_gesture_(false), | |
230 mime_type_(mime_type), | |
231 original_mime_type_(mime_type), | |
232 total_bytes_(0), | |
233 received_bytes_(0), | |
234 bytes_per_sec_(0), | |
235 last_reason_(DOWNLOAD_INTERRUPT_REASON_NONE), | |
236 start_tick_(base::TimeTicks::Now()), | |
237 state_(IN_PROGRESS_INTERNAL), | |
238 danger_type_(DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS), | |
239 start_time_(base::Time::Now()), | |
240 delegate_(delegate), | |
241 is_paused_(false), | |
242 auto_resume_count_(0), | |
243 open_when_complete_(false), | |
244 file_externally_removed_(false), | |
245 auto_opened_(false), | |
246 is_temporary_(false), | |
247 all_data_saved_(false), | |
248 destination_error_(content::DOWNLOAD_INTERRUPT_REASON_NONE), | |
249 opened_(false), | |
250 delegate_delayed_complete_(false), | |
251 bound_net_log_(bound_net_log), | |
252 weak_ptr_factory_(this) { | |
253 delegate_->Attach(); | |
254 Init(true /* actively downloading */, SRC_SAVE_PAGE_AS); | |
255 } | 215 } |
256 | 216 |
257 DownloadItemImpl::~DownloadItemImpl() { | 217 DownloadItemImpl::~DownloadItemImpl() { |
258 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 218 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
259 | 219 |
260 // Should always have been nuked before now, at worst in | 220 // Should always have been nuked before now, at worst in |
261 // DownloadManager shutdown. | 221 // DownloadManager shutdown. |
262 DCHECK(!download_file_.get()); | 222 DCHECK(!download_file_.get()); |
263 | 223 |
264 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadDestroyed(this)); | 224 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadDestroyed(this)); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
323 } | 283 } |
324 current_path_.clear(); | 284 current_path_.clear(); |
325 Remove(); | 285 Remove(); |
326 // We have now been deleted. | 286 // We have now been deleted. |
327 } | 287 } |
328 | 288 |
329 void DownloadItemImpl::Pause() { | 289 void DownloadItemImpl::Pause() { |
330 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 290 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
331 | 291 |
332 // Ignore irrelevant states. | 292 // Ignore irrelevant states. |
333 if (state_ != IN_PROGRESS_INTERNAL || is_paused_) | 293 if (state_ != IN_PROGRESS_INTERNAL || is_paused_ || !request_handle_) |
334 return; | 294 return; |
335 | 295 |
336 request_handle_->PauseRequest(); | 296 request_handle_->PauseRequest(); |
337 is_paused_ = true; | 297 is_paused_ = true; |
338 UpdateObservers(); | 298 UpdateObservers(); |
339 } | 299 } |
340 | 300 |
341 void DownloadItemImpl::Resume() { | 301 void DownloadItemImpl::Resume() { |
342 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 302 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 303 if (!request_handle_) |
| 304 return; |
343 switch (state_) { | 305 switch (state_) { |
344 case IN_PROGRESS_INTERNAL: | 306 case IN_PROGRESS_INTERNAL: |
345 if (!is_paused_) | 307 if (!is_paused_) |
346 return; | 308 return; |
347 request_handle_->ResumeRequest(); | 309 request_handle_->ResumeRequest(); |
348 is_paused_ = false; | 310 is_paused_ = false; |
349 UpdateObservers(); | 311 UpdateObservers(); |
350 return; | 312 return; |
351 | 313 |
352 case COMPLETING_INTERNAL: | 314 case COMPLETING_INTERNAL: |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
388 | 350 |
389 RecordDownloadCount(CANCELLED_COUNT); | 351 RecordDownloadCount(CANCELLED_COUNT); |
390 | 352 |
391 // TODO(rdsmith/benjhayden): Remove condition as part of | 353 // TODO(rdsmith/benjhayden): Remove condition as part of |
392 // |SavePackage| integration. | 354 // |SavePackage| integration. |
393 // |download_file_| can be NULL if Interrupt() is called after the | 355 // |download_file_| can be NULL if Interrupt() is called after the |
394 // download file has been released. | 356 // download file has been released. |
395 if (!is_save_package_download_ && download_file_) | 357 if (!is_save_package_download_ && download_file_) |
396 ReleaseDownloadFile(true); | 358 ReleaseDownloadFile(true); |
397 | 359 |
398 if (state_ == IN_PROGRESS_INTERNAL) { | 360 if (state_ == IN_PROGRESS_INTERNAL && request_handle_) { |
399 // Cancel the originating URL request unless it's already been cancelled | 361 // Cancel the originating URL request unless it's already been cancelled |
400 // by interrupt. | 362 // by interrupt. |
401 request_handle_->CancelRequest(); | 363 request_handle_->CancelRequest(); |
402 } | 364 } |
403 | 365 |
404 // Remove the intermediate file if we are cancelling an interrupted download. | 366 // Remove the intermediate file if we are cancelling an interrupted download. |
405 // Continuable interruptions leave the intermediate file around. | 367 // Continuable interruptions leave the intermediate file around. |
406 if ((state_ == INTERRUPTED_INTERNAL || state_ == RESUMING_INTERNAL) && | 368 if ((state_ == INTERRUPTED_INTERNAL || state_ == RESUMING_INTERNAL) && |
407 !current_path_.empty()) { | 369 !current_path_.empty()) { |
408 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 370 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 return is_temporary_; | 439 return is_temporary_; |
478 } | 440 } |
479 | 441 |
480 bool DownloadItemImpl::CanResume() const { | 442 bool DownloadItemImpl::CanResume() const { |
481 if ((GetState() == IN_PROGRESS) && IsPaused()) | 443 if ((GetState() == IN_PROGRESS) && IsPaused()) |
482 return true; | 444 return true; |
483 | 445 |
484 if (state_ != INTERRUPTED_INTERNAL) | 446 if (state_ != INTERRUPTED_INTERNAL) |
485 return false; | 447 return false; |
486 | 448 |
487 // Downloads that don't have a WebContents should still be resumable, but this | |
488 // isn't currently the case. See ResumeInterruptedDownload(). | |
489 if (!GetWebContents()) | |
490 return false; | |
491 | |
492 ResumeMode resume_mode = GetResumeMode(); | 449 ResumeMode resume_mode = GetResumeMode(); |
493 return IsDownloadResumptionEnabled() && | 450 return IsDownloadResumptionEnabled() && |
494 (resume_mode == RESUME_MODE_USER_RESTART || | 451 (resume_mode == RESUME_MODE_USER_RESTART || |
495 resume_mode == RESUME_MODE_USER_CONTINUE); | 452 resume_mode == RESUME_MODE_USER_CONTINUE); |
496 } | 453 } |
497 | 454 |
498 bool DownloadItemImpl::IsDone() const { | 455 bool DownloadItemImpl::IsDone() const { |
499 switch (state_) { | 456 switch (state_) { |
500 case IN_PROGRESS_INTERNAL: | 457 case IN_PROGRESS_INTERNAL: |
501 case COMPLETING_INTERNAL: | 458 case COMPLETING_INTERNAL: |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
723 | 680 |
724 bool DownloadItemImpl::GetOpened() const { | 681 bool DownloadItemImpl::GetOpened() const { |
725 return opened_; | 682 return opened_; |
726 } | 683 } |
727 | 684 |
728 BrowserContext* DownloadItemImpl::GetBrowserContext() const { | 685 BrowserContext* DownloadItemImpl::GetBrowserContext() const { |
729 return delegate_->GetBrowserContext(); | 686 return delegate_->GetBrowserContext(); |
730 } | 687 } |
731 | 688 |
732 WebContents* DownloadItemImpl::GetWebContents() const { | 689 WebContents* DownloadItemImpl::GetWebContents() const { |
733 // TODO(rdsmith): Remove null check after removing GetWebContents() from | 690 if (route_id_ == GlobalRoutingID()) |
734 // paths that might be used by DownloadItems created from history import. | 691 return NULL; |
735 // Currently such items have null request_handle_s, where other items | 692 |
736 // (regular and SavePackage downloads) have actual objects off the pointer. | 693 RenderViewHostImpl* render_view_host = |
737 if (request_handle_) | 694 RenderViewHostImpl::FromID(route_id_.child_id, route_id_.route_id); |
738 return request_handle_->GetWebContents(); | 695 if (!render_view_host) |
739 return NULL; | 696 return NULL; |
| 697 |
| 698 return render_view_host->GetDelegate()->GetAsWebContents(); |
740 } | 699 } |
741 | 700 |
742 void DownloadItemImpl::OnContentCheckCompleted(DownloadDangerType danger_type) { | 701 void DownloadItemImpl::OnContentCheckCompleted(DownloadDangerType danger_type) { |
743 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 702 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
744 DCHECK(AllDataSaved()); | 703 DCHECK(AllDataSaved()); |
745 VLOG(20) << __FUNCTION__ << " danger_type=" << danger_type | 704 VLOG(20) << __FUNCTION__ << " danger_type=" << danger_type |
746 << " download=" << DebugString(true); | 705 << " download=" << DebugString(true); |
747 SetDangerType(danger_type); | 706 SetDangerType(danger_type); |
748 UpdateObservers(); | 707 UpdateObservers(); |
749 } | 708 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
796 " danger = %d" | 755 " danger = %d" |
797 " all_data_saved = %c" | 756 " all_data_saved = %c" |
798 " last_modified = '%s'" | 757 " last_modified = '%s'" |
799 " etag = '%s'" | 758 " etag = '%s'" |
800 " has_download_file = %s" | 759 " has_download_file = %s" |
801 " url_chain = \n\t\"%s\"\n\t" | 760 " url_chain = \n\t\"%s\"\n\t" |
802 " full_path = \"%" PRFilePath "\"\n\t" | 761 " full_path = \"%" PRFilePath "\"\n\t" |
803 " target_path = \"%" PRFilePath "\"", | 762 " target_path = \"%" PRFilePath "\"", |
804 GetTotalBytes(), | 763 GetTotalBytes(), |
805 GetReceivedBytes(), | 764 GetReceivedBytes(), |
806 InterruptReasonDebugString(last_reason_).c_str(), | 765 DownloadInterruptReasonToString(last_reason_).c_str(), |
807 IsPaused() ? 'T' : 'F', | 766 IsPaused() ? 'T' : 'F', |
808 DebugResumeModeString(GetResumeMode()), | 767 DebugResumeModeString(GetResumeMode()), |
809 auto_resume_count_, | 768 auto_resume_count_, |
810 GetDangerType(), | 769 GetDangerType(), |
811 AllDataSaved() ? 'T' : 'F', | 770 AllDataSaved() ? 'T' : 'F', |
812 GetLastModifiedTime().c_str(), | 771 GetLastModifiedTime().c_str(), |
813 GetETag().c_str(), | 772 GetETag().c_str(), |
814 download_file_.get() ? "true" : "false", | 773 download_file_.get() ? "true" : "false", |
815 url_list.c_str(), | 774 url_list.c_str(), |
816 GetFullPath().value().c_str(), | 775 GetFullPath().value().c_str(), |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
857 case DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT: | 816 case DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT: |
858 if (force_user) | 817 if (force_user) |
859 mode = RESUME_MODE_USER_RESTART; | 818 mode = RESUME_MODE_USER_RESTART; |
860 else | 819 else |
861 mode = RESUME_MODE_IMMEDIATE_RESTART; | 820 mode = RESUME_MODE_IMMEDIATE_RESTART; |
862 break; | 821 break; |
863 | 822 |
864 case DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED: | 823 case DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED: |
865 case DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED: | 824 case DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED: |
866 case DOWNLOAD_INTERRUPT_REASON_NETWORK_SERVER_DOWN: | 825 case DOWNLOAD_INTERRUPT_REASON_NETWORK_SERVER_DOWN: |
| 826 case DOWNLOAD_INTERRUPT_REASON_NETWORK_INVALID_REQUEST: |
867 case DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED: | 827 case DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED: |
868 case DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN: | 828 case DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN: |
869 case DOWNLOAD_INTERRUPT_REASON_CRASH: | 829 case DOWNLOAD_INTERRUPT_REASON_CRASH: |
870 if (force_restart) | 830 if (force_restart) |
871 mode = RESUME_MODE_USER_RESTART; | 831 mode = RESUME_MODE_USER_RESTART; |
872 else | 832 else |
873 mode = RESUME_MODE_USER_CONTINUE; | 833 mode = RESUME_MODE_USER_CONTINUE; |
874 break; | 834 break; |
875 | 835 |
876 case DOWNLOAD_INTERRUPT_REASON_FILE_FAILED: | 836 case DOWNLOAD_INTERRUPT_REASON_FILE_FAILED: |
(...skipping 10 matching lines...) Expand all Loading... |
887 case DOWNLOAD_INTERRUPT_REASON_USER_CANCELED: | 847 case DOWNLOAD_INTERRUPT_REASON_USER_CANCELED: |
888 case DOWNLOAD_INTERRUPT_REASON_FILE_BLOCKED: | 848 case DOWNLOAD_INTERRUPT_REASON_FILE_BLOCKED: |
889 case DOWNLOAD_INTERRUPT_REASON_FILE_SECURITY_CHECK_FAILED: | 849 case DOWNLOAD_INTERRUPT_REASON_FILE_SECURITY_CHECK_FAILED: |
890 mode = RESUME_MODE_INVALID; | 850 mode = RESUME_MODE_INVALID; |
891 break; | 851 break; |
892 } | 852 } |
893 | 853 |
894 return mode; | 854 return mode; |
895 } | 855 } |
896 | 856 |
| 857 void DownloadItemImpl::MergeOriginInfoOnResume( |
| 858 const DownloadCreateInfo& new_create_info) { |
| 859 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 860 DCHECK_EQ(RESUMING_INTERNAL, state_); |
| 861 DCHECK(!new_create_info.url_chain.empty()); |
| 862 |
| 863 // We are going to tack on any new redirects to our list of redirects. |
| 864 std::vector<GURL>::const_iterator chain_iter = |
| 865 new_create_info.url_chain.begin(); |
| 866 if (*chain_iter == url_chain_.back()) |
| 867 ++chain_iter; |
| 868 url_chain_.insert( |
| 869 url_chain_.end(), chain_iter, new_create_info.url_chain.end()); |
| 870 // TODO(asanka): Measure how URL chains change with resumption. Resumption |
| 871 // requests are issued against the actual download URL and we don't expect any |
| 872 // redirects. |
| 873 |
| 874 // If the server precondition failed, then the download will be resumed |
| 875 // automatically without validators. |
| 876 etag_ = new_create_info.etag; |
| 877 last_modified_time_ = new_create_info.last_modified; |
| 878 content_disposition_ = new_create_info.content_disposition; |
| 879 // TODO(asanka): Measure how validators change with resumption. I.e. An ETag |
| 880 // should only change if we used it and the server responded with |
| 881 // HTTP_PRECONDITION_FAILED. |
| 882 |
| 883 // Don't update observers. This method is expected to be called just before a |
| 884 // DownloadFile is created and Start() is called. The observers will be |
| 885 // notified when the download transitions to the IN_PROGRESS state. |
| 886 } |
| 887 |
897 void DownloadItemImpl::NotifyRemoved() { | 888 void DownloadItemImpl::NotifyRemoved() { |
898 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadRemoved(this)); | 889 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadRemoved(this)); |
899 } | 890 } |
900 | 891 |
901 void DownloadItemImpl::OnDownloadedFileRemoved() { | 892 void DownloadItemImpl::OnDownloadedFileRemoved() { |
902 file_externally_removed_ = true; | 893 file_externally_removed_ = true; |
903 VLOG(20) << __FUNCTION__ << " download=" << DebugString(true); | 894 VLOG(20) << __FUNCTION__ << " download=" << DebugString(true); |
904 UpdateObservers(); | 895 UpdateObservers(); |
905 } | 896 } |
906 | 897 |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1026 net::NetLog::TYPE_DOWNLOAD_ITEM_ACTIVE, active_data); | 1017 net::NetLog::TYPE_DOWNLOAD_ITEM_ACTIVE, active_data); |
1027 } else { | 1018 } else { |
1028 bound_net_log_.AddEvent( | 1019 bound_net_log_.AddEvent( |
1029 net::NetLog::TYPE_DOWNLOAD_ITEM_ACTIVE, active_data); | 1020 net::NetLog::TYPE_DOWNLOAD_ITEM_ACTIVE, active_data); |
1030 } | 1021 } |
1031 | 1022 |
1032 VLOG(20) << __FUNCTION__ << "() " << DebugString(true); | 1023 VLOG(20) << __FUNCTION__ << "() " << DebugString(true); |
1033 } | 1024 } |
1034 | 1025 |
1035 // We're starting the download. | 1026 // We're starting the download. |
1036 void DownloadItemImpl::Start( | 1027 void DownloadItemImpl::Start(scoped_ptr<DownloadFile> file, |
1037 scoped_ptr<DownloadFile> file, | 1028 scoped_ptr<DownloadRequestHandle> req_handle) { |
1038 scoped_ptr<DownloadRequestHandleInterface> req_handle) { | |
1039 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1029 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1040 DCHECK(!download_file_.get()); | 1030 DCHECK(!download_file_.get()); |
1041 DCHECK(file.get()); | 1031 DCHECK(file.get()); |
1042 DCHECK(req_handle.get()); | 1032 DCHECK(req_handle.get()); |
1043 | 1033 |
1044 download_file_ = file.Pass(); | 1034 download_file_ = file.Pass(); |
1045 request_handle_ = req_handle.Pass(); | 1035 request_handle_ = req_handle.Pass(); |
1046 | 1036 |
1047 if (GetState() == CANCELLED) { | 1037 if (GetState() == CANCELLED) { |
1048 // The download was in the process of resuming when it was cancelled. Don't | 1038 // The download was in the process of resuming when it was cancelled. Don't |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1325 // we still need to set it auto-opened so that it can be removed from the | 1315 // we still need to set it auto-opened so that it can be removed from the |
1326 // download shelf. | 1316 // download shelf. |
1327 if (!IsTemporary()) | 1317 if (!IsTemporary()) |
1328 OpenDownload(); | 1318 OpenDownload(); |
1329 | 1319 |
1330 auto_opened_ = true; | 1320 auto_opened_ = true; |
1331 UpdateObservers(); | 1321 UpdateObservers(); |
1332 } | 1322 } |
1333 } | 1323 } |
1334 | 1324 |
1335 void DownloadItemImpl::OnResumeRequestStarted(DownloadItem* item, | 1325 void DownloadItemImpl::OnResumeRequestStarted( |
1336 net::Error error) { | 1326 DownloadItem* item, |
| 1327 DownloadInterruptReason interrupt_reason) { |
1337 // If |item| is not NULL, then Start() has been called already, and nothing | 1328 // If |item| is not NULL, then Start() has been called already, and nothing |
1338 // more needs to be done here. | 1329 // more needs to be done here. |
1339 if (item) { | 1330 if (item) { |
1340 DCHECK_EQ(net::OK, error); | 1331 DCHECK_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, interrupt_reason); |
1341 DCHECK_EQ(static_cast<DownloadItem*>(this), item); | 1332 DCHECK_EQ(static_cast<DownloadItem*>(this), item); |
1342 return; | 1333 return; |
1343 } | 1334 } |
1344 // Otherwise, the request failed without passing through | 1335 // Otherwise, the request failed without passing through |
1345 // DownloadResourceHandler::OnResponseStarted. | 1336 // DownloadResourceHandler::OnResponseStarted. |
1346 if (error == net::OK) | 1337 DCHECK_NE(DOWNLOAD_INTERRUPT_REASON_NONE, interrupt_reason); |
1347 error = net::ERR_FAILED; | 1338 Interrupt(interrupt_reason); |
1348 DownloadInterruptReason reason = | |
1349 ConvertNetErrorToInterruptReason(error, DOWNLOAD_INTERRUPT_FROM_NETWORK); | |
1350 DCHECK_NE(DOWNLOAD_INTERRUPT_REASON_NONE, reason); | |
1351 Interrupt(reason); | |
1352 } | 1339 } |
1353 | 1340 |
1354 // **** End of Download progression cascade | 1341 // **** End of Download progression cascade |
1355 | 1342 |
1356 // An error occurred somewhere. | 1343 // An error occurred somewhere. |
1357 void DownloadItemImpl::Interrupt(DownloadInterruptReason reason) { | 1344 void DownloadItemImpl::Interrupt(DownloadInterruptReason reason) { |
1358 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1345 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1359 | 1346 |
1360 // Somewhat counter-intuitively, it is possible for us to receive an | 1347 // Somewhat counter-intuitively, it is possible for us to receive an |
1361 // interrupt after we've already been interrupted. The generation of | 1348 // interrupt after we've already been interrupted. The generation of |
(...skipping 14 matching lines...) Expand all Loading... |
1376 | 1363 |
1377 if (state_ == IN_PROGRESS_INTERNAL) { | 1364 if (state_ == IN_PROGRESS_INTERNAL) { |
1378 // Cancel (delete file) if we're going to restart; no point in leaving | 1365 // Cancel (delete file) if we're going to restart; no point in leaving |
1379 // data around we aren't going to use. Also cancel if resumption isn't | 1366 // data around we aren't going to use. Also cancel if resumption isn't |
1380 // enabled for the same reason. | 1367 // enabled for the same reason. |
1381 ReleaseDownloadFile(resume_mode == RESUME_MODE_IMMEDIATE_RESTART || | 1368 ReleaseDownloadFile(resume_mode == RESUME_MODE_IMMEDIATE_RESTART || |
1382 resume_mode == RESUME_MODE_USER_RESTART || | 1369 resume_mode == RESUME_MODE_USER_RESTART || |
1383 !IsDownloadResumptionEnabled()); | 1370 !IsDownloadResumptionEnabled()); |
1384 | 1371 |
1385 // Cancel the originating URL request. | 1372 // Cancel the originating URL request. |
1386 request_handle_->CancelRequest(); | 1373 if (request_handle_) |
| 1374 request_handle_->CancelRequest(); |
1387 } else { | 1375 } else { |
1388 DCHECK(!download_file_.get()); | 1376 DCHECK(!download_file_.get()); |
1389 } | 1377 } |
1390 | 1378 |
1391 // Reset all data saved, as even if we did save all the data we're going | 1379 // Reset all data saved, as even if we did save all the data we're going |
1392 // to go through another round of downloading when we resume. | 1380 // to go through another round of downloading when we resume. |
1393 // There's a potential problem here in the abstract, as if we did download | 1381 // There's a potential problem here in the abstract, as if we did download |
1394 // all the data and then run into a continuable error, on resumption we | 1382 // all the data and then run into a continuable error, on resumption we |
1395 // won't download any more data. However, a) there are currently no | 1383 // won't download any more data. However, a) there are currently no |
1396 // continuable errors that can occur after we download all the data, and | 1384 // continuable errors that can occur after we download all the data, and |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1583 // If the flag for downloads resumption isn't enabled, ignore | 1571 // If the flag for downloads resumption isn't enabled, ignore |
1584 // this request. | 1572 // this request. |
1585 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 1573 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
1586 if (!command_line.HasSwitch(switches::kEnableDownloadResumption)) | 1574 if (!command_line.HasSwitch(switches::kEnableDownloadResumption)) |
1587 return; | 1575 return; |
1588 | 1576 |
1589 // If we're not interrupted, ignore the request; our caller is drunk. | 1577 // If we're not interrupted, ignore the request; our caller is drunk. |
1590 if (state_ != INTERRUPTED_INTERNAL) | 1578 if (state_ != INTERRUPTED_INTERNAL) |
1591 return; | 1579 return; |
1592 | 1580 |
1593 // If we can't get a web contents, we can't resume the download. | |
1594 // TODO(rdsmith): Find some alternative web contents to use--this | |
1595 // means we can't restart a download if it's a download imported | |
1596 // from the history. | |
1597 if (!GetWebContents()) | |
1598 return; | |
1599 | |
1600 // Reset the appropriate state if restarting. | 1581 // Reset the appropriate state if restarting. |
1601 ResumeMode mode = GetResumeMode(); | 1582 ResumeMode mode = GetResumeMode(); |
1602 if (mode == RESUME_MODE_IMMEDIATE_RESTART || | 1583 if (mode == RESUME_MODE_IMMEDIATE_RESTART || |
1603 mode == RESUME_MODE_USER_RESTART) { | 1584 mode == RESUME_MODE_USER_RESTART) { |
1604 received_bytes_ = 0; | 1585 received_bytes_ = 0; |
1605 hash_state_ = ""; | 1586 hash_state_ = ""; |
1606 last_modified_time_ = ""; | 1587 last_modified_time_ = ""; |
1607 etag_ = ""; | 1588 etag_ = ""; |
1608 } | 1589 } |
1609 | 1590 |
| 1591 // Just in case we were interrupted while paused. |
| 1592 is_paused_ = false; |
| 1593 |
| 1594 // TODO(asanka): The resource context may not be correct if the original |
| 1595 // request was associated with a different storage partition. |
1610 scoped_ptr<DownloadUrlParameters> download_params( | 1596 scoped_ptr<DownloadUrlParameters> download_params( |
1611 DownloadUrlParameters::FromWebContents(GetWebContents(), | 1597 new DownloadUrlParameters(GetOriginalUrl(), |
1612 GetOriginalUrl())); | 1598 route_id_.child_id, |
| 1599 route_id_.route_id, |
| 1600 GetBrowserContext()->GetResourceContext())); |
1613 | 1601 |
1614 download_params->set_file_path(GetFullPath()); | 1602 download_params->set_file_path(GetFullPath()); |
1615 download_params->set_offset(GetReceivedBytes()); | 1603 download_params->set_offset(GetReceivedBytes()); |
1616 download_params->set_hash_state(GetHashState()); | 1604 download_params->set_hash_state(GetHashState()); |
1617 download_params->set_last_modified(GetLastModifiedTime()); | 1605 download_params->set_last_modified(GetLastModifiedTime()); |
1618 download_params->set_etag(GetETag()); | 1606 download_params->set_etag(GetETag()); |
1619 download_params->set_callback( | 1607 download_params->set_callback( |
1620 base::Bind(&DownloadItemImpl::OnResumeRequestStarted, | 1608 base::Bind(&DownloadItemImpl::OnResumeRequestStarted, |
1621 weak_ptr_factory_.GetWeakPtr())); | 1609 weak_ptr_factory_.GetWeakPtr())); |
1622 | 1610 |
1623 delegate_->ResumeInterruptedDownload(download_params.Pass(), GetId()); | 1611 delegate_->ResumeInterruptedDownload(download_params.Pass(), GetId()); |
1624 // Just in case we were interrupted while paused. | |
1625 is_paused_ = false; | |
1626 | 1612 |
1627 TransitionTo(RESUMING_INTERNAL, DONT_UPDATE_OBSERVERS); | 1613 TransitionTo(RESUMING_INTERNAL, DONT_UPDATE_OBSERVERS); |
1628 } | 1614 } |
1629 | 1615 |
1630 // static | 1616 // static |
1631 DownloadItem::DownloadState DownloadItemImpl::InternalToExternalState( | 1617 DownloadItem::DownloadState DownloadItemImpl::InternalToExternalState( |
1632 DownloadInternalState internal_state) { | 1618 DownloadInternalState internal_state) { |
1633 switch (internal_state) { | 1619 switch (internal_state) { |
1634 case IN_PROGRESS_INTERNAL: | 1620 case IN_PROGRESS_INTERNAL: |
1635 return IN_PROGRESS; | 1621 return IN_PROGRESS; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1702 case RESUME_MODE_USER_CONTINUE: | 1688 case RESUME_MODE_USER_CONTINUE: |
1703 return "USER_CONTINUE"; | 1689 return "USER_CONTINUE"; |
1704 case RESUME_MODE_USER_RESTART: | 1690 case RESUME_MODE_USER_RESTART: |
1705 return "USER_RESTART"; | 1691 return "USER_RESTART"; |
1706 } | 1692 } |
1707 NOTREACHED() << "Unknown resume mode " << mode; | 1693 NOTREACHED() << "Unknown resume mode " << mode; |
1708 return "unknown"; | 1694 return "unknown"; |
1709 } | 1695 } |
1710 | 1696 |
1711 } // namespace content | 1697 } // namespace content |
OLD | NEW |