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

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

Issue 148133007: [Downloads] Always call DM::StartDownload() for explicit downloads. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comments Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View 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 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 has_user_gesture_(info.has_user_gesture), 185 has_user_gesture_(info.has_user_gesture),
186 content_disposition_(info.content_disposition), 186 content_disposition_(info.content_disposition),
187 mime_type_(info.mime_type), 187 mime_type_(info.mime_type),
188 original_mime_type_(info.original_mime_type), 188 original_mime_type_(info.original_mime_type),
189 remote_address_(info.remote_address), 189 remote_address_(info.remote_address),
190 total_bytes_(info.total_bytes), 190 total_bytes_(info.total_bytes),
191 received_bytes_(0), 191 received_bytes_(0),
192 bytes_per_sec_(0), 192 bytes_per_sec_(0),
193 last_modified_time_(info.last_modified), 193 last_modified_time_(info.last_modified),
194 etag_(info.etag), 194 etag_(info.etag),
195 last_reason_(DOWNLOAD_INTERRUPT_REASON_NONE), 195 last_reason_(info.result),
196 start_tick_(base::TimeTicks::Now()), 196 start_tick_(base::TimeTicks::Now()),
197 state_(INITIAL_INTERNAL), 197 state_(INITIAL_INTERNAL),
198 danger_type_(DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS), 198 danger_type_(DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS),
199 start_time_(info.start_time), 199 start_time_(info.start_time),
200 delegate_(delegate), 200 delegate_(delegate),
201 is_paused_(false), 201 is_paused_(false),
202 auto_resume_count_(0), 202 auto_resume_count_(0),
203 open_when_complete_(false), 203 open_when_complete_(false),
204 file_externally_removed_(false), 204 file_externally_removed_(false),
205 auto_opened_(false), 205 auto_opened_(false),
206 is_temporary_(!info.save_info->file_path.empty()), 206 is_temporary_(!info.save_info->file_path.empty()),
207 all_data_saved_(false), 207 all_data_saved_(false),
208 destination_error_(content::DOWNLOAD_INTERRUPT_REASON_NONE), 208 destination_error_(DOWNLOAD_INTERRUPT_REASON_NONE),
209 opened_(false), 209 opened_(false),
210 delegate_delayed_complete_(false), 210 delegate_delayed_complete_(false),
211 bound_net_log_(bound_net_log), 211 bound_net_log_(bound_net_log),
212 weak_ptr_factory_(this) { 212 weak_ptr_factory_(this) {
213 delegate_->Attach(); 213 delegate_->Attach();
214 Init(true /* actively downloading */, SRC_ACTIVE_DOWNLOAD); 214 Init(true /* actively downloading */, SRC_ACTIVE_DOWNLOAD);
215 215
216 // Link the event sources. 216 // Link the event sources.
217 bound_net_log_.AddEvent( 217 bound_net_log_.AddEvent(
218 net::NetLog::TYPE_DOWNLOAD_URL_REQUEST, 218 net::NetLog::TYPE_DOWNLOAD_URL_REQUEST,
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 } 288 }
289 289
290 void DownloadItemImpl::RemoveObserver(Observer* observer) { 290 void DownloadItemImpl::RemoveObserver(Observer* observer) {
291 DCHECK_CURRENTLY_ON(BrowserThread::UI); 291 DCHECK_CURRENTLY_ON(BrowserThread::UI);
292 292
293 observers_.RemoveObserver(observer); 293 observers_.RemoveObserver(observer);
294 } 294 }
295 295
296 void DownloadItemImpl::UpdateObservers() { 296 void DownloadItemImpl::UpdateObservers() {
297 DCHECK_CURRENTLY_ON(BrowserThread::UI); 297 DCHECK_CURRENTLY_ON(BrowserThread::UI);
298 DVLOG(20) << __FUNCTION__ << "()";
298 299
299 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadUpdated(this)); 300 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadUpdated(this));
300 } 301 }
301 302
302 void DownloadItemImpl::ValidateDangerousDownload() { 303 void DownloadItemImpl::ValidateDangerousDownload() {
303 DCHECK_CURRENTLY_ON(BrowserThread::UI); 304 DCHECK_CURRENTLY_ON(BrowserThread::UI);
304 DCHECK(!IsDone()); 305 DCHECK(!IsDone());
305 DCHECK(IsDangerous()); 306 DCHECK(IsDangerous());
306 307
307 DVLOG(20) << __FUNCTION__ << " download=" << DebugString(true); 308 DVLOG(20) << __FUNCTION__ << " download=" << DebugString(true);
308 309
309 if (IsDone() || !IsDangerous()) 310 if (IsDone() || !IsDangerous())
310 return; 311 return;
311 312
312 RecordDangerousDownloadAccept(GetDangerType(), 313 RecordDangerousDownloadAccept(GetDangerType(),
313 GetTargetFilePath()); 314 GetTargetFilePath());
314 315
315 danger_type_ = DOWNLOAD_DANGER_TYPE_USER_VALIDATED; 316 danger_type_ = DOWNLOAD_DANGER_TYPE_USER_VALIDATED;
316 317
317 bound_net_log_.AddEvent( 318 bound_net_log_.AddEvent(
318 net::NetLog::TYPE_DOWNLOAD_ITEM_SAFETY_STATE_UPDATED, 319 net::NetLog::TYPE_DOWNLOAD_ITEM_SAFETY_STATE_UPDATED,
319 base::Bind(&ItemCheckedNetLogCallback, GetDangerType())); 320 base::Bind(&ItemCheckedNetLogCallback, GetDangerType()));
320 321
321 UpdateObservers(); 322 UpdateObservers(); // TODO(asanka): This is potentially unsafe. The download
323 // may not be in a consistent state or around at all after
324 // invoking observers.
Randy Smith (Not in Mondays) 2016/02/12 19:10:28 I presume there are no observers that do anything
asanka 2016/02/12 20:52:28 Yeah. None of the observers do anything crazy, but
322 325
323 MaybeCompleteDownload(); 326 MaybeCompleteDownload();
324 } 327 }
325 328
326 void DownloadItemImpl::StealDangerousDownload( 329 void DownloadItemImpl::StealDangerousDownload(
327 const AcquireFileCallback& callback) { 330 const AcquireFileCallback& callback) {
328 DVLOG(20) << __FUNCTION__ << "() download = " << DebugString(true); 331 DVLOG(20) << __FUNCTION__ << "() download = " << DebugString(true);
329 DCHECK_CURRENTLY_ON(BrowserThread::UI); 332 DCHECK_CURRENTLY_ON(BrowserThread::UI);
330 DCHECK(IsDangerous()); 333 DCHECK(IsDangerous());
331 334
(...skipping 22 matching lines...) Expand all
354 case INITIAL_INTERNAL: 357 case INITIAL_INTERNAL:
355 case COMPLETING_INTERNAL: 358 case COMPLETING_INTERNAL:
356 case COMPLETE_INTERNAL: 359 case COMPLETE_INTERNAL:
357 case INTERRUPTED_INTERNAL: 360 case INTERRUPTED_INTERNAL:
358 case CANCELLED_INTERNAL: 361 case CANCELLED_INTERNAL:
359 case RESUMING_INTERNAL: 362 case RESUMING_INTERNAL:
360 // No active request. 363 // No active request.
361 return; 364 return;
362 365
363 case TARGET_PENDING_INTERNAL: 366 case TARGET_PENDING_INTERNAL:
367 case INTERRUPTED_TARGET_PENDING_INTERNAL:
Randy Smith (Not in Mondays) 2016/02/12 21:57:19 Hasn't the request already failed, or doesn't exis
asanka 2016/02/12 23:34:47 True. Moved to the no-op block above.
364 case IN_PROGRESS_INTERNAL: 368 case IN_PROGRESS_INTERNAL:
365 request_handle_->PauseRequest(); 369 request_handle_->PauseRequest();
366 is_paused_ = true; 370 is_paused_ = true;
367 UpdateObservers(); 371 UpdateObservers();
368 return; 372 return;
369 373
370 case MAX_DOWNLOAD_INTERNAL_STATE: 374 case MAX_DOWNLOAD_INTERNAL_STATE:
371 case TARGET_RESOLVED_INTERNAL: 375 case TARGET_RESOLVED_INTERNAL:
372 NOTREACHED(); 376 NOTREACHED();
373 } 377 }
374 } 378 }
375 379
376 void DownloadItemImpl::Resume() { 380 void DownloadItemImpl::Resume() {
377 DCHECK_CURRENTLY_ON(BrowserThread::UI); 381 DCHECK_CURRENTLY_ON(BrowserThread::UI);
382 DVLOG(20) << __FUNCTION__ << "() download = " << DebugString(true);
378 switch (state_) { 383 switch (state_) {
379 case INITIAL_INTERNAL: 384 case INITIAL_INTERNAL:
380 case COMPLETING_INTERNAL: 385 case COMPLETING_INTERNAL:
381 case COMPLETE_INTERNAL: 386 case COMPLETE_INTERNAL:
382 case CANCELLED_INTERNAL: 387 case CANCELLED_INTERNAL: // Nothing to resume.
383 // Nothing to resume. 388 case RESUMING_INTERNAL: // Resumption in progress.
384 case RESUMING_INTERNAL:
385 // Resumption in progress.
386 DCHECK(!is_paused_);
387 return; 389 return;
388 390
389 case TARGET_PENDING_INTERNAL: 391 case TARGET_PENDING_INTERNAL:
392 case INTERRUPTED_TARGET_PENDING_INTERNAL:
Randy Smith (Not in Mondays) 2016/02/12 21:57:19 Same as above.
asanka 2016/02/12 23:34:47 Same.
390 case IN_PROGRESS_INTERNAL: 393 case IN_PROGRESS_INTERNAL:
391 if (!is_paused_) 394 if (!is_paused_)
392 return; 395 return;
393 request_handle_->ResumeRequest(); 396 request_handle_->ResumeRequest();
394 is_paused_ = false; 397 is_paused_ = false;
395 UpdateObservers(); 398 UpdateObservers();
396 return; 399 return;
397 400
398 case INTERRUPTED_INTERNAL: 401 case INTERRUPTED_INTERNAL:
399 auto_resume_count_ = 0; // User input resets the counter. 402 auto_resume_count_ = 0; // User input resets the counter.
400 ResumeInterruptedDownload(); 403 ResumeInterruptedDownload();
404 UpdateObservers();
401 return; 405 return;
402 406
403 case MAX_DOWNLOAD_INTERNAL_STATE: 407 case MAX_DOWNLOAD_INTERNAL_STATE:
404 case TARGET_RESOLVED_INTERNAL: 408 case TARGET_RESOLVED_INTERNAL:
405 NOTREACHED(); 409 NOTREACHED();
406 } 410 }
407 } 411 }
408 412
409 void DownloadItemImpl::Cancel(bool user_cancel) { 413 void DownloadItemImpl::Cancel(bool user_cancel) {
410 DCHECK_CURRENTLY_ON(BrowserThread::UI); 414 DCHECK_CURRENTLY_ON(BrowserThread::UI);
411 DVLOG(20) << __FUNCTION__ << "() download = " << DebugString(true); 415 DVLOG(20) << __FUNCTION__ << "() download = " << DebugString(true);
412 Interrupt(user_cancel ? DOWNLOAD_INTERRUPT_REASON_USER_CANCELED 416 Interrupt(user_cancel ? DOWNLOAD_INTERRUPT_REASON_USER_CANCELED
413 : DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN); 417 : DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN);
418 UpdateObservers();
414 } 419 }
415 420
416 void DownloadItemImpl::Remove() { 421 void DownloadItemImpl::Remove() {
417 DVLOG(20) << __FUNCTION__ << "() download = " << DebugString(true); 422 DVLOG(20) << __FUNCTION__ << "() download = " << DebugString(true);
418 DCHECK_CURRENTLY_ON(BrowserThread::UI); 423 DCHECK_CURRENTLY_ON(BrowserThread::UI);
419 424
420 delegate_->AssertStateConsistent(this); 425 delegate_->AssertStateConsistent(this);
421 Interrupt(DOWNLOAD_INTERRUPT_REASON_USER_CANCELED); 426 Interrupt(DOWNLOAD_INTERRUPT_REASON_USER_CANCELED);
427 UpdateObservers();
422 delegate_->AssertStateConsistent(this); 428 delegate_->AssertStateConsistent(this);
423 429
424 NotifyRemoved(); 430 NotifyRemoved();
425 delegate_->DownloadRemoved(this); 431 delegate_->DownloadRemoved(this);
426 // We have now been deleted. 432 // We have now been deleted.
427 } 433 }
428 434
429 void DownloadItemImpl::OpenDownload() { 435 void DownloadItemImpl::OpenDownload() {
430 DCHECK_CURRENTLY_ON(BrowserThread::UI); 436 DCHECK_CURRENTLY_ON(BrowserThread::UI);
431 437
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 } 484 }
479 485
480 bool DownloadItemImpl::CanResume() const { 486 bool DownloadItemImpl::CanResume() const {
481 DCHECK_CURRENTLY_ON(BrowserThread::UI); 487 DCHECK_CURRENTLY_ON(BrowserThread::UI);
482 switch (state_) { 488 switch (state_) {
483 case INITIAL_INTERNAL: 489 case INITIAL_INTERNAL:
484 case COMPLETING_INTERNAL: 490 case COMPLETING_INTERNAL:
485 case COMPLETE_INTERNAL: 491 case COMPLETE_INTERNAL:
486 case CANCELLED_INTERNAL: 492 case CANCELLED_INTERNAL:
487 case RESUMING_INTERNAL: 493 case RESUMING_INTERNAL:
494 case INTERRUPTED_TARGET_PENDING_INTERNAL:
488 return false; 495 return false;
489 496
490 case TARGET_PENDING_INTERNAL: 497 case TARGET_PENDING_INTERNAL:
491 case TARGET_RESOLVED_INTERNAL: 498 case TARGET_RESOLVED_INTERNAL:
492 case IN_PROGRESS_INTERNAL: 499 case IN_PROGRESS_INTERNAL:
493 return is_paused_; 500 return is_paused_;
494 501
495 case INTERRUPTED_INTERNAL: { 502 case INTERRUPTED_INTERNAL: {
496 ResumeMode resume_mode = GetResumeMode(); 503 ResumeMode resume_mode = GetResumeMode();
497 // Only allow Resume() calls if the resumption mode requires a user 504 // Only allow Resume() calls if the resumption mode requires a user
498 // action. 505 // action.
499 return IsDownloadResumptionEnabled() && 506 return IsDownloadResumptionEnabled() &&
500 (resume_mode == RESUME_MODE_USER_RESTART || 507 (resume_mode == RESUME_MODE_USER_RESTART ||
501 resume_mode == RESUME_MODE_USER_CONTINUE); 508 resume_mode == RESUME_MODE_USER_CONTINUE);
502 } 509 }
503 510
504 case MAX_DOWNLOAD_INTERNAL_STATE: 511 case MAX_DOWNLOAD_INTERNAL_STATE:
505 NOTREACHED(); 512 NOTREACHED();
506 } 513 }
507 return false; 514 return false;
508 } 515 }
509 516
510 bool DownloadItemImpl::IsDone() const { 517 bool DownloadItemImpl::IsDone() const {
511 switch (state_) { 518 switch (state_) {
512 case INITIAL_INTERNAL: 519 case INITIAL_INTERNAL:
513 case COMPLETING_INTERNAL: 520 case COMPLETING_INTERNAL:
514 case RESUMING_INTERNAL: 521 case RESUMING_INTERNAL:
515 case TARGET_PENDING_INTERNAL: 522 case TARGET_PENDING_INTERNAL:
523 case INTERRUPTED_TARGET_PENDING_INTERNAL:
516 case TARGET_RESOLVED_INTERNAL: 524 case TARGET_RESOLVED_INTERNAL:
517 case IN_PROGRESS_INTERNAL: 525 case IN_PROGRESS_INTERNAL:
518 return false; 526 return false;
519 527
520 case COMPLETE_INTERNAL: 528 case COMPLETE_INTERNAL:
521 case CANCELLED_INTERNAL: 529 case CANCELLED_INTERNAL:
522 return true; 530 return true;
523 531
524 case INTERRUPTED_INTERNAL: 532 case INTERRUPTED_INTERNAL:
525 return !CanResume(); 533 return !CanResume();
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
930 case DOWNLOAD_INTERRUPT_REASON_SERVER_UNAUTHORIZED: 938 case DOWNLOAD_INTERRUPT_REASON_SERVER_UNAUTHORIZED:
931 case DOWNLOAD_INTERRUPT_REASON_SERVER_CERT_PROBLEM: 939 case DOWNLOAD_INTERRUPT_REASON_SERVER_CERT_PROBLEM:
932 case DOWNLOAD_INTERRUPT_REASON_SERVER_FORBIDDEN: 940 case DOWNLOAD_INTERRUPT_REASON_SERVER_FORBIDDEN:
933 mode = RESUME_MODE_INVALID; 941 mode = RESUME_MODE_INVALID;
934 break; 942 break;
935 } 943 }
936 944
937 return mode; 945 return mode;
938 } 946 }
939 947
940 void DownloadItemImpl::MergeOriginInfoOnResume( 948 void DownloadItemImpl::UpdateValidatorsOnResumption(
941 const DownloadCreateInfo& new_create_info) { 949 const DownloadCreateInfo& new_create_info) {
942 DCHECK_CURRENTLY_ON(BrowserThread::UI); 950 DCHECK_CURRENTLY_ON(BrowserThread::UI);
943 DCHECK_EQ(RESUMING_INTERNAL, state_); 951 DCHECK_EQ(RESUMING_INTERNAL, state_);
944 DCHECK(!new_create_info.url_chain.empty()); 952 DCHECK(!new_create_info.url_chain.empty());
945 953
946 // We are going to tack on any new redirects to our list of redirects. 954 // We are going to tack on any new redirects to our list of redirects.
947 // When a download is resumed, the URL used for the resumption request is the 955 // When a download is resumed, the URL used for the resumption request is the
948 // one at the end of the previous redirect chain. Tacking additional redirects 956 // one at the end of the previous redirect chain. Tacking additional redirects
949 // to the end of this chain ensures that: 957 // to the end of this chain ensures that:
950 // - If the download needs to be resumed again, the ETag/Last-Modified headers 958 // - If the download needs to be resumed again, the ETag/Last-Modified headers
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1015 hash_state_ = ""; 1023 hash_state_ = "";
1016 1024
1017 UpdateObservers(); 1025 UpdateObservers();
1018 } 1026 }
1019 1027
1020 void DownloadItemImpl::MarkAsComplete() { 1028 void DownloadItemImpl::MarkAsComplete() {
1021 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1029 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1022 1030
1023 DCHECK(all_data_saved_); 1031 DCHECK(all_data_saved_);
1024 end_time_ = base::Time::Now(); 1032 end_time_ = base::Time::Now();
1025 TransitionTo(COMPLETE_INTERNAL, UPDATE_OBSERVERS); 1033 TransitionTo(COMPLETE_INTERNAL);
1034 UpdateObservers();
1026 } 1035 }
1027 1036
1028 void DownloadItemImpl::DestinationUpdate(int64_t bytes_so_far, 1037 void DownloadItemImpl::DestinationUpdate(int64_t bytes_so_far,
1029 int64_t bytes_per_sec, 1038 int64_t bytes_per_sec,
1030 const std::string& hash_state) { 1039 const std::string& hash_state) {
1031 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1040 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1032 // If the download is in any other state we don't expect any 1041 // If the download is in any other state we don't expect any
1033 // DownloadDestinationObserver callbacks. An interruption or a cancellation 1042 // DownloadDestinationObserver callbacks. An interruption or a cancellation
1034 // results in a call to ReleaseDownloadFile which invalidates the weak 1043 // results in a call to ReleaseDownloadFile which invalidates the weak
1035 // reference held by the DownloadFile and hence cuts off any pending 1044 // reference held by the DownloadFile and hence cuts off any pending
(...skipping 28 matching lines...) Expand all
1064 // results in a call to ReleaseDownloadFile which invalidates the weak 1073 // results in a call to ReleaseDownloadFile which invalidates the weak
1065 // reference held by the DownloadFile and hence cuts off any pending 1074 // reference held by the DownloadFile and hence cuts off any pending
1066 // callbacks. 1075 // callbacks.
1067 DCHECK(state_ == TARGET_PENDING_INTERNAL || state_ == IN_PROGRESS_INTERNAL); 1076 DCHECK(state_ == TARGET_PENDING_INTERNAL || state_ == IN_PROGRESS_INTERNAL);
1068 DVLOG(20) << __FUNCTION__ 1077 DVLOG(20) << __FUNCTION__
1069 << "() reason:" << DownloadInterruptReasonToString(reason); 1078 << "() reason:" << DownloadInterruptReasonToString(reason);
1070 1079
1071 // Postpone recognition of this error until after file name determination 1080 // Postpone recognition of this error until after file name determination
1072 // has completed and the intermediate file has been renamed to simplify 1081 // has completed and the intermediate file has been renamed to simplify
1073 // resumption conditions. 1082 // resumption conditions.
1074 if (state_ != IN_PROGRESS_INTERNAL) 1083 if (state_ == TARGET_PENDING_INTERNAL) {
1075 destination_error_ = reason; 1084 destination_error_ = reason;
1076 else 1085 return;
1077 Interrupt(reason); 1086 }
1087 Interrupt(reason);
1088 UpdateObservers();
1078 } 1089 }
1079 1090
1080 void DownloadItemImpl::DestinationCompleted(const std::string& final_hash) { 1091 void DownloadItemImpl::DestinationCompleted(const std::string& final_hash) {
1081 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1092 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1082 // If the download is in any other state we don't expect any 1093 // If the download is in any other state we don't expect any
1083 // DownloadDestinationObserver callbacks. An interruption or a cancellation 1094 // DownloadDestinationObserver callbacks. An interruption or a cancellation
1084 // results in a call to ReleaseDownloadFile which invalidates the weak 1095 // results in a call to ReleaseDownloadFile which invalidates the weak
1085 // reference held by the DownloadFile and hence cuts off any pending 1096 // reference held by the DownloadFile and hence cuts off any pending
1086 // callbacks. 1097 // callbacks.
1087 DCHECK(state_ == TARGET_PENDING_INTERNAL || state_ == IN_PROGRESS_INTERNAL); 1098 DCHECK(state_ == TARGET_PENDING_INTERNAL || state_ == IN_PROGRESS_INTERNAL);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1124 bound_net_log_.AddEvent( 1135 bound_net_log_.AddEvent(
1125 net::NetLog::TYPE_DOWNLOAD_ITEM_ACTIVE, active_data); 1136 net::NetLog::TYPE_DOWNLOAD_ITEM_ACTIVE, active_data);
1126 } 1137 }
1127 1138
1128 DVLOG(20) << __FUNCTION__ << "() " << DebugString(true); 1139 DVLOG(20) << __FUNCTION__ << "() " << DebugString(true);
1129 } 1140 }
1130 1141
1131 // We're starting the download. 1142 // We're starting the download.
1132 void DownloadItemImpl::Start( 1143 void DownloadItemImpl::Start(
1133 scoped_ptr<DownloadFile> file, 1144 scoped_ptr<DownloadFile> file,
1134 scoped_ptr<DownloadRequestHandleInterface> req_handle) { 1145 scoped_ptr<DownloadRequestHandleInterface> req_handle,
1146 const DownloadCreateInfo& new_create_info) {
1135 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1147 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1136 DCHECK(!download_file_.get()); 1148 DCHECK(!download_file_.get());
1137 DCHECK(file.get());
1138 DCHECK(req_handle.get());
1139 DVLOG(20) << __FUNCTION__ << "() this=" << DebugString(true); 1149 DVLOG(20) << __FUNCTION__ << "() this=" << DebugString(true);
1140 1150
1141 download_file_ = std::move(file); 1151 download_file_ = std::move(file);
1142 request_handle_ = std::move(req_handle); 1152 request_handle_ = std::move(req_handle);
1143 1153
1144 if (state_ == CANCELLED_INTERNAL) { 1154 if (state_ == CANCELLED_INTERNAL) {
1145 // The download was in the process of resuming when it was cancelled. Don't 1155 // The download was in the process of resuming when it was cancelled. Don't
1146 // proceed. 1156 // proceed.
1147 ReleaseDownloadFile(true); 1157 ReleaseDownloadFile(true);
1148 request_handle_->CancelRequest(); 1158 if (request_handle_)
1159 request_handle_->CancelRequest();
1149 return; 1160 return;
1150 } 1161 }
1151 1162
1152 TransitionTo(TARGET_PENDING_INTERNAL, UPDATE_OBSERVERS); 1163 // The state could be one of the following:
1164 //
1165 // INITIAL_INTERNAL: A normal download attempt.
1166 //
1167 // RESUMING_INTERNAL: A resumption attempt. May or may not have been
1168 // successful.
1169 DCHECK(state_ == INITIAL_INTERNAL || state_ == RESUMING_INTERNAL);
1170
1171 // If a resumption attempted failed, or if the download was DOA, then the
1172 // download should go back to being interrupted.
1173 if (new_create_info.result != DOWNLOAD_INTERRUPT_REASON_NONE) {
1174 DCHECK(!download_file_.get());
1175
1176 // For downloads that are interrupted on initiation, or which don't have a
1177 // target, invoke target determination so that we'll end up with a usable
1178 // filename.
Randy Smith (Not in Mondays) 2016/02/12 21:57:19 nit, suggestion: I had some trouble matching this
asanka 2016/02/12 23:34:47 Ah. I simplified the condition and the comment to
1179 if (state_ == INITIAL_INTERNAL || target_path_.empty()) {
1180 TransitionTo(INTERRUPTED_TARGET_PENDING_INTERNAL);
1181 destination_error_ = new_create_info.result;
1182 DetermineDownloadTarget();
1183 return;
1184 }
1185
1186 // Otherwise, this was a resumption attempt which ended with an
1187 // interruption. Continue with current target path.
1188 TransitionTo(TARGET_RESOLVED_INTERNAL);
1189 Interrupt(new_create_info.result);
1190 UpdateObservers();
1191 return;
1192 }
1193
1194 // Successful download start.
1195 DCHECK(download_file_.get());
1196 DCHECK(request_handle_.get());
1197
1198 if (state_ == RESUMING_INTERNAL)
1199 UpdateValidatorsOnResumption(new_create_info);
1200
1201 TransitionTo(TARGET_PENDING_INTERNAL);
1153 1202
1154 BrowserThread::PostTask( 1203 BrowserThread::PostTask(
1155 BrowserThread::FILE, FROM_HERE, 1204 BrowserThread::FILE, FROM_HERE,
1156 base::Bind(&DownloadFile::Initialize, 1205 base::Bind(&DownloadFile::Initialize,
1157 // Safe because we control download file lifetime. 1206 // Safe because we control download file lifetime.
1158 base::Unretained(download_file_.get()), 1207 base::Unretained(download_file_.get()),
1159 base::Bind(&DownloadItemImpl::OnDownloadFileInitialized, 1208 base::Bind(&DownloadItemImpl::OnDownloadFileInitialized,
1160 weak_ptr_factory_.GetWeakPtr()))); 1209 weak_ptr_factory_.GetWeakPtr())));
1161 } 1210 }
1162 1211
1163 void DownloadItemImpl::OnDownloadFileInitialized( 1212 void DownloadItemImpl::OnDownloadFileInitialized(
1164 DownloadInterruptReason result) { 1213 DownloadInterruptReason result) {
1165 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1214 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1166 DCHECK_EQ(state_, TARGET_PENDING_INTERNAL); 1215 DCHECK_EQ(state_, TARGET_PENDING_INTERNAL);
1167 DVLOG(20) << __FUNCTION__ 1216 DVLOG(20) << __FUNCTION__
1168 << "() result:" << DownloadInterruptReasonToString(result); 1217 << "() result:" << DownloadInterruptReasonToString(result);
1169 if (result != DOWNLOAD_INTERRUPT_REASON_NONE) { 1218 if (result != DOWNLOAD_INTERRUPT_REASON_NONE) {
1170 // Transition out to TARGET_RESOLVED_INTERNAL since this DownloadItem is 1219 // Whoops. That didn't work. Proceed as an interrupted download.
1171 // skipping the download target determination process. 1220 destination_error_ = result;
1172 TransitionTo(TARGET_RESOLVED_INTERNAL, DONT_UPDATE_OBSERVERS); 1221 TransitionTo(INTERRUPTED_TARGET_PENDING_INTERNAL);
1173 Interrupt(result);
1174 // TODO(rdsmith/asanka): Arguably we should show this in the UI, but
1175 // it's not at all clear what to show--we haven't done filename
1176 // determination, so we don't know what name to display. OTOH,
1177 // the failure mode of not showing the DI if the file initialization
1178 // fails isn't a good one. Can we hack up a name based on the
1179 // URLRequest? We'll need to make sure that initialization happens
1180 // properly. Possibly the right thing is to have the UI handle
1181 // this case specially.
1182 return;
1183 } 1222 }
1184 1223
1224 DetermineDownloadTarget();
1225 }
1226
1227 void DownloadItemImpl::DetermineDownloadTarget() {
1228 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1229 DVLOG(20) << __FUNCTION__ << "() " << DebugString(true);
1230
1185 delegate_->DetermineDownloadTarget( 1231 delegate_->DetermineDownloadTarget(
1186 this, base::Bind(&DownloadItemImpl::OnDownloadTargetDetermined, 1232 this, base::Bind(&DownloadItemImpl::OnDownloadTargetDetermined,
1187 weak_ptr_factory_.GetWeakPtr())); 1233 weak_ptr_factory_.GetWeakPtr()));
1188 } 1234 }
1189 1235
1190 // Called by delegate_ when the download target path has been 1236 // Called by delegate_ when the download target path has been determined.
1191 // determined.
1192 void DownloadItemImpl::OnDownloadTargetDetermined( 1237 void DownloadItemImpl::OnDownloadTargetDetermined(
1193 const base::FilePath& target_path, 1238 const base::FilePath& target_path,
1194 TargetDisposition disposition, 1239 TargetDisposition disposition,
1195 DownloadDangerType danger_type, 1240 DownloadDangerType danger_type,
1196 const base::FilePath& intermediate_path) { 1241 const base::FilePath& intermediate_path) {
1197 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1242 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1198 DCHECK_EQ(state_, TARGET_PENDING_INTERNAL); 1243 DCHECK(state_ == TARGET_PENDING_INTERNAL ||
1244 state_ == INTERRUPTED_TARGET_PENDING_INTERNAL);
1199 1245
1200 // If the |target_path| is empty, then we consider this download to be 1246 // If the |target_path| is empty, then we consider this download to be
1201 // canceled. 1247 // canceled.
1202 if (target_path.empty()) { 1248 if (target_path.empty()) {
1203 Cancel(true); 1249 Cancel(true);
1204 return; 1250 return;
1205 } 1251 }
1206 1252
1207 // TODO(rdsmith,asanka): We are ignoring the possibility that the download 1253 DVLOG(20) << __FUNCTION__ << "() target_path:" << target_path.value()
1208 // has been interrupted at this point until we finish the intermediate 1254 << " disposition:" << disposition << " danger_type:" << danger_type
1209 // rename and set the full path. That's dangerous, because we might race 1255 << " this:" << DebugString(true);
1210 // with resumption, either manual (because the interrupt is visible to the
1211 // UI) or automatic. If we keep the "ignore an error on download until file
1212 // name determination complete" semantics, we need to make sure that the
1213 // error is kept completely invisible until that point.
1214
1215 DVLOG(20) << __FUNCTION__ << " " << target_path.value() << " " << disposition
1216 << " " << danger_type << " " << DebugString(true);
1217 1256
1218 target_path_ = target_path; 1257 target_path_ = target_path;
1219 target_disposition_ = disposition; 1258 target_disposition_ = disposition;
1220 SetDangerType(danger_type); 1259 SetDangerType(danger_type);
1221 1260
1261 // This was an interrupted download that was looking for a filename. Now that
1262 // it has one, transition to interrupted.
1263 if (state_ == INTERRUPTED_TARGET_PENDING_INTERNAL) {
1264 Interrupt(destination_error_);
1265 destination_error_ = DOWNLOAD_INTERRUPT_REASON_NONE;
1266 UpdateObservers();
1267 return;
1268 }
1269
1222 // We want the intermediate and target paths to refer to the same directory so 1270 // We want the intermediate and target paths to refer to the same directory so
1223 // that they are both on the same device and subject to same 1271 // that they are both on the same device and subject to same
1224 // space/permission/availability constraints. 1272 // space/permission/availability constraints.
1225 DCHECK(intermediate_path.DirName() == target_path.DirName()); 1273 DCHECK(intermediate_path.DirName() == target_path.DirName());
1226 1274
1227 // During resumption, we may choose to proceed with the same intermediate 1275 // During resumption, we may choose to proceed with the same intermediate
1228 // file. No rename is necessary if our intermediate file already has the 1276 // file. No rename is necessary if our intermediate file already has the
1229 // correct name. 1277 // correct name.
1230 // 1278 //
1231 // The intermediate name may change from its original value during filename 1279 // The intermediate name may change from its original value during filename
(...skipping 22 matching lines...) Expand all
1254 base::Unretained(download_file_.get()), 1302 base::Unretained(download_file_.get()),
1255 intermediate_path, callback)); 1303 intermediate_path, callback));
1256 } 1304 }
1257 1305
1258 void DownloadItemImpl::OnDownloadRenamedToIntermediateName( 1306 void DownloadItemImpl::OnDownloadRenamedToIntermediateName(
1259 DownloadInterruptReason reason, 1307 DownloadInterruptReason reason,
1260 const base::FilePath& full_path) { 1308 const base::FilePath& full_path) {
1261 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1309 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1262 DCHECK_EQ(state_, TARGET_PENDING_INTERNAL); 1310 DCHECK_EQ(state_, TARGET_PENDING_INTERNAL);
1263 DVLOG(20) << __FUNCTION__ << " download=" << DebugString(true); 1311 DVLOG(20) << __FUNCTION__ << " download=" << DebugString(true);
1264 TransitionTo(TARGET_RESOLVED_INTERNAL, DONT_UPDATE_OBSERVERS); 1312 TransitionTo(TARGET_RESOLVED_INTERNAL);
1265 1313
1266 if (DOWNLOAD_INTERRUPT_REASON_NONE != destination_error_) { 1314 if (DOWNLOAD_INTERRUPT_REASON_NONE != destination_error_) {
1267 // Process destination error. If both |reason| and |destination_error_| 1315 // Process destination error. If both |reason| and |destination_error_|
1268 // refer to actual errors, we want to use the |destination_error_| as the 1316 // refer to actual errors, we want to use the |destination_error_| as the
1269 // argument to the Interrupt() routine, as it happened first. 1317 // argument to the Interrupt() routine, as it happened first.
1270 if (reason == DOWNLOAD_INTERRUPT_REASON_NONE) 1318 if (reason == DOWNLOAD_INTERRUPT_REASON_NONE)
1271 SetFullPath(full_path); 1319 SetFullPath(full_path);
1272 Interrupt(destination_error_); 1320 Interrupt(destination_error_);
1273 destination_error_ = DOWNLOAD_INTERRUPT_REASON_NONE; 1321 destination_error_ = DOWNLOAD_INTERRUPT_REASON_NONE;
1322 UpdateObservers();
1274 } else if (DOWNLOAD_INTERRUPT_REASON_NONE != reason) { 1323 } else if (DOWNLOAD_INTERRUPT_REASON_NONE != reason) {
1275 Interrupt(reason); 1324 Interrupt(reason);
1276 // All file errors result in file deletion above; no need to cleanup. The 1325 // All file errors result in file deletion above; no need to cleanup. The
1277 // current_path_ should be empty. Resuming this download will force a 1326 // current_path_ should be empty. Resuming this download will force a
1278 // restart and a re-doing of filename determination. 1327 // restart and a re-doing of filename determination.
1279 DCHECK(current_path_.empty()); 1328 DCHECK(current_path_.empty());
1329 UpdateObservers();
1280 } else { 1330 } else {
1281 SetFullPath(full_path); 1331 SetFullPath(full_path);
1282 TransitionTo(IN_PROGRESS_INTERNAL, UPDATE_OBSERVERS); 1332 TransitionTo(IN_PROGRESS_INTERNAL);
1333 UpdateObservers(); // TODO(asanka): This is not safe. The download could be
1334 // in an underminate state after invoking observers.
Randy Smith (Not in Mondays) 2016/02/12 19:10:28 Unlike the other place where you have the same com
asanka 2016/02/12 19:30:35 Semantics are the same? I.e. both before and after
1283 MaybeCompleteDownload(); 1335 MaybeCompleteDownload();
1284 } 1336 }
1285 } 1337 }
1286 1338
1287 // When SavePackage downloads MHTML to GData (see 1339 // When SavePackage downloads MHTML to GData (see
1288 // SavePackageFilePickerChromeOS), GData calls MaybeCompleteDownload() like it 1340 // SavePackageFilePickerChromeOS), GData calls MaybeCompleteDownload() like it
1289 // does for non-SavePackage downloads, but SavePackage downloads never satisfy 1341 // does for non-SavePackage downloads, but SavePackage downloads never satisfy
1290 // IsDownloadReadyForCompletion(). GDataDownloadObserver manually calls 1342 // IsDownloadReadyForCompletion(). GDataDownloadObserver manually calls
1291 // DownloadItem::UpdateObservers() when the upload completes so that SavePackage 1343 // DownloadItem::UpdateObservers() when the upload completes so that SavePackage
1292 // notices that the upload has completed and runs its normal Finish() pathway. 1344 // notices that the upload has completed and runs its normal Finish() pathway.
(...skipping 27 matching lines...) Expand all
1320 return; 1372 return;
1321 1373
1322 DVLOG(20) << __FUNCTION__ << "()" 1374 DVLOG(20) << __FUNCTION__ << "()"
1323 << " " << DebugString(true); 1375 << " " << DebugString(true);
1324 DCHECK(!GetTargetFilePath().empty()); 1376 DCHECK(!GetTargetFilePath().empty());
1325 DCHECK(!IsDangerous()); 1377 DCHECK(!IsDangerous());
1326 1378
1327 // TODO(rdsmith/benjhayden): Remove as part of SavePackage integration. 1379 // TODO(rdsmith/benjhayden): Remove as part of SavePackage integration.
1328 if (is_save_package_download_) { 1380 if (is_save_package_download_) {
1329 // Avoid doing anything on the file thread; there's nothing we control 1381 // Avoid doing anything on the file thread; there's nothing we control
1330 // there. 1382 // there. Strictly speaking, this skips giving the embedder a chance to
1331 // Strictly speaking, this skips giving the embedder a chance to open 1383 // open the download. But on a save package download, there's no real
1332 // the download. But on a save package download, there's no real
1333 // concept of opening. 1384 // concept of opening.
1334 Completed(); 1385 Completed();
1335 return; 1386 return;
1336 } 1387 }
1337 1388
1338 DCHECK(download_file_.get()); 1389 DCHECK(download_file_.get());
1339 // Unilaterally rename; even if it already has the right name, 1390 // Unilaterally rename; even if it already has the right name,
1340 // we need theannotation. 1391 // we need theannotation.
1341 DownloadFile::RenameCompletionCallback callback = 1392 DownloadFile::RenameCompletionCallback callback =
1342 base::Bind(&DownloadItemImpl::OnDownloadRenamedToFinalName, 1393 base::Bind(&DownloadItemImpl::OnDownloadRenamedToFinalName,
(...skipping 20 matching lines...) Expand all
1363 DVLOG(20) << __FUNCTION__ << "()" 1414 DVLOG(20) << __FUNCTION__ << "()"
1364 << " full_path = \"" << full_path.value() << "\"" 1415 << " full_path = \"" << full_path.value() << "\""
1365 << " " << DebugString(false); 1416 << " " << DebugString(false);
1366 1417
1367 if (DOWNLOAD_INTERRUPT_REASON_NONE != reason) { 1418 if (DOWNLOAD_INTERRUPT_REASON_NONE != reason) {
1368 Interrupt(reason); 1419 Interrupt(reason);
1369 1420
1370 // All file errors should have resulted in in file deletion above. On 1421 // All file errors should have resulted in in file deletion above. On
1371 // resumption we will need to re-do filename determination. 1422 // resumption we will need to re-do filename determination.
1372 DCHECK(current_path_.empty()); 1423 DCHECK(current_path_.empty());
1424 UpdateObservers();
1373 return; 1425 return;
1374 } 1426 }
1375 1427
1376 DCHECK(target_path_ == full_path); 1428 DCHECK(target_path_ == full_path);
1377 1429
1378 if (full_path != current_path_) { 1430 if (full_path != current_path_) {
1379 // full_path is now the current and target file path. 1431 // full_path is now the current and target file path.
1380 DCHECK(!full_path.empty()); 1432 DCHECK(!full_path.empty());
1381 SetFullPath(full_path); 1433 SetFullPath(full_path);
1382 } 1434 }
1383 1435
1384 // Complete the download and release the DownloadFile. 1436 // Complete the download and release the DownloadFile.
1385 DCHECK(download_file_); 1437 DCHECK(download_file_);
1386 ReleaseDownloadFile(false); 1438 ReleaseDownloadFile(false);
1387 1439
1388 // We're not completely done with the download item yet, but at this 1440 // We're not completely done with the download item yet, but at this
1389 // point we're committed to complete the download. Cancels (or Interrupts, 1441 // point we're committed to complete the download. Cancels (or Interrupts,
1390 // though it's not clear how they could happen) after this point will be 1442 // though it's not clear how they could happen) after this point will be
1391 // ignored. 1443 // ignored.
1392 TransitionTo(COMPLETING_INTERNAL, DONT_UPDATE_OBSERVERS); 1444 TransitionTo(COMPLETING_INTERNAL);
1393 1445
1394 if (delegate_->ShouldOpenDownload( 1446 if (delegate_->ShouldOpenDownload(
1395 this, base::Bind(&DownloadItemImpl::DelayedDownloadOpened, 1447 this, base::Bind(&DownloadItemImpl::DelayedDownloadOpened,
1396 weak_ptr_factory_.GetWeakPtr()))) { 1448 weak_ptr_factory_.GetWeakPtr()))) {
1397 Completed(); 1449 Completed();
1398 } else { 1450 } else {
1399 delegate_delayed_complete_ = true; 1451 delegate_delayed_complete_ = true;
1400 UpdateObservers(); 1452 UpdateObservers();
1401 } 1453 }
1402 } 1454 }
1403 1455
1404 void DownloadItemImpl::DelayedDownloadOpened(bool auto_opened) { 1456 void DownloadItemImpl::DelayedDownloadOpened(bool auto_opened) {
1405 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1457 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1406 1458
1407 auto_opened_ = auto_opened; 1459 auto_opened_ = auto_opened;
1408 Completed(); 1460 Completed();
1409 } 1461 }
1410 1462
1411 void DownloadItemImpl::Completed() { 1463 void DownloadItemImpl::Completed() {
1412 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1464 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1413 1465
1414 DVLOG(20) << __FUNCTION__ << "() " << DebugString(false); 1466 DVLOG(20) << __FUNCTION__ << "() " << DebugString(false);
1415 1467
1416 DCHECK(all_data_saved_); 1468 DCHECK(all_data_saved_);
1417 end_time_ = base::Time::Now(); 1469 end_time_ = base::Time::Now();
1418 TransitionTo(COMPLETE_INTERNAL, UPDATE_OBSERVERS); 1470 TransitionTo(COMPLETE_INTERNAL);
1419 RecordDownloadCompleted(start_tick_, received_bytes_); 1471 RecordDownloadCompleted(start_tick_, received_bytes_);
1420 1472
1421 if (auto_opened_) { 1473 if (auto_opened_) {
1422 // If it was already handled by the delegate, do nothing. 1474 // If it was already handled by the delegate, do nothing.
1423 } else if (GetOpenWhenComplete() || 1475 } else if (GetOpenWhenComplete() ||
1424 ShouldOpenFileBasedOnExtension() || 1476 ShouldOpenFileBasedOnExtension() ||
1425 IsTemporary()) { 1477 IsTemporary()) {
1426 // If the download is temporary, like in drag-and-drop, do not open it but 1478 // If the download is temporary, like in drag-and-drop, do not open it but
1427 // we still need to set it auto-opened so that it can be removed from the 1479 // we still need to set it auto-opened so that it can be removed from the
1428 // download shelf. 1480 // download shelf.
1429 if (!IsTemporary()) 1481 if (!IsTemporary())
1430 OpenDownload(); 1482 OpenDownload();
1431 1483
1432 auto_opened_ = true; 1484 auto_opened_ = true;
1433 UpdateObservers();
1434 } 1485 }
1435 } 1486 UpdateObservers();
1436
1437 void DownloadItemImpl::OnResumeRequestStarted(
1438 DownloadItem* item,
1439 DownloadInterruptReason interrupt_reason) {
1440 // If |item| is not NULL, then Start() has been called already, and nothing
1441 // more needs to be done here.
1442 if (item) {
1443 DCHECK_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, interrupt_reason);
1444 DCHECK_EQ(static_cast<DownloadItem*>(this), item);
1445 return;
1446 }
1447 // Otherwise, the request failed without passing through
1448 // DownloadResourceHandler::OnResponseStarted.
1449 DCHECK_NE(DOWNLOAD_INTERRUPT_REASON_NONE, interrupt_reason);
1450 Interrupt(interrupt_reason);
1451 } 1487 }
1452 1488
1453 // **** End of Download progression cascade 1489 // **** End of Download progression cascade
1454 1490
1455 // An error occurred somewhere. 1491 // An error occurred somewhere.
1456 void DownloadItemImpl::Interrupt(DownloadInterruptReason reason) { 1492 void DownloadItemImpl::Interrupt(DownloadInterruptReason reason) {
1457 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1493 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1458 DCHECK_NE(DOWNLOAD_INTERRUPT_REASON_NONE, reason); 1494 DCHECK_NE(DOWNLOAD_INTERRUPT_REASON_NONE, reason);
1459 DVLOG(20) << __FUNCTION__ 1495 DVLOG(20) << __FUNCTION__
1460 << "() reason:" << DownloadInterruptReasonToString(reason) 1496 << "() reason:" << DownloadInterruptReasonToString(reason)
(...skipping 14 matching lines...) Expand all
1475 case COMPLETING_INTERNAL: 1511 case COMPLETING_INTERNAL:
1476 case COMPLETE_INTERNAL: 1512 case COMPLETE_INTERNAL:
1477 // Already complete. 1513 // Already complete.
1478 return; 1514 return;
1479 1515
1480 case INITIAL_INTERNAL: 1516 case INITIAL_INTERNAL:
1481 case MAX_DOWNLOAD_INTERNAL_STATE: 1517 case MAX_DOWNLOAD_INTERNAL_STATE:
1482 NOTREACHED(); 1518 NOTREACHED();
1483 return; 1519 return;
1484 1520
1521 case INTERRUPTED_TARGET_PENDING_INTERNAL:
1522 case IN_PROGRESS_INTERNAL:
1485 case TARGET_PENDING_INTERNAL: 1523 case TARGET_PENDING_INTERNAL:
Randy Smith (Not in Mondays) 2016/02/12 21:57:19 I thought we couldn't interrupt from TARGET_PENDIN
asanka 2016/02/12 23:34:47 It's not allowed. But we can transition to CANCELL
1486 case TARGET_RESOLVED_INTERNAL: 1524 case TARGET_RESOLVED_INTERNAL:
1487 case IN_PROGRESS_INTERNAL:
1488 // last_reason_ needs to be set for GetResumeMode() to work. 1525 // last_reason_ needs to be set for GetResumeMode() to work.
1489 last_reason_ = reason; 1526 last_reason_ = reason;
1490 1527
1491 if (download_file_) { 1528 if (download_file_) {
1492 ResumeMode resume_mode = GetResumeMode(); 1529 ResumeMode resume_mode = GetResumeMode();
1493 ReleaseDownloadFile(resume_mode != RESUME_MODE_IMMEDIATE_CONTINUE && 1530 ReleaseDownloadFile(resume_mode != RESUME_MODE_IMMEDIATE_CONTINUE &&
1494 resume_mode != RESUME_MODE_USER_CONTINUE); 1531 resume_mode != RESUME_MODE_USER_CONTINUE);
1495 } 1532 }
1496 break; 1533 break;
1497 1534
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1535 reason == DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN) { 1572 reason == DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN) {
1536 if (IsDangerous()) { 1573 if (IsDangerous()) {
1537 RecordDangerousDownloadDiscard( 1574 RecordDangerousDownloadDiscard(
1538 reason == DOWNLOAD_INTERRUPT_REASON_USER_CANCELED 1575 reason == DOWNLOAD_INTERRUPT_REASON_USER_CANCELED
1539 ? DOWNLOAD_DISCARD_DUE_TO_USER_ACTION 1576 ? DOWNLOAD_DISCARD_DUE_TO_USER_ACTION
1540 : DOWNLOAD_DISCARD_DUE_TO_SHUTDOWN, 1577 : DOWNLOAD_DISCARD_DUE_TO_SHUTDOWN,
1541 GetDangerType(), GetTargetFilePath()); 1578 GetDangerType(), GetTargetFilePath());
1542 } 1579 }
1543 1580
1544 RecordDownloadCount(CANCELLED_COUNT); 1581 RecordDownloadCount(CANCELLED_COUNT);
1545 TransitionTo(CANCELLED_INTERNAL, DONT_UPDATE_OBSERVERS); 1582 TransitionTo(CANCELLED_INTERNAL);
1546 } else { 1583 return;
1547 RecordDownloadInterrupted(reason, received_bytes_, total_bytes_);
1548 if (!GetWebContents())
1549 RecordDownloadCount(INTERRUPTED_WITHOUT_WEBCONTENTS);
1550 TransitionTo(INTERRUPTED_INTERNAL, DONT_UPDATE_OBSERVERS);
1551 AutoResumeIfValid();
1552 } 1584 }
1553 1585
1554 UpdateObservers(); 1586 RecordDownloadInterrupted(reason, received_bytes_, total_bytes_);
1587 if (!GetWebContents())
1588 RecordDownloadCount(INTERRUPTED_WITHOUT_WEBCONTENTS);
1589
1590 TransitionTo(INTERRUPTED_INTERNAL);
1591 AutoResumeIfValid();
1555 } 1592 }
1556 1593
1557 void DownloadItemImpl::ReleaseDownloadFile(bool destroy_file) { 1594 void DownloadItemImpl::ReleaseDownloadFile(bool destroy_file) {
1558 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1595 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1559 DVLOG(20) << __FUNCTION__ << "() destroy_file:" << destroy_file; 1596 DVLOG(20) << __FUNCTION__ << "() destroy_file:" << destroy_file;
1560 1597
1561 if (destroy_file) { 1598 if (destroy_file) {
1562 BrowserThread::PostTask( 1599 BrowserThread::PostTask(
1563 BrowserThread::FILE, FROM_HERE, 1600 BrowserThread::FILE, FROM_HERE,
1564 // Will be deleted at end of task execution. 1601 // Will be deleted at end of task execution.
(...skipping 25 matching lines...) Expand all
1590 // If we don't have all the data, the download is not ready for 1627 // If we don't have all the data, the download is not ready for
1591 // completion. 1628 // completion.
1592 if (!AllDataSaved()) 1629 if (!AllDataSaved())
1593 return false; 1630 return false;
1594 1631
1595 // If the download is dangerous, but not yet validated, it's not ready for 1632 // If the download is dangerous, but not yet validated, it's not ready for
1596 // completion. 1633 // completion.
1597 if (IsDangerous()) 1634 if (IsDangerous())
1598 return false; 1635 return false;
1599 1636
1600 // Invariants for the IN_PROGRESS state. DCHECKs here verify that the 1637 // Check for consistency before invoking delegate. Since there are no pending
1601 // invariants are still true. 1638 // target determination calls and the download is in progress, both the target
1639 // and current paths should be non-empty and they should point to the same
1640 // directory.
1602 DCHECK(!target_path_.empty()); 1641 DCHECK(!target_path_.empty());
1603 DCHECK(!current_path_.empty()); 1642 DCHECK(!current_path_.empty());
1604 DCHECK(target_path_.DirName() == current_path_.DirName()); 1643 DCHECK(target_path_.DirName() == current_path_.DirName());
1605 1644
1606 // Give the delegate a chance to hold up a stop sign. It'll call 1645 // Give the delegate a chance to hold up a stop sign. It'll call
1607 // use back through the passed callback if it does and that state changes. 1646 // use back through the passed callback if it does and that state changes.
1608 if (!delegate_->ShouldCompleteDownload(this, state_change_notification)) 1647 if (!delegate_->ShouldCompleteDownload(this, state_change_notification))
1609 return false; 1648 return false;
1610 1649
1611 return true; 1650 return true;
1612 } 1651 }
1613 1652
1614 void DownloadItemImpl::TransitionTo(DownloadInternalState new_state, 1653 void DownloadItemImpl::TransitionTo(DownloadInternalState new_state) {
1615 ShouldUpdateObservers notify_action) {
1616 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1654 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1617 1655
1618 if (state_ == new_state) 1656 if (state_ == new_state)
1619 return; 1657 return;
1620 1658
1621 DownloadInternalState old_state = state_; 1659 DownloadInternalState old_state = state_;
1622 state_ = new_state; 1660 state_ = new_state;
1623 1661
1624 DCHECK(is_save_package_download_ 1662 DCHECK(is_save_package_download_
1625 ? IsValidSavePackageStateTransition(old_state, new_state) 1663 ? IsValidSavePackageStateTransition(old_state, new_state)
1626 : IsValidStateTransition(old_state, new_state)) 1664 : IsValidStateTransition(old_state, new_state))
1627 << "Invalid state transition from:" << DebugDownloadStateString(old_state) 1665 << "Invalid state transition from:" << DebugDownloadStateString(old_state)
1628 << " to:" << DebugDownloadStateString(new_state); 1666 << " to:" << DebugDownloadStateString(new_state);
1629 1667
1630 switch (state_) { 1668 switch (state_) {
1631 case INITIAL_INTERNAL: 1669 case INITIAL_INTERNAL:
1632 NOTREACHED(); 1670 NOTREACHED();
1633 break; 1671 break;
1634 1672
1635 case TARGET_PENDING_INTERNAL: 1673 case TARGET_PENDING_INTERNAL:
1636 case TARGET_RESOLVED_INTERNAL: 1674 case TARGET_RESOLVED_INTERNAL:
1675 case INTERRUPTED_TARGET_PENDING_INTERNAL:
1637 break; 1676 break;
1638 1677
1639 case IN_PROGRESS_INTERNAL: 1678 case IN_PROGRESS_INTERNAL:
1640 DCHECK(!current_path_.empty()) << "Current output path must be known."; 1679 DCHECK(!current_path_.empty()) << "Current output path must be known.";
1641 DCHECK(!target_path_.empty()) << "Target path must be known."; 1680 DCHECK(!target_path_.empty()) << "Target path must be known.";
1642 DCHECK(current_path_.DirName() == target_path_.DirName()) 1681 DCHECK(current_path_.DirName() == target_path_.DirName())
1643 << "Current output directory must match target directory."; 1682 << "Current output directory must match target directory.";
1644 DCHECK(download_file_) << "Output file must be owned by download item."; 1683 DCHECK(download_file_) << "Output file must be owned by download item.";
1645 DCHECK(request_handle_) << "Download source must be active."; 1684 DCHECK(request_handle_) << "Download source must be active.";
1646 DCHECK(!is_paused_) << "At the time a download enters IN_PROGRESS state, " 1685 DCHECK(!is_paused_) << "At the time a download enters IN_PROGRESS state, "
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1708 bound_net_log_.EndEvent(net::NetLog::TYPE_DOWNLOAD_ITEM_ACTIVE); 1747 bound_net_log_.EndEvent(net::NetLog::TYPE_DOWNLOAD_ITEM_ACTIVE);
1709 1748
1710 // Resumption 1749 // Resumption
1711 if (was_done && !is_done) { 1750 if (was_done && !is_done) {
1712 std::string file_name(target_path_.BaseName().AsUTF8Unsafe()); 1751 std::string file_name(target_path_.BaseName().AsUTF8Unsafe());
1713 bound_net_log_.BeginEvent(net::NetLog::TYPE_DOWNLOAD_ITEM_ACTIVE, 1752 bound_net_log_.BeginEvent(net::NetLog::TYPE_DOWNLOAD_ITEM_ACTIVE,
1714 base::Bind(&ItemActivatedNetLogCallback, 1753 base::Bind(&ItemActivatedNetLogCallback,
1715 this, SRC_ACTIVE_DOWNLOAD, 1754 this, SRC_ACTIVE_DOWNLOAD,
1716 &file_name)); 1755 &file_name));
1717 } 1756 }
1718
1719 if (notify_action == UPDATE_OBSERVERS)
1720 UpdateObservers();
1721 } 1757 }
1722 1758
1723 void DownloadItemImpl::SetDangerType(DownloadDangerType danger_type) { 1759 void DownloadItemImpl::SetDangerType(DownloadDangerType danger_type) {
1724 if (danger_type != danger_type_) { 1760 if (danger_type != danger_type_) {
1725 bound_net_log_.AddEvent( 1761 bound_net_log_.AddEvent(
1726 net::NetLog::TYPE_DOWNLOAD_ITEM_SAFETY_STATE_UPDATED, 1762 net::NetLog::TYPE_DOWNLOAD_ITEM_SAFETY_STATE_UPDATED,
1727 base::Bind(&ItemCheckedNetLogCallback, danger_type)); 1763 base::Bind(&ItemCheckedNetLogCallback, danger_type));
1728 } 1764 }
1729 // Only record the Malicious UMA stat if it's going from {not malicious} -> 1765 // Only record the Malicious UMA stat if it's going from {not malicious} ->
1730 // {malicious}. 1766 // {malicious}.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1772 1808
1773 void DownloadItemImpl::ResumeInterruptedDownload() { 1809 void DownloadItemImpl::ResumeInterruptedDownload() {
1774 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1810 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1775 if (!IsDownloadResumptionEnabled()) 1811 if (!IsDownloadResumptionEnabled())
1776 return; 1812 return;
1777 1813
1778 // If we're not interrupted, ignore the request; our caller is drunk. 1814 // If we're not interrupted, ignore the request; our caller is drunk.
1779 if (state_ != INTERRUPTED_INTERNAL) 1815 if (state_ != INTERRUPTED_INTERNAL)
1780 return; 1816 return;
1781 1817
1818 // We are starting a new request. Shake off all pending operations.
1819 DCHECK(!download_file_);
1820 weak_ptr_factory_.InvalidateWeakPtrs();
1821
1782 // Reset the appropriate state if restarting. 1822 // Reset the appropriate state if restarting.
1783 ResumeMode mode = GetResumeMode(); 1823 ResumeMode mode = GetResumeMode();
1784 if (mode == RESUME_MODE_IMMEDIATE_RESTART || 1824 if (mode == RESUME_MODE_IMMEDIATE_RESTART ||
1785 mode == RESUME_MODE_USER_RESTART) { 1825 mode == RESUME_MODE_USER_RESTART) {
1786 received_bytes_ = 0; 1826 received_bytes_ = 0;
1787 hash_state_ = ""; 1827 hash_state_ = "";
1788 last_modified_time_ = ""; 1828 last_modified_time_ = "";
1789 etag_ = ""; 1829 etag_ = "";
1790 } 1830 }
1791 1831
1792 scoped_ptr<DownloadUrlParameters> download_params; 1832 // Avoid using the WebContents even if it's still around. Resumption requests
1793 if (GetWebContents()) { 1833 // are consistently routed through the no-renderer code paths so that the
1794 download_params = 1834 // request will not be dropped if the WebContents (and by extension, the
1795 DownloadUrlParameters::FromWebContents(GetWebContents(), GetURL()); 1835 // associated renderer) goes away before a response is received.
1796 } else { 1836 scoped_ptr<DownloadUrlParameters> download_params(new DownloadUrlParameters(
1797 download_params = make_scoped_ptr(new DownloadUrlParameters( 1837 GetURL(), -1, -1, -1, GetBrowserContext()->GetResourceContext()));
1798 GetURL(), -1, -1, -1, GetBrowserContext()->GetResourceContext()));
1799 }
1800
1801 download_params->set_file_path(GetFullPath()); 1838 download_params->set_file_path(GetFullPath());
1802 download_params->set_offset(GetReceivedBytes()); 1839 download_params->set_offset(GetReceivedBytes());
1803 download_params->set_hash_state(GetHashState()); 1840 download_params->set_hash_state(GetHashState());
1804 download_params->set_last_modified(GetLastModifiedTime()); 1841 download_params->set_last_modified(GetLastModifiedTime());
1805 download_params->set_etag(GetETag()); 1842 download_params->set_etag(GetETag());
1806 download_params->set_callback(
1807 base::Bind(&DownloadItemImpl::OnResumeRequestStarted,
1808 weak_ptr_factory_.GetWeakPtr()));
1809 1843
1810 TransitionTo(RESUMING_INTERNAL, DONT_UPDATE_OBSERVERS); 1844 TransitionTo(RESUMING_INTERNAL);
1811 delegate_->ResumeInterruptedDownload(std::move(download_params), GetId()); 1845 delegate_->ResumeInterruptedDownload(std::move(download_params), GetId());
1812 // Just in case we were interrupted while paused. 1846 // Just in case we were interrupted while paused.
1813 is_paused_ = false; 1847 is_paused_ = false;
1814 } 1848 }
1815 1849
1816 // static 1850 // static
1817 DownloadItem::DownloadState DownloadItemImpl::InternalToExternalState( 1851 DownloadItem::DownloadState DownloadItemImpl::InternalToExternalState(
1818 DownloadInternalState internal_state) { 1852 DownloadInternalState internal_state) {
1819 switch (internal_state) { 1853 switch (internal_state) {
1820 case INITIAL_INTERNAL: 1854 case INITIAL_INTERNAL:
1821 case TARGET_PENDING_INTERNAL: 1855 case TARGET_PENDING_INTERNAL:
1822 case TARGET_RESOLVED_INTERNAL: 1856 case TARGET_RESOLVED_INTERNAL:
1857 case INTERRUPTED_TARGET_PENDING_INTERNAL:
1823 // TODO(asanka): Introduce an externally visible state to distinguish 1858 // TODO(asanka): Introduce an externally visible state to distinguish
1824 // between the above states and IN_PROGRESS_INTERNAL. The latter (the 1859 // between the above states and IN_PROGRESS_INTERNAL. The latter (the
1825 // state where the download is active and has a known target) is the state 1860 // state where the download is active and has a known target) is the state
1826 // that most external users are interested in. 1861 // that most external users are interested in.
1827 case IN_PROGRESS_INTERNAL: 1862 case IN_PROGRESS_INTERNAL:
1828 return IN_PROGRESS; 1863 return IN_PROGRESS;
1829 case COMPLETING_INTERNAL: 1864 case COMPLETING_INTERNAL:
1830 return IN_PROGRESS; 1865 return IN_PROGRESS;
1831 case COMPLETE_INTERNAL: 1866 case COMPLETE_INTERNAL:
1832 return COMPLETE; 1867 return COMPLETE;
(...skipping 30 matching lines...) Expand all
1863 } 1898 }
1864 1899
1865 // static 1900 // static
1866 bool DownloadItemImpl::IsValidSavePackageStateTransition( 1901 bool DownloadItemImpl::IsValidSavePackageStateTransition(
1867 DownloadInternalState from, 1902 DownloadInternalState from,
1868 DownloadInternalState to) { 1903 DownloadInternalState to) {
1869 #if DCHECK_IS_ON() 1904 #if DCHECK_IS_ON()
1870 switch (from) { 1905 switch (from) {
1871 case INITIAL_INTERNAL: 1906 case INITIAL_INTERNAL:
1872 case TARGET_PENDING_INTERNAL: 1907 case TARGET_PENDING_INTERNAL:
1908 case INTERRUPTED_TARGET_PENDING_INTERNAL:
1873 case TARGET_RESOLVED_INTERNAL: 1909 case TARGET_RESOLVED_INTERNAL:
1874 case COMPLETING_INTERNAL: 1910 case COMPLETING_INTERNAL:
1875 case COMPLETE_INTERNAL: 1911 case COMPLETE_INTERNAL:
1876 case INTERRUPTED_INTERNAL: 1912 case INTERRUPTED_INTERNAL:
1877 case RESUMING_INTERNAL: 1913 case RESUMING_INTERNAL:
1878 case CANCELLED_INTERNAL: 1914 case CANCELLED_INTERNAL:
1879 return false; 1915 return false;
1880 1916
1881 case IN_PROGRESS_INTERNAL: 1917 case IN_PROGRESS_INTERNAL:
1882 return to == CANCELLED_INTERNAL || to == COMPLETE_INTERNAL; 1918 return to == CANCELLED_INTERNAL || to == COMPLETE_INTERNAL;
1883 1919
1884 case MAX_DOWNLOAD_INTERNAL_STATE: 1920 case MAX_DOWNLOAD_INTERNAL_STATE:
1885 NOTREACHED(); 1921 NOTREACHED();
1886 } 1922 }
1887 return false; 1923 return false;
1888 #else 1924 #else
1889 return true; 1925 return true;
1890 #endif 1926 #endif
1891 } 1927 }
1892 1928
1893 // static 1929 // static
1894 bool DownloadItemImpl::IsValidStateTransition(DownloadInternalState from, 1930 bool DownloadItemImpl::IsValidStateTransition(DownloadInternalState from,
1895 DownloadInternalState to) { 1931 DownloadInternalState to) {
1896 #if DCHECK_IS_ON() 1932 #if DCHECK_IS_ON()
1897 switch (from) { 1933 switch (from) {
1898 case INITIAL_INTERNAL: 1934 case INITIAL_INTERNAL:
1899 return to == TARGET_PENDING_INTERNAL || to == INTERRUPTED_INTERNAL; 1935 return to == TARGET_PENDING_INTERNAL ||
1936 to == INTERRUPTED_TARGET_PENDING_INTERNAL;
1900 1937
1901 case TARGET_PENDING_INTERNAL: 1938 case TARGET_PENDING_INTERNAL:
1902 return to == TARGET_RESOLVED_INTERNAL || to == CANCELLED_INTERNAL; 1939 return to == INTERRUPTED_TARGET_PENDING_INTERNAL ||
1940 to == TARGET_RESOLVED_INTERNAL || to == CANCELLED_INTERNAL;
1941
1942 case INTERRUPTED_TARGET_PENDING_INTERNAL:
1943 return to == INTERRUPTED_INTERNAL || to == CANCELLED_INTERNAL;
1903 1944
1904 case TARGET_RESOLVED_INTERNAL: 1945 case TARGET_RESOLVED_INTERNAL:
1905 return to == IN_PROGRESS_INTERNAL || to == INTERRUPTED_INTERNAL || 1946 return to == IN_PROGRESS_INTERNAL || to == INTERRUPTED_INTERNAL ||
1906 to == CANCELLED_INTERNAL; 1947 to == CANCELLED_INTERNAL;
1907 1948
1908 case IN_PROGRESS_INTERNAL: 1949 case IN_PROGRESS_INTERNAL:
1909 return to == COMPLETING_INTERNAL || to == CANCELLED_INTERNAL || 1950 return to == COMPLETING_INTERNAL || to == CANCELLED_INTERNAL ||
1910 to == INTERRUPTED_INTERNAL; 1951 to == INTERRUPTED_INTERNAL;
1911 1952
1912 case COMPLETING_INTERNAL: 1953 case COMPLETING_INTERNAL:
1913 return to == COMPLETE_INTERNAL; 1954 return to == COMPLETE_INTERNAL;
1914 1955
1915 case COMPLETE_INTERNAL: 1956 case COMPLETE_INTERNAL:
1916 return false; 1957 return false;
1917 1958
1918 case INTERRUPTED_INTERNAL: 1959 case INTERRUPTED_INTERNAL:
1919 return to == RESUMING_INTERNAL || to == CANCELLED_INTERNAL; 1960 return to == RESUMING_INTERNAL || to == CANCELLED_INTERNAL;
1920 1961
1921 case RESUMING_INTERNAL: 1962 case RESUMING_INTERNAL:
1922 return to == TARGET_PENDING_INTERNAL || to == CANCELLED_INTERNAL; 1963 return to == TARGET_PENDING_INTERNAL ||
1964 to == INTERRUPTED_TARGET_PENDING_INTERNAL ||
1965 to == TARGET_RESOLVED_INTERNAL || to == CANCELLED_INTERNAL;
1923 1966
1924 case CANCELLED_INTERNAL: 1967 case CANCELLED_INTERNAL:
1925 return false; 1968 return false;
1926 1969
1927 case MAX_DOWNLOAD_INTERNAL_STATE: 1970 case MAX_DOWNLOAD_INTERNAL_STATE:
1928 NOTREACHED(); 1971 NOTREACHED();
1929 } 1972 }
1930 return false; 1973 return false;
1931 #else 1974 #else
1932 return true; 1975 return true;
1933 #endif // DCHECK_IS_ON() 1976 #endif // DCHECK_IS_ON()
1934 } 1977 }
1935 1978
1936 const char* DownloadItemImpl::DebugDownloadStateString( 1979 const char* DownloadItemImpl::DebugDownloadStateString(
1937 DownloadInternalState state) { 1980 DownloadInternalState state) {
1938 switch (state) { 1981 switch (state) {
1939 case INITIAL_INTERNAL: 1982 case INITIAL_INTERNAL:
1940 return "INITIAL"; 1983 return "INITIAL";
1941 case TARGET_PENDING_INTERNAL: 1984 case TARGET_PENDING_INTERNAL:
1942 return "TARGET_PENDING"; 1985 return "TARGET_PENDING";
1986 case INTERRUPTED_TARGET_PENDING_INTERNAL:
1987 return "INTERRUPTED_TARGET_PENDING";
1943 case TARGET_RESOLVED_INTERNAL: 1988 case TARGET_RESOLVED_INTERNAL:
1944 return "TARGET_RESOLVED"; 1989 return "TARGET_RESOLVED";
1945 case IN_PROGRESS_INTERNAL: 1990 case IN_PROGRESS_INTERNAL:
1946 return "IN_PROGRESS"; 1991 return "IN_PROGRESS";
1947 case COMPLETING_INTERNAL: 1992 case COMPLETING_INTERNAL:
1948 return "COMPLETING"; 1993 return "COMPLETING";
1949 case COMPLETE_INTERNAL: 1994 case COMPLETE_INTERNAL:
1950 return "COMPLETE"; 1995 return "COMPLETE";
1951 case CANCELLED_INTERNAL: 1996 case CANCELLED_INTERNAL:
1952 return "CANCELLED"; 1997 return "CANCELLED";
(...skipping 19 matching lines...) Expand all
1972 case RESUME_MODE_USER_CONTINUE: 2017 case RESUME_MODE_USER_CONTINUE:
1973 return "USER_CONTINUE"; 2018 return "USER_CONTINUE";
1974 case RESUME_MODE_USER_RESTART: 2019 case RESUME_MODE_USER_RESTART:
1975 return "USER_RESTART"; 2020 return "USER_RESTART";
1976 } 2021 }
1977 NOTREACHED() << "Unknown resume mode " << mode; 2022 NOTREACHED() << "Unknown resume mode " << mode;
1978 return "unknown"; 2023 return "unknown";
1979 } 2024 }
1980 2025
1981 } // namespace content 2026 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698