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

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

Issue 10827314: Revert 151351 - Replace the DownloadFileManager with direct ownership (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 4 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 #include "content/browser/download/download_item_impl.h" 5 #include "content/browser/download/download_item_impl.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/basictypes.h" 9 #include "base/basictypes.h"
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/file_util.h" 11 #include "base/file_util.h"
12 #include "base/format_macros.h" 12 #include "base/format_macros.h"
13 #include "base/i18n/case_conversion.h" 13 #include "base/i18n/case_conversion.h"
14 #include "base/i18n/string_search.h" 14 #include "base/i18n/string_search.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/metrics/histogram.h" 16 #include "base/metrics/histogram.h"
17 #include "base/stl_util.h" 17 #include "base/stl_util.h"
18 #include "base/stringprintf.h" 18 #include "base/stringprintf.h"
19 #include "base/utf_string_conversions.h" 19 #include "base/utf_string_conversions.h"
20 #include "content/browser/download/download_create_info.h" 20 #include "content/browser/download/download_create_info.h"
21 #include "content/browser/download/download_file.h" 21 #include "content/browser/download/download_file.h"
22 #include "content/browser/download/download_file_manager.h"
22 #include "content/browser/download/download_interrupt_reasons_impl.h" 23 #include "content/browser/download/download_interrupt_reasons_impl.h"
23 #include "content/browser/download/download_item_impl_delegate.h" 24 #include "content/browser/download/download_item_impl_delegate.h"
24 #include "content/browser/download/download_request_handle.h" 25 #include "content/browser/download/download_request_handle.h"
25 #include "content/browser/download/download_stats.h" 26 #include "content/browser/download/download_stats.h"
26 #include "content/browser/web_contents/web_contents_impl.h" 27 #include "content/browser/web_contents/web_contents_impl.h"
27 #include "content/public/browser/browser_thread.h" 28 #include "content/public/browser/browser_thread.h"
28 #include "content/public/browser/content_browser_client.h" 29 #include "content/public/browser/content_browser_client.h"
29 #include "content/public/browser/download_persistent_store_info.h" 30 #include "content/public/browser/download_persistent_store_info.h"
30 #include "net/base/net_util.h" 31 #include "net/base/net_util.h"
31 32
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 return NULL; 112 return NULL;
112 } 113 }
113 virtual void PauseRequest() const OVERRIDE {} 114 virtual void PauseRequest() const OVERRIDE {}
114 virtual void ResumeRequest() const OVERRIDE {} 115 virtual void ResumeRequest() const OVERRIDE {}
115 virtual void CancelRequest() const OVERRIDE {} 116 virtual void CancelRequest() const OVERRIDE {}
116 virtual std::string DebugString() const OVERRIDE { 117 virtual std::string DebugString() const OVERRIDE {
117 return "Null DownloadRequestHandle"; 118 return "Null DownloadRequestHandle";
118 } 119 }
119 }; 120 };
120 121
121 // Detach the specified download file, then invoke the callback on the
122 // UI thread. Note that this will also delete the DownloadFile object,
123 // as the function accepts ownership and does not transfer it on.
124 //
125 // This is effectively a "PostTaskAndReply" targeted at
126 // download_file->Detach(), with the difference that the destruction of the
127 // task arguments is done on the target thread rather than the originating
128 // thread. If |ui_callback| wasn't needed, we could have just used
129 // PostTask transferring ownership of download_file, and if download_file
130 // FILE thread destruction wasn't needed, we could have used PostTaskAndReply.
131 static void ReleaseDownloadFile(scoped_ptr<DownloadFile> download_file,
132 const base::Closure& ui_callback) {
133 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
134 download_file->Detach();
135
136 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, ui_callback);
137 }
138
139 } // namespace 122 } // namespace
140 123
141 namespace content { 124 namespace content {
142 125
143 // Our download table ID starts at 1, so we use 0 to represent a download that 126 // Our download table ID starts at 1, so we use 0 to represent a download that
144 // has started, but has not yet had its data persisted in the table. We use fake 127 // has started, but has not yet had its data persisted in the table. We use fake
145 // database handles in incognito mode starting at -1 and progressively getting 128 // database handles in incognito mode starting at -1 and progressively getting
146 // more negative. 129 // more negative.
147 // static 130 // static
148 const int DownloadItem::kUninitializedHandle = 0; 131 const int DownloadItem::kUninitializedHandle = 0;
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 delegate_delayed_complete_(false), 290 delegate_delayed_complete_(false),
308 bound_net_log_(bound_net_log), 291 bound_net_log_(bound_net_log),
309 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { 292 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
310 delegate_->Attach(); 293 delegate_->Attach();
311 Init(true /* actively downloading */, 294 Init(true /* actively downloading */,
312 download_net_logs::SRC_SAVE_PAGE_AS); 295 download_net_logs::SRC_SAVE_PAGE_AS);
313 } 296 }
314 297
315 DownloadItemImpl::~DownloadItemImpl() { 298 DownloadItemImpl::~DownloadItemImpl() {
316 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 299 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
317
318 // Should always have been nuked before now, at worst in
319 // DownloadManager shutdown.
320 DCHECK(!download_file_.get());
321
322 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadDestroyed(this)); 300 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadDestroyed(this));
323 delegate_->AssertStateConsistent(this); 301 delegate_->AssertStateConsistent(this);
324 delegate_->Detach(); 302 delegate_->Detach();
325 } 303 }
326 304
327 base::WeakPtr<content::DownloadDestinationObserver>
328 DownloadItemImpl::DestinationObserverAsWeakPtr() {
329 // Return does private downcast.
330 return weak_ptr_factory_.GetWeakPtr();
331 }
332
333 void DownloadItemImpl::AddObserver(Observer* observer) { 305 void DownloadItemImpl::AddObserver(Observer* observer) {
334 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 306 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
335 307
336 observers_.AddObserver(observer); 308 observers_.AddObserver(observer);
337 } 309 }
338 310
339 void DownloadItemImpl::RemoveObserver(Observer* observer) { 311 void DownloadItemImpl::RemoveObserver(Observer* observer) {
340 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 312 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
341 313
342 observers_.RemoveObserver(observer); 314 observers_.RemoveObserver(observer);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 bound_net_log_.AddEvent( 383 bound_net_log_.AddEvent(
412 net::NetLog::TYPE_DOWNLOAD_ITEM_SAFETY_STATE_UPDATED, 384 net::NetLog::TYPE_DOWNLOAD_ITEM_SAFETY_STATE_UPDATED,
413 base::Bind(&download_net_logs::ItemCheckedCallback, 385 base::Bind(&download_net_logs::ItemCheckedCallback,
414 GetDangerType(), GetSafetyState())); 386 GetDangerType(), GetSafetyState()));
415 387
416 UpdateObservers(); 388 UpdateObservers();
417 389
418 delegate_->MaybeCompleteDownload(this); 390 delegate_->MaybeCompleteDownload(this);
419 } 391 }
420 392
393 void DownloadItemImpl::ProgressComplete(int64 bytes_so_far,
394 const std::string& final_hash) {
395 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
396
397 hash_ = final_hash;
398 hash_state_ = "";
399
400 received_bytes_ = bytes_so_far;
401
402 // If we've received more data than we were expecting (bad server info?),
403 // revert to 'unknown size mode'.
404 if (received_bytes_ > total_bytes_)
405 total_bytes_ = 0;
406 }
407
421 // Updates from the download thread may have been posted while this download 408 // Updates from the download thread may have been posted while this download
422 // was being cancelled in the UI thread, so we'll accept them unless we're 409 // was being cancelled in the UI thread, so we'll accept them unless we're
423 // complete. 410 // complete.
424 void DownloadItemImpl::UpdateProgress(int64 bytes_so_far, 411 void DownloadItemImpl::UpdateProgress(int64 bytes_so_far,
425 int64 bytes_per_sec, 412 int64 bytes_per_sec,
426 const std::string& hash_state) { 413 const std::string& hash_state) {
427 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 414 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
428 415
429 if (!IsInProgress()) { 416 if (!IsInProgress()) {
430 // Ignore if we're no longer in-progress. This can happen if we race a 417 // Ignore if we're no longer in-progress. This can happen if we race a
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 VLOG(20) << __FUNCTION__ << "() download = " << DebugString(true); 454 VLOG(20) << __FUNCTION__ << "() download = " << DebugString(true);
468 if (!IsPartialDownload()) { 455 if (!IsPartialDownload()) {
469 // Small downloads might be complete before this method has 456 // Small downloads might be complete before this method has
470 // a chance to run. 457 // a chance to run.
471 return; 458 return;
472 } 459 }
473 460
474 download_stats::RecordDownloadCount(download_stats::CANCELLED_COUNT); 461 download_stats::RecordDownloadCount(download_stats::CANCELLED_COUNT);
475 462
476 TransitionTo(CANCELLED); 463 TransitionTo(CANCELLED);
477
478 // Cancel and remove the download file.
479 DCHECK(download_file_.get());
480 BrowserThread::PostTask(
481 BrowserThread::FILE, FROM_HERE,
482 // Will be deleted at end of task execution.
483 base::Bind(&DownloadFile::Cancel, base::Owned(download_file_.release())));
484
485 // Cancel the originating URL request.
486 request_handle_->CancelRequest();
487
488 if (user_cancel) 464 if (user_cancel)
489 delegate_->DownloadStopped(this); 465 delegate_->DownloadStopped(this);
490 } 466 }
491 467
492 // We're starting the download.
493 void DownloadItemImpl::Start(scoped_ptr<content::DownloadFile> download_file) {
494 DCHECK(!download_file_.get());
495 download_file_ = download_file.Pass();
496
497 BrowserThread::PostTask(
498 BrowserThread::FILE, FROM_HERE,
499 base::Bind(&DownloadFile::Initialize,
500 // Safe because we control download file lifetime.
501 base::Unretained(download_file_.get()),
502 base::Bind(&DownloadItemImpl::OnDownloadFileInitialized,
503 weak_ptr_factory_.GetWeakPtr())));
504 }
505
506 // An error occurred somewhere. 468 // An error occurred somewhere.
507 void DownloadItemImpl::Interrupt(content::DownloadInterruptReason reason) { 469 void DownloadItemImpl::Interrupt(content::DownloadInterruptReason reason) {
508 // Somewhat counter-intuitively, it is possible for us to receive an 470 // Somewhat counter-intuitively, it is possible for us to receive an
509 // interrupt after we've already been interrupted. The generation of 471 // interrupt after we've already been interrupted. The generation of
510 // interrupts from the file thread Renames and the generation of 472 // interrupts from the file thread Renames and the generation of
511 // interrupts from disk writes go through two different mechanisms (driven 473 // interrupts from disk writes go through two different mechanisms (driven
512 // by rename requests from UI thread and by write requests from IO thread, 474 // by rename requests from UI thread and by write requests from IO thread,
513 // respectively), and since we choose not to keep state on the File thread, 475 // respectively), and since we choose not to keep state on the File thread,
514 // this is the place where the races collide. It's also possible for 476 // this is the place where the races collide. It's also possible for
515 // interrupts to race with cancels. 477 // interrupts to race with cancels.
516 478
517 // Whatever happens, the first one to hit the UI thread wins. 479 // Whatever happens, the first one to hit the UI thread wins.
518 if (!IsInProgress()) 480 if (!IsInProgress())
519 return; 481 return;
520 482
521 last_reason_ = reason; 483 last_reason_ = reason;
522 TransitionTo(INTERRUPTED); 484 TransitionTo(INTERRUPTED);
523
524 // Cancel and remove the download file.
525 DCHECK(download_file_.get());
526 BrowserThread::PostTask(
527 BrowserThread::FILE, FROM_HERE,
528 // Will be deleted at end of task execution.
529 base::Bind(&DownloadFile::Cancel, base::Owned(download_file_.release())));
530
531 // Cancel the originating URL request.
532 request_handle_->CancelRequest();
533
534 download_stats::RecordDownloadInterrupted( 485 download_stats::RecordDownloadInterrupted(
535 reason, received_bytes_, total_bytes_); 486 reason, received_bytes_, total_bytes_);
536 delegate_->DownloadStopped(this); 487 delegate_->DownloadStopped(this);
537 } 488 }
538 489
539 void DownloadItemImpl::MarkAsComplete() { 490 void DownloadItemImpl::MarkAsComplete() {
540 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 491 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
541 492
542 DCHECK(all_data_saved_); 493 DCHECK(all_data_saved_);
543 end_time_ = base::Time::Now(); 494 end_time_ = base::Time::Now();
544 TransitionTo(COMPLETE); 495 TransitionTo(COMPLETE);
545 } 496 }
546 497
547 void DownloadItemImpl::DelayedDownloadOpened(bool auto_opened) { 498 void DownloadItemImpl::DelayedDownloadOpened(bool auto_opened) {
548 auto_opened_ = auto_opened; 499 auto_opened_ = auto_opened;
549 Completed(); 500 Completed();
550 } 501 }
551 502
552 void DownloadItemImpl::OnAllDataSaved( 503 void DownloadItemImpl::OnAllDataSaved(
553 const std::string& final_hash) { 504 int64 size, const std::string& final_hash) {
554 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 505 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
555 506
556 DCHECK_EQ(IN_PROGRESS, state_);
557 DCHECK(!all_data_saved_); 507 DCHECK(!all_data_saved_);
558 all_data_saved_ = true; 508 all_data_saved_ = true;
559 509 ProgressComplete(size, final_hash);
560 // Store final hash and null out intermediate serialized hash state.
561 hash_ = final_hash;
562 hash_state_ = "";
563
564 UpdateObservers(); 510 UpdateObservers();
565 } 511 }
566 512
567 void DownloadItemImpl::OnDownloadedFileRemoved() { 513 void DownloadItemImpl::OnDownloadedFileRemoved() {
568 file_externally_removed_ = true; 514 file_externally_removed_ = true;
569 UpdateObservers(); 515 UpdateObservers();
570 } 516 }
571 517
572 void DownloadItemImpl::MaybeCompleteDownload() { 518 void DownloadItemImpl::MaybeCompleteDownload() {
573 // TODO(rdsmith): Move logic for this function here. 519 // TODO(rdsmith): Move logic for this function here.
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
748 request_handle_->ResumeRequest(); 694 request_handle_->ResumeRequest();
749 else 695 else
750 request_handle_->PauseRequest(); 696 request_handle_->PauseRequest();
751 is_paused_ = !is_paused_; 697 is_paused_ = !is_paused_;
752 UpdateObservers(); 698 UpdateObservers();
753 } 699 }
754 700
755 void DownloadItemImpl::OnDownloadCompleting() { 701 void DownloadItemImpl::OnDownloadCompleting() {
756 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 702 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
757 703
758 if (!IsInProgress())
759 return;
760
761 VLOG(20) << __FUNCTION__ << "()" 704 VLOG(20) << __FUNCTION__ << "()"
762 << " needs rename = " << NeedsRename() 705 << " needs rename = " << NeedsRename()
763 << " " << DebugString(true); 706 << " " << DebugString(true);
764 DCHECK(!GetTargetName().empty()); 707 DCHECK(!GetTargetName().empty());
765 DCHECK_NE(DANGEROUS, GetSafetyState()); 708 DCHECK_NE(DANGEROUS, GetSafetyState());
766 709
767 DCHECK(download_file_.get());
768 if (NeedsRename()) { 710 if (NeedsRename()) {
769 content::DownloadFile::RenameCompletionCallback callback = 711 DownloadFileManager::RenameCompletionCallback callback =
770 base::Bind(&DownloadItemImpl::OnDownloadRenamedToFinalName, 712 base::Bind(&DownloadItemImpl::OnDownloadRenamedToFinalName,
771 weak_ptr_factory_.GetWeakPtr()); 713 weak_ptr_factory_.GetWeakPtr());
772 BrowserThread::PostTask( 714 BrowserThread::PostTask(
773 BrowserThread::FILE, FROM_HERE, 715 BrowserThread::FILE, FROM_HERE,
774 base::Bind(&DownloadFile::Rename, 716 base::Bind(&DownloadFileManager::RenameDownloadFile,
775 base::Unretained(download_file_.get()), 717 delegate_->GetDownloadFileManager(), GetGlobalId(),
776 GetTargetFilePath(), true, callback)); 718 GetTargetFilePath(), true, callback));
777 } else { 719 } else {
778 // Complete the download and release the DownloadFile. 720 // Complete the download and release the DownloadFile.
779 BrowserThread::PostTask( 721 BrowserThread::PostTask(
780 BrowserThread::FILE, FROM_HERE, 722 BrowserThread::FILE, FROM_HERE,
781 base::Bind(&ReleaseDownloadFile, base::Passed(download_file_.Pass()), 723 base::Bind(&DownloadFileManager::CompleteDownload,
724 delegate_->GetDownloadFileManager(), GetGlobalId(),
782 base::Bind(&DownloadItemImpl::OnDownloadFileReleased, 725 base::Bind(&DownloadItemImpl::OnDownloadFileReleased,
783 weak_ptr_factory_.GetWeakPtr()))); 726 weak_ptr_factory_.GetWeakPtr())));
784 } 727 }
785 } 728 }
786 729
787 void DownloadItemImpl::OnDownloadRenamedToFinalName( 730 void DownloadItemImpl::OnDownloadRenamedToFinalName(
788 content::DownloadInterruptReason reason, 731 content::DownloadInterruptReason reason,
789 const FilePath& full_path) { 732 const FilePath& full_path) {
790 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 733 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
791 734
792 if (!IsInProgress())
793 return;
794
795 VLOG(20) << __FUNCTION__ << "()" 735 VLOG(20) << __FUNCTION__ << "()"
796 << " full_path = \"" << full_path.value() << "\"" 736 << " full_path = \"" << full_path.value() << "\""
797 << " needed rename = " << NeedsRename() 737 << " needed rename = " << NeedsRename()
798 << " " << DebugString(false); 738 << " " << DebugString(false);
799 DCHECK(NeedsRename()); 739 DCHECK(NeedsRename());
800 740
801 if (content::DOWNLOAD_INTERRUPT_REASON_NONE != reason) { 741 if (content::DOWNLOAD_INTERRUPT_REASON_NONE != reason) {
802 Interrupt(reason); 742 Interrupt(reason);
803 return; 743 return;
804 } 744 }
805 745
806 // full_path is now the current and target file path. 746 // full_path is now the current and target file path.
807 DCHECK(!full_path.empty()); 747 DCHECK(!full_path.empty());
808 target_path_ = full_path; 748 target_path_ = full_path;
809 SetFullPath(full_path); 749 SetFullPath(full_path);
810 delegate_->DownloadRenamedToFinalName(this); 750 delegate_->DownloadRenamedToFinalName(this);
811 751
812 // Complete the download and release the DownloadFile. 752 // Complete the download and release the DownloadFile.
813 // TODO(rdsmith): Unify this path with the !NeedsRename() path in
814 // OnDownloadCompleting above. This can happen easily after history
815 // is made into an observer and the path accessors are cleaned up;
816 // that should allow OnDownloadCompleting to simply call
817 // OnDownloadRenamedToFinalName directly.
818 DCHECK(download_file_.get());
819 BrowserThread::PostTask( 753 BrowserThread::PostTask(
820 BrowserThread::FILE, FROM_HERE, 754 BrowserThread::FILE, FROM_HERE,
821 base::Bind(&ReleaseDownloadFile, base::Passed(download_file_.Pass()), 755 base::Bind(&DownloadFileManager::CompleteDownload,
756 delegate_->GetDownloadFileManager(), GetGlobalId(),
822 base::Bind(&DownloadItemImpl::OnDownloadFileReleased, 757 base::Bind(&DownloadItemImpl::OnDownloadFileReleased,
823 weak_ptr_factory_.GetWeakPtr()))); 758 weak_ptr_factory_.GetWeakPtr())));
824 } 759 }
825 760
826 void DownloadItemImpl::OnDownloadFileInitialized(
827 content::DownloadInterruptReason result) {
828 if (result != content::DOWNLOAD_INTERRUPT_REASON_NONE) {
829 Interrupt(result);
830 // TODO(rdsmith): It makes no sense to continue along the
831 // regular download path after we've gotten an error. But it's
832 // the way the code has historically worked, and this allows us
833 // to get the download persisted and observers of the download manager
834 // notified, so tests work. When we execute all side effects of cancel
835 // (including queue removal) immedately rather than waiting for
836 // persistence we should replace this comment with a "return;".
837 }
838
839 delegate_->DelegateStart(this);
840 }
841
842 void DownloadItemImpl::OnDownloadFileReleased() { 761 void DownloadItemImpl::OnDownloadFileReleased() {
843 if (delegate_->ShouldOpenDownload(this)) 762 if (delegate_->ShouldOpenDownload(this))
844 Completed(); 763 Completed();
845 else 764 else
846 delegate_delayed_complete_ = true; 765 delegate_delayed_complete_ = true;
847 } 766 }
848 767
849 void DownloadItemImpl::OnDownloadRenamedToIntermediateName( 768 void DownloadItemImpl::OnDownloadRenamedToIntermediateName(
850 content::DownloadInterruptReason reason, 769 content::DownloadInterruptReason reason,
851 const FilePath& full_path) { 770 const FilePath& full_path) {
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 target_path_ = target_path; 879 target_path_ = target_path;
961 target_disposition_ = disposition; 880 target_disposition_ = disposition;
962 SetDangerType(danger_type); 881 SetDangerType(danger_type);
963 // TODO(asanka): SetDangerType() doesn't need to send a notification here. 882 // TODO(asanka): SetDangerType() doesn't need to send a notification here.
964 883
965 // We want the intermediate and target paths to refer to the same directory so 884 // We want the intermediate and target paths to refer to the same directory so
966 // that they are both on the same device and subject to same 885 // that they are both on the same device and subject to same
967 // space/permission/availability constraints. 886 // space/permission/availability constraints.
968 DCHECK(intermediate_path.DirName() == target_path.DirName()); 887 DCHECK(intermediate_path.DirName() == target_path.DirName());
969 888
970 if (!IsInProgress()) {
971 // If we've been cancelled or interrupted while the target was being
972 // determined, continue the cascade with a null name.
973 // The error doesn't matter as the cause of download stoppaged
974 // will already have been recorded.
975 OnDownloadRenamedToIntermediateName(
976 content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, FilePath());
977 return;
978 }
979
980 // Rename to intermediate name. 889 // Rename to intermediate name.
981 // TODO(asanka): Skip this rename if AllDataSaved() is true. This avoids a 890 // TODO(asanka): Skip this rename if AllDataSaved() is true. This avoids a
982 // spurious rename when we can just rename to the final 891 // spurious rename when we can just rename to the final
983 // filename. Unnecessary renames may cause bugs like 892 // filename. Unnecessary renames may cause bugs like
984 // http://crbug.com/74187. 893 // http://crbug.com/74187.
985 DCHECK(download_file_.get()); 894 DownloadFileManager::RenameCompletionCallback callback =
986 DownloadFile::RenameCompletionCallback callback =
987 base::Bind(&DownloadItemImpl::OnDownloadRenamedToIntermediateName, 895 base::Bind(&DownloadItemImpl::OnDownloadRenamedToIntermediateName,
988 weak_ptr_factory_.GetWeakPtr()); 896 weak_ptr_factory_.GetWeakPtr());
989 BrowserThread::PostTask( 897 BrowserThread::PostTask(
990 BrowserThread::FILE, FROM_HERE, 898 BrowserThread::FILE, FROM_HERE,
991 base::Bind(&DownloadFile::Rename, 899 base::Bind(&DownloadFileManager::RenameDownloadFile,
992 // Safe because we control download file lifetime. 900 delegate_->GetDownloadFileManager(), GetGlobalId(),
993 base::Unretained(download_file_.get()),
994 intermediate_path, false, callback)); 901 intermediate_path, false, callback));
995 } 902 }
996 903
997 void DownloadItemImpl::OnContentCheckCompleted( 904 void DownloadItemImpl::OnContentCheckCompleted(
998 content::DownloadDangerType danger_type) { 905 content::DownloadDangerType danger_type) {
999 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 906 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1000 DCHECK(AllDataSaved()); 907 DCHECK(AllDataSaved());
1001 SetDangerType(danger_type); 908 SetDangerType(danger_type);
1002 UpdateObservers(); 909 UpdateObservers();
1003 } 910 }
(...skipping 10 matching lines...) Expand all
1014 921
1015 void DownloadItemImpl::SetDisplayName(const FilePath& name) { 922 void DownloadItemImpl::SetDisplayName(const FilePath& name) {
1016 display_name_ = name; 923 display_name_ = name;
1017 } 924 }
1018 925
1019 FilePath DownloadItemImpl::GetUserVerifiedFilePath() const { 926 FilePath DownloadItemImpl::GetUserVerifiedFilePath() const {
1020 return (safety_state_ == DownloadItem::SAFE) ? 927 return (safety_state_ == DownloadItem::SAFE) ?
1021 GetTargetFilePath() : GetFullPath(); 928 GetTargetFilePath() : GetFullPath();
1022 } 929 }
1023 930
1024 void DownloadItemImpl::DestinationUpdate(int64 bytes_so_far, 931 void DownloadItemImpl::OffThreadCancel() {
1025 int64 bytes_per_sec,
1026 const std::string& hash_state) {
1027 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 932 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
933 request_handle_->CancelRequest();
1028 934
1029 if (!IsInProgress()) { 935 BrowserThread::PostTask(
1030 // Ignore if we're no longer in-progress. This can happen if we race a 936 BrowserThread::FILE, FROM_HERE,
1031 // Cancel on the UI thread with an update on the FILE thread. 937 base::Bind(&DownloadFileManager::CancelDownload,
1032 // 938 delegate_->GetDownloadFileManager(), download_id_));
1033 // TODO(rdsmith): Arguably we should let this go through, as this means
1034 // the download really did get further than we know before it was
1035 // cancelled. But the gain isn't very large, and the code is more
1036 // fragile if it has to support in progress updates in a non-in-progress
1037 // state. This issue should be readdressed when we revamp performance
1038 // reporting.
1039 return;
1040 }
1041 bytes_per_sec_ = bytes_per_sec;
1042 hash_state_ = hash_state;
1043 received_bytes_ = bytes_so_far;
1044
1045 // If we've received more data than we were expecting (bad server info?),
1046 // revert to 'unknown size mode'.
1047 if (received_bytes_ > total_bytes_)
1048 total_bytes_ = 0;
1049
1050 if (bound_net_log_.IsLoggingAllEvents()) {
1051 bound_net_log_.AddEvent(
1052 net::NetLog::TYPE_DOWNLOAD_ITEM_UPDATED,
1053 net::NetLog::Int64Callback("bytes_so_far", received_bytes_));
1054 }
1055
1056 UpdateObservers();
1057 }
1058
1059 void DownloadItemImpl::DestinationError(
1060 content::DownloadInterruptReason reason) {
1061 // The DestinationError and Interrupt routines are being kept separate
1062 // to allow for a future merging of the Cancel and Interrupt routines..
1063 Interrupt(reason);
1064 }
1065
1066 void DownloadItemImpl::DestinationCompleted(const std::string& final_hash) {
1067 if (!IsInProgress())
1068 return;
1069 OnAllDataSaved(final_hash);
1070 delegate_->MaybeCompleteDownload(this);
1071 } 939 }
1072 940
1073 void DownloadItemImpl::Init(bool active, 941 void DownloadItemImpl::Init(bool active,
1074 download_net_logs::DownloadType download_type) { 942 download_net_logs::DownloadType download_type) {
1075 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 943 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1076 944
1077 if (active) 945 if (active)
1078 download_stats::RecordDownloadCount(download_stats::START_COUNT); 946 download_stats::RecordDownloadCount(download_stats::START_COUNT);
1079 947
1080 if (target_path_.empty()) 948 if (target_path_.empty())
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1171 " total = %" PRId64 1039 " total = %" PRId64
1172 " received = %" PRId64 1040 " received = %" PRId64
1173 " reason = %s" 1041 " reason = %s"
1174 " paused = %c" 1042 " paused = %c"
1175 " otr = %c" 1043 " otr = %c"
1176 " safety = %s" 1044 " safety = %s"
1177 " last_modified = '%s'" 1045 " last_modified = '%s'"
1178 " etag = '%s'" 1046 " etag = '%s'"
1179 " url_chain = \n\t\"%s\"\n\t" 1047 " url_chain = \n\t\"%s\"\n\t"
1180 " full_path = \"%" PRFilePath "\"" 1048 " full_path = \"%" PRFilePath "\""
1181 " target_path = \"%" PRFilePath "\"" 1049 " target_path = \"%" PRFilePath "\"",
1182 " has download file = %s",
1183 GetDbHandle(), 1050 GetDbHandle(),
1184 GetTotalBytes(), 1051 GetTotalBytes(),
1185 GetReceivedBytes(), 1052 GetReceivedBytes(),
1186 InterruptReasonDebugString(last_reason_).c_str(), 1053 InterruptReasonDebugString(last_reason_).c_str(),
1187 IsPaused() ? 'T' : 'F', 1054 IsPaused() ? 'T' : 'F',
1188 IsOtr() ? 'T' : 'F', 1055 IsOtr() ? 'T' : 'F',
1189 DebugSafetyStateString(GetSafetyState()), 1056 DebugSafetyStateString(GetSafetyState()),
1190 GetLastModifiedTime().c_str(), 1057 GetLastModifiedTime().c_str(),
1191 GetETag().c_str(), 1058 GetETag().c_str(),
1192 url_list.c_str(), 1059 url_list.c_str(),
1193 GetFullPath().value().c_str(), 1060 GetFullPath().value().c_str(),
1194 GetTargetFilePath().value().c_str(), 1061 GetTargetFilePath().value().c_str());
1195 download_file_.get() ? "true" : "false");
1196 } else { 1062 } else {
1197 description += base::StringPrintf(" url = \"%s\"", url_list.c_str()); 1063 description += base::StringPrintf(" url = \"%s\"", url_list.c_str());
1198 } 1064 }
1199 1065
1200 description += " }"; 1066 description += " }";
1201 1067
1202 return description; 1068 return description;
1203 } 1069 }
1204 1070
1205 bool DownloadItemImpl::AllDataSaved() const { return all_data_saved_; } 1071 bool DownloadItemImpl::AllDataSaved() const { return all_data_saved_; }
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1296 void DownloadItemImpl::SetOpened(bool opened) { opened_ = opened; } 1162 void DownloadItemImpl::SetOpened(bool opened) { opened_ = opened; }
1297 bool DownloadItemImpl::GetOpened() const { return opened_; } 1163 bool DownloadItemImpl::GetOpened() const { return opened_; }
1298 const std::string& DownloadItemImpl::GetLastModifiedTime() const { 1164 const std::string& DownloadItemImpl::GetLastModifiedTime() const {
1299 return last_modified_time_; 1165 return last_modified_time_;
1300 } 1166 }
1301 const std::string& DownloadItemImpl::GetETag() const { return etag_; } 1167 const std::string& DownloadItemImpl::GetETag() const { return etag_; }
1302 content::DownloadInterruptReason DownloadItemImpl::GetLastReason() const { 1168 content::DownloadInterruptReason DownloadItemImpl::GetLastReason() const {
1303 return last_reason_; 1169 return last_reason_;
1304 } 1170 }
1305 void DownloadItemImpl::MockDownloadOpenForTesting() { open_enabled_ = false; } 1171 void DownloadItemImpl::MockDownloadOpenForTesting() { open_enabled_ = false; }
OLDNEW
« no previous file with comments | « content/browser/download/download_item_impl.h ('k') | content/browser/download/download_item_impl_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698