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

Side by Side Diff: content/browser/download/download_item_impl.cc

Issue 23496076: WIP - Refactor programmatic downloads Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « content/browser/download/download_item_impl.h ('k') | content/browser/download/download_item_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698