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

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

Issue 10823406: Remove DownloadFileManager in favor of direct ownership of DownloadFiles. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added weasel words to justify current notification source. Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #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"
23 #include "content/browser/download/download_interrupt_reasons_impl.h" 22 #include "content/browser/download/download_interrupt_reasons_impl.h"
24 #include "content/browser/download/download_item_impl_delegate.h" 23 #include "content/browser/download/download_item_impl_delegate.h"
25 #include "content/browser/download/download_request_handle.h" 24 #include "content/browser/download/download_request_handle.h"
26 #include "content/browser/download/download_stats.h" 25 #include "content/browser/download/download_stats.h"
27 #include "content/browser/web_contents/web_contents_impl.h" 26 #include "content/browser/web_contents/web_contents_impl.h"
28 #include "content/public/browser/browser_thread.h" 27 #include "content/public/browser/browser_thread.h"
29 #include "content/public/browser/content_browser_client.h" 28 #include "content/public/browser/content_browser_client.h"
30 #include "content/public/browser/download_persistent_store_info.h" 29 #include "content/public/browser/download_persistent_store_info.h"
31 #include "net/base/net_util.h" 30 #include "net/base/net_util.h"
32 31
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 return NULL; 111 return NULL;
113 } 112 }
114 virtual void PauseRequest() const OVERRIDE {} 113 virtual void PauseRequest() const OVERRIDE {}
115 virtual void ResumeRequest() const OVERRIDE {} 114 virtual void ResumeRequest() const OVERRIDE {}
116 virtual void CancelRequest() const OVERRIDE {} 115 virtual void CancelRequest() const OVERRIDE {}
117 virtual std::string DebugString() const OVERRIDE { 116 virtual std::string DebugString() const OVERRIDE {
118 return "Null DownloadRequestHandle"; 117 return "Null DownloadRequestHandle";
119 } 118 }
120 }; 119 };
121 120
121 // Wrapper around DownloadFile::Detach and DownloadFile::Cancel that
122 // takes ownership of the DownloadFile and hence implicitly destroys it
123 // at the end of the function.
124 static void DownloadFileDetach(scoped_ptr<DownloadFile> download_file) {
125 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
126 download_file->Detach();
127 }
128
129 static void DownloadFileCancel(scoped_ptr<DownloadFile> download_file) {
130 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
131 download_file->Cancel();
132 }
133
122 } // namespace 134 } // namespace
123 135
124 namespace content { 136 namespace content {
125 137
126 // Our download table ID starts at 1, so we use 0 to represent a download that 138 // Our download table ID starts at 1, so we use 0 to represent a download that
127 // has started, but has not yet had its data persisted in the table. We use fake 139 // has started, but has not yet had its data persisted in the table. We use fake
128 // database handles in incognito mode starting at -1 and progressively getting 140 // database handles in incognito mode starting at -1 and progressively getting
129 // more negative. 141 // more negative.
130 // static 142 // static
131 const int DownloadItem::kUninitializedHandle = 0; 143 const int DownloadItem::kUninitializedHandle = 0;
132 144
133 const char DownloadItem::kEmptyFileHash[] = ""; 145 const char DownloadItem::kEmptyFileHash[] = "";
134 146
135 } 147 }
136 148
137 // Our download table ID starts at 1, so we use 0 to represent a download that 149 // Our download table ID starts at 1, so we use 0 to represent a download that
138 // has started, but has not yet had its data persisted in the table. We use fake 150 // has started, but has not yet had its data persisted in the table. We use fake
139 // database handles in incognito mode starting at -1 and progressively getting 151 // database handles in incognito mode starting at -1 and progressively getting
140 // more negative. 152 // more negative.
141 153
142 // Constructor for reading from the history service. 154 // Constructor for reading from the history service.
143 DownloadItemImpl::DownloadItemImpl(DownloadItemImplDelegate* delegate, 155 DownloadItemImpl::DownloadItemImpl(DownloadItemImplDelegate* delegate,
144 DownloadId download_id, 156 DownloadId download_id,
145 const DownloadPersistentStoreInfo& info, 157 const DownloadPersistentStoreInfo& info,
146 const net::BoundNetLog& bound_net_log) 158 const net::BoundNetLog& bound_net_log)
147 : download_id_(download_id), 159 : is_save_package_download_(false),
160 download_id_(download_id),
148 current_path_(info.path), 161 current_path_(info.path),
149 target_path_(info.path), 162 target_path_(info.path),
150 target_disposition_(TARGET_DISPOSITION_OVERWRITE), 163 target_disposition_(TARGET_DISPOSITION_OVERWRITE),
151 url_chain_(1, info.url), 164 url_chain_(1, info.url),
152 referrer_url_(info.referrer_url), 165 referrer_url_(info.referrer_url),
153 transition_type_(content::PAGE_TRANSITION_LINK), 166 transition_type_(content::PAGE_TRANSITION_LINK),
154 has_user_gesture_(false), 167 has_user_gesture_(false),
155 total_bytes_(info.total_bytes), 168 total_bytes_(info.total_bytes),
156 received_bytes_(info.received_bytes), 169 received_bytes_(info.received_bytes),
157 bytes_per_sec_(0), 170 bytes_per_sec_(0),
(...skipping 26 matching lines...) Expand all
184 Init(false /* not actively downloading */, 197 Init(false /* not actively downloading */,
185 download_net_logs::SRC_HISTORY_IMPORT); 198 download_net_logs::SRC_HISTORY_IMPORT);
186 } 199 }
187 200
188 // Constructing for a regular download: 201 // Constructing for a regular download:
189 DownloadItemImpl::DownloadItemImpl( 202 DownloadItemImpl::DownloadItemImpl(
190 DownloadItemImplDelegate* delegate, 203 DownloadItemImplDelegate* delegate,
191 const DownloadCreateInfo& info, 204 const DownloadCreateInfo& info,
192 scoped_ptr<DownloadRequestHandleInterface> request_handle, 205 scoped_ptr<DownloadRequestHandleInterface> request_handle,
193 const net::BoundNetLog& bound_net_log) 206 const net::BoundNetLog& bound_net_log)
194 : request_handle_(request_handle.Pass()), 207 : is_save_package_download_(false),
208 request_handle_(request_handle.Pass()),
195 download_id_(info.download_id), 209 download_id_(info.download_id),
196 target_disposition_( 210 target_disposition_(
197 (info.prompt_user_for_save_location) ? 211 (info.prompt_user_for_save_location) ?
198 TARGET_DISPOSITION_PROMPT : TARGET_DISPOSITION_OVERWRITE), 212 TARGET_DISPOSITION_PROMPT : TARGET_DISPOSITION_OVERWRITE),
199 url_chain_(info.url_chain), 213 url_chain_(info.url_chain),
200 referrer_url_(info.referrer_url), 214 referrer_url_(info.referrer_url),
201 suggested_filename_(UTF16ToUTF8(info.save_info.suggested_name)), 215 suggested_filename_(UTF16ToUTF8(info.save_info.suggested_name)),
202 forced_file_path_(info.save_info.file_path), 216 forced_file_path_(info.save_info.file_path),
203 transition_type_(info.transition_type), 217 transition_type_(info.transition_type),
204 has_user_gesture_(info.has_user_gesture), 218 has_user_gesture_(info.has_user_gesture),
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 bound_net_log_.source().ToEventParametersCallback()); 258 bound_net_log_.source().ToEventParametersCallback());
245 } 259 }
246 260
247 // Constructing for the "Save Page As..." feature: 261 // Constructing for the "Save Page As..." feature:
248 DownloadItemImpl::DownloadItemImpl(DownloadItemImplDelegate* delegate, 262 DownloadItemImpl::DownloadItemImpl(DownloadItemImplDelegate* delegate,
249 const FilePath& path, 263 const FilePath& path,
250 const GURL& url, 264 const GURL& url,
251 DownloadId download_id, 265 DownloadId download_id,
252 const std::string& mime_type, 266 const std::string& mime_type,
253 const net::BoundNetLog& bound_net_log) 267 const net::BoundNetLog& bound_net_log)
254 : request_handle_(new NullDownloadRequestHandle()), 268 : is_save_package_download_(true),
269 request_handle_(new NullDownloadRequestHandle()),
255 download_id_(download_id), 270 download_id_(download_id),
256 current_path_(path), 271 current_path_(path),
257 target_path_(path), 272 target_path_(path),
258 target_disposition_(TARGET_DISPOSITION_OVERWRITE), 273 target_disposition_(TARGET_DISPOSITION_OVERWRITE),
259 url_chain_(1, url), 274 url_chain_(1, url),
260 referrer_url_(GURL()), 275 referrer_url_(GURL()),
261 transition_type_(content::PAGE_TRANSITION_LINK), 276 transition_type_(content::PAGE_TRANSITION_LINK),
262 has_user_gesture_(false), 277 has_user_gesture_(false),
263 mime_type_(mime_type), 278 mime_type_(mime_type),
264 original_mime_type_(mime_type), 279 original_mime_type_(mime_type),
(...skipping 20 matching lines...) Expand all
285 delegate_delayed_complete_(false), 300 delegate_delayed_complete_(false),
286 bound_net_log_(bound_net_log), 301 bound_net_log_(bound_net_log),
287 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { 302 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
288 delegate_->Attach(); 303 delegate_->Attach();
289 Init(true /* actively downloading */, 304 Init(true /* actively downloading */,
290 download_net_logs::SRC_SAVE_PAGE_AS); 305 download_net_logs::SRC_SAVE_PAGE_AS);
291 } 306 }
292 307
293 DownloadItemImpl::~DownloadItemImpl() { 308 DownloadItemImpl::~DownloadItemImpl() {
294 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 309 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
310
311 // Should always have been nuked before now, at worst in
312 // DownloadManager shutdown.
313 DCHECK(!download_file_.get());
314
295 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadDestroyed(this)); 315 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadDestroyed(this));
296 delegate_->AssertStateConsistent(this); 316 delegate_->AssertStateConsistent(this);
297 delegate_->Detach(); 317 delegate_->Detach();
298 } 318 }
299 319
320 base::WeakPtr<content::DownloadDestinationObserver>
321 DownloadItemImpl::DestinationObserverAsWeakPtr() {
322 // Return does private downcast.
323 return weak_ptr_factory_.GetWeakPtr();
324 }
325
300 void DownloadItemImpl::AddObserver(Observer* observer) { 326 void DownloadItemImpl::AddObserver(Observer* observer) {
301 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 327 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
302 328
303 observers_.AddObserver(observer); 329 observers_.AddObserver(observer);
304 } 330 }
305 331
306 void DownloadItemImpl::RemoveObserver(Observer* observer) { 332 void DownloadItemImpl::RemoveObserver(Observer* observer) {
307 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 333 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
308 334
309 observers_.RemoveObserver(observer); 335 observers_.RemoveObserver(observer);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 bound_net_log_.AddEvent( 404 bound_net_log_.AddEvent(
379 net::NetLog::TYPE_DOWNLOAD_ITEM_SAFETY_STATE_UPDATED, 405 net::NetLog::TYPE_DOWNLOAD_ITEM_SAFETY_STATE_UPDATED,
380 base::Bind(&download_net_logs::ItemCheckedCallback, 406 base::Bind(&download_net_logs::ItemCheckedCallback,
381 GetDangerType(), GetSafetyState())); 407 GetDangerType(), GetSafetyState()));
382 408
383 UpdateObservers(); 409 UpdateObservers();
384 410
385 delegate_->MaybeCompleteDownload(this); 411 delegate_->MaybeCompleteDownload(this);
386 } 412 }
387 413
388 void DownloadItemImpl::ProgressComplete(int64 bytes_so_far,
389 const std::string& final_hash) {
390 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
391
392 hash_ = final_hash;
393 hash_state_ = "";
394
395 received_bytes_ = bytes_so_far;
396
397 // If we've received more data than we were expecting (bad server info?),
398 // revert to 'unknown size mode'.
399 if (received_bytes_ > total_bytes_)
400 total_bytes_ = 0;
401 }
402
403 // Updates from the download thread may have been posted while this download 414 // Updates from the download thread may have been posted while this download
404 // was being cancelled in the UI thread, so we'll accept them unless we're 415 // was being cancelled in the UI thread, so we'll accept them unless we're
405 // complete. 416 // complete.
406 void DownloadItemImpl::UpdateProgress(int64 bytes_so_far, 417 void DownloadItemImpl::UpdateProgress(int64 bytes_so_far,
407 int64 bytes_per_sec, 418 int64 bytes_per_sec,
408 const std::string& hash_state) { 419 const std::string& hash_state) {
409 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 420 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
410 421
411 if (!IsInProgress()) { 422 if (!IsInProgress()) {
412 // Ignore if we're no longer in-progress. This can happen if we race a 423 // 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
449 VLOG(20) << __FUNCTION__ << "() download = " << DebugString(true); 460 VLOG(20) << __FUNCTION__ << "() download = " << DebugString(true);
450 if (!IsPartialDownload()) { 461 if (!IsPartialDownload()) {
451 // Small downloads might be complete before this method has 462 // Small downloads might be complete before this method has
452 // a chance to run. 463 // a chance to run.
453 return; 464 return;
454 } 465 }
455 466
456 download_stats::RecordDownloadCount(download_stats::CANCELLED_COUNT); 467 download_stats::RecordDownloadCount(download_stats::CANCELLED_COUNT);
457 468
458 TransitionTo(CANCELLED); 469 TransitionTo(CANCELLED);
470
471 // Cancel and remove the download file.
472 // TODO(rdsmith/benjhayden): Remove condition as part of
473 // SavePackage integration.
474 if (!is_save_package_download_) {
475 CHECK(download_file_.get());
476 BrowserThread::PostTask(
477 BrowserThread::FILE, FROM_HERE,
478 // Will be deleted at end of task execution.
479 base::Bind(&DownloadFileCancel, base::Passed(download_file_.Pass())));
480 }
481
482 // Cancel the originating URL request.
483 request_handle_->CancelRequest();
484
459 if (user_cancel) 485 if (user_cancel)
460 delegate_->DownloadStopped(this); 486 delegate_->DownloadStopped(this);
461 } 487 }
462 488
489 // We're starting the download.
490 void DownloadItemImpl::Start(scoped_ptr<content::DownloadFile> download_file) {
491 DCHECK(!download_file_.get());
492 download_file_ = download_file.Pass();
493
494 BrowserThread::PostTask(
495 BrowserThread::FILE, FROM_HERE,
496 base::Bind(&DownloadFile::Initialize,
497 // Safe because we control download file lifetime.
498 base::Unretained(download_file_.get()),
499 base::Bind(&DownloadItemImpl::OnDownloadFileInitialized,
500 weak_ptr_factory_.GetWeakPtr())));
501 }
502
463 // An error occurred somewhere. 503 // An error occurred somewhere.
464 void DownloadItemImpl::Interrupt(content::DownloadInterruptReason reason) { 504 void DownloadItemImpl::Interrupt(content::DownloadInterruptReason reason) {
465 // Somewhat counter-intuitively, it is possible for us to receive an 505 // Somewhat counter-intuitively, it is possible for us to receive an
466 // interrupt after we've already been interrupted. The generation of 506 // interrupt after we've already been interrupted. The generation of
467 // interrupts from the file thread Renames and the generation of 507 // interrupts from the file thread Renames and the generation of
468 // interrupts from disk writes go through two different mechanisms (driven 508 // interrupts from disk writes go through two different mechanisms (driven
469 // by rename requests from UI thread and by write requests from IO thread, 509 // by rename requests from UI thread and by write requests from IO thread,
470 // respectively), and since we choose not to keep state on the File thread, 510 // respectively), and since we choose not to keep state on the File thread,
471 // this is the place where the races collide. It's also possible for 511 // this is the place where the races collide. It's also possible for
472 // interrupts to race with cancels. 512 // interrupts to race with cancels.
473 513
474 // Whatever happens, the first one to hit the UI thread wins. 514 // Whatever happens, the first one to hit the UI thread wins.
475 if (!IsInProgress()) 515 if (!IsInProgress())
476 return; 516 return;
477 517
478 last_reason_ = reason; 518 last_reason_ = reason;
479 TransitionTo(INTERRUPTED); 519 TransitionTo(INTERRUPTED);
520
521 // Cancel and remove the download file.
522 // TODO(rdsmith/benjhayden): Remove condition as part of
523 // SavePackage integration.
524 if (!is_save_package_download_) {
525 CHECK(download_file_.get());
526 BrowserThread::PostTask(
527 BrowserThread::FILE, FROM_HERE,
528 // Will be deleted at end of task execution.
529 base::Bind(&DownloadFileCancel, base::Passed(download_file_.Pass())));
530 }
531
532 // Cancel the originating URL request.
533 request_handle_->CancelRequest();
534
480 download_stats::RecordDownloadInterrupted( 535 download_stats::RecordDownloadInterrupted(
481 reason, received_bytes_, total_bytes_); 536 reason, received_bytes_, total_bytes_);
482 delegate_->DownloadStopped(this); 537 delegate_->DownloadStopped(this);
483 } 538 }
484 539
485 void DownloadItemImpl::MarkAsComplete() { 540 void DownloadItemImpl::MarkAsComplete() {
486 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 541 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
487 542
488 DCHECK(all_data_saved_); 543 DCHECK(all_data_saved_);
489 end_time_ = base::Time::Now(); 544 end_time_ = base::Time::Now();
490 TransitionTo(COMPLETE); 545 TransitionTo(COMPLETE);
491 } 546 }
492 547
493 void DownloadItemImpl::DelayedDownloadOpened(bool auto_opened) { 548 void DownloadItemImpl::DelayedDownloadOpened(bool auto_opened) {
494 auto_opened_ = auto_opened; 549 auto_opened_ = auto_opened;
495 Completed(); 550 Completed();
496 } 551 }
497 552
498 void DownloadItemImpl::OnAllDataSaved( 553 void DownloadItemImpl::OnAllDataSaved(
499 int64 size, const std::string& final_hash) { 554 const std::string& final_hash) {
500 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 555 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
501 556
557 DCHECK_EQ(IN_PROGRESS, state_);
502 DCHECK(!all_data_saved_); 558 DCHECK(!all_data_saved_);
503 all_data_saved_ = true; 559 all_data_saved_ = true;
504 ProgressComplete(size, final_hash); 560
561 // Store final hash and null out intermediate serialized hash state.
562 hash_ = final_hash;
563 hash_state_ = "";
564
505 UpdateObservers(); 565 UpdateObservers();
506 } 566 }
507 567
508 void DownloadItemImpl::OnDownloadedFileRemoved() { 568 void DownloadItemImpl::OnDownloadedFileRemoved() {
509 file_externally_removed_ = true; 569 file_externally_removed_ = true;
510 UpdateObservers(); 570 UpdateObservers();
511 } 571 }
512 572
513 void DownloadItemImpl::MaybeCompleteDownload() { 573 void DownloadItemImpl::MaybeCompleteDownload() {
514 // TODO(rdsmith): Move logic for this function here. 574 // TODO(rdsmith): Move logic for this function here.
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
689 request_handle_->ResumeRequest(); 749 request_handle_->ResumeRequest();
690 else 750 else
691 request_handle_->PauseRequest(); 751 request_handle_->PauseRequest();
692 is_paused_ = !is_paused_; 752 is_paused_ = !is_paused_;
693 UpdateObservers(); 753 UpdateObservers();
694 } 754 }
695 755
696 void DownloadItemImpl::OnDownloadCompleting() { 756 void DownloadItemImpl::OnDownloadCompleting() {
697 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 757 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
698 758
759 if (!IsInProgress())
760 return;
761
699 VLOG(20) << __FUNCTION__ << "()" 762 VLOG(20) << __FUNCTION__ << "()"
700 << " needs rename = " << NeedsRename() 763 << " needs rename = " << NeedsRename()
701 << " " << DebugString(true); 764 << " " << DebugString(true);
702 DCHECK(!GetTargetName().empty()); 765 DCHECK(!GetTargetName().empty());
703 DCHECK_NE(DANGEROUS, GetSafetyState()); 766 DCHECK_NE(DANGEROUS, GetSafetyState());
704 767
768 // TODO(rdsmith/benjhayden): Remove as part of SavePackage integration.
769 if (is_save_package_download_) {
770 // Avoid doing anything on the file thread; there's nothing we control
771 // there.
772 OnDownloadFileReleased();
773 return;
774 }
775
776 CHECK(download_file_.get());
benjhayden 2012/08/22 19:07:31 Should some of these new CHECKs be DCHECKs?
Randy Smith (Not in Mondays) 2012/08/23 16:55:58 So the context here is http://crbug.com/143600--th
705 if (NeedsRename()) { 777 if (NeedsRename()) {
706 DownloadFileManager::RenameCompletionCallback callback = 778 content::DownloadFile::RenameCompletionCallback callback =
707 base::Bind(&DownloadItemImpl::OnDownloadRenamedToFinalName, 779 base::Bind(&DownloadItemImpl::OnDownloadRenamedToFinalName,
708 weak_ptr_factory_.GetWeakPtr()); 780 weak_ptr_factory_.GetWeakPtr());
709 BrowserThread::PostTask( 781 BrowserThread::PostTask(
710 BrowserThread::FILE, FROM_HERE, 782 BrowserThread::FILE, FROM_HERE,
711 base::Bind(&DownloadFileManager::RenameDownloadFile, 783 base::Bind(&DownloadFile::Rename,
712 delegate_->GetDownloadFileManager(), GetGlobalId(), 784 base::Unretained(download_file_.get()),
713 GetTargetFilePath(), true, callback)); 785 GetTargetFilePath(), true, callback));
714 } else { 786 } else {
715 // Complete the download and release the DownloadFile. 787 // Complete the download and release the DownloadFile.
716 BrowserThread::PostTask( 788 BrowserThread::PostTaskAndReply(
717 BrowserThread::FILE, FROM_HERE, 789 BrowserThread::FILE, FROM_HERE,
718 base::Bind(&DownloadFileManager::CompleteDownload, 790 base::Bind(&DownloadFileDetach, base::Passed(download_file_.Pass())),
719 delegate_->GetDownloadFileManager(), GetGlobalId(), 791 base::Bind(&DownloadItemImpl::OnDownloadFileReleased,
720 base::Bind(&DownloadItemImpl::OnDownloadFileReleased, 792 weak_ptr_factory_.GetWeakPtr()));
721 weak_ptr_factory_.GetWeakPtr())));
722 } 793 }
723 } 794 }
724 795
725 void DownloadItemImpl::OnDownloadRenamedToFinalName( 796 void DownloadItemImpl::OnDownloadRenamedToFinalName(
726 content::DownloadInterruptReason reason, 797 content::DownloadInterruptReason reason,
727 const FilePath& full_path) { 798 const FilePath& full_path) {
728 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 799 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
729 800
801 if (!IsInProgress())
802 return;
803
730 VLOG(20) << __FUNCTION__ << "()" 804 VLOG(20) << __FUNCTION__ << "()"
731 << " full_path = \"" << full_path.value() << "\"" 805 << " full_path = \"" << full_path.value() << "\""
732 << " needed rename = " << NeedsRename() 806 << " needed rename = " << NeedsRename()
733 << " " << DebugString(false); 807 << " " << DebugString(false);
734 DCHECK(NeedsRename()); 808 DCHECK(NeedsRename());
735 809
736 if (content::DOWNLOAD_INTERRUPT_REASON_NONE != reason) { 810 if (content::DOWNLOAD_INTERRUPT_REASON_NONE != reason) {
737 Interrupt(reason); 811 Interrupt(reason);
738 return; 812 return;
739 } 813 }
740 814
741 // full_path is now the current and target file path. 815 // full_path is now the current and target file path.
742 DCHECK(!full_path.empty()); 816 DCHECK(!full_path.empty());
743 target_path_ = full_path; 817 target_path_ = full_path;
744 SetFullPath(full_path); 818 SetFullPath(full_path);
745 delegate_->DownloadRenamedToFinalName(this); 819 delegate_->DownloadRenamedToFinalName(this);
746 820
747 // Complete the download and release the DownloadFile. 821 // Complete the download and release the DownloadFile.
748 BrowserThread::PostTask( 822 // TODO(rdsmith): Unify this path with the !NeedsRename() path in
823 // OnDownloadCompleting above. This can happen easily after history
824 // is made into an observer and the path accessors are cleaned up;
825 // that should allow OnDownloadCompleting to simply call
826 // OnDownloadRenamedToFinalName directly.
827 DCHECK(!is_save_package_download_);
828 CHECK(download_file_.get());
829 BrowserThread::PostTaskAndReply(
749 BrowserThread::FILE, FROM_HERE, 830 BrowserThread::FILE, FROM_HERE,
750 base::Bind(&DownloadFileManager::CompleteDownload, 831 base::Bind(&DownloadFileDetach, base::Passed(download_file_.Pass())),
751 delegate_->GetDownloadFileManager(), GetGlobalId(), 832 base::Bind(&DownloadItemImpl::OnDownloadFileReleased,
752 base::Bind(&DownloadItemImpl::OnDownloadFileReleased, 833 weak_ptr_factory_.GetWeakPtr()));
753 weak_ptr_factory_.GetWeakPtr()))); 834 }
835
836 void DownloadItemImpl::OnDownloadFileInitialized(
837 content::DownloadInterruptReason result) {
838 if (result != content::DOWNLOAD_INTERRUPT_REASON_NONE) {
839 Interrupt(result);
840 // TODO(rdsmith): It makes no sense to continue along the
841 // regular download path after we've gotten an error. But it's
842 // the way the code has historically worked, and this allows us
843 // to get the download persisted and observers of the download manager
844 // notified, so tests work. When we execute all side effects of cancel
845 // (including queue removal) immedately rather than waiting for
846 // persistence we should replace this comment with a "return;".
847 }
848
849 delegate_->DelegateStart(this);
754 } 850 }
755 851
756 void DownloadItemImpl::OnDownloadFileReleased() { 852 void DownloadItemImpl::OnDownloadFileReleased() {
757 if (delegate_->ShouldOpenDownload(this)) 853 if (delegate_->ShouldOpenDownload(this))
758 Completed(); 854 Completed();
759 else 855 else
760 delegate_delayed_complete_ = true; 856 delegate_delayed_complete_ = true;
761 } 857 }
762 858
763 void DownloadItemImpl::OnDownloadRenamedToIntermediateName( 859 void DownloadItemImpl::OnDownloadRenamedToIntermediateName(
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
874 target_path_ = target_path; 970 target_path_ = target_path;
875 target_disposition_ = disposition; 971 target_disposition_ = disposition;
876 SetDangerType(danger_type); 972 SetDangerType(danger_type);
877 // TODO(asanka): SetDangerType() doesn't need to send a notification here. 973 // TODO(asanka): SetDangerType() doesn't need to send a notification here.
878 974
879 // We want the intermediate and target paths to refer to the same directory so 975 // We want the intermediate and target paths to refer to the same directory so
880 // that they are both on the same device and subject to same 976 // that they are both on the same device and subject to same
881 // space/permission/availability constraints. 977 // space/permission/availability constraints.
882 DCHECK(intermediate_path.DirName() == target_path.DirName()); 978 DCHECK(intermediate_path.DirName() == target_path.DirName());
883 979
980 if (!IsInProgress()) {
981 // If we've been cancelled or interrupted while the target was being
982 // determined, continue the cascade with a null name.
983 // The error doesn't matter as the cause of download stoppaged
984 // will already have been recorded.
985 OnDownloadRenamedToIntermediateName(
986 content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, FilePath());
987 return;
988 }
989
884 // Rename to intermediate name. 990 // Rename to intermediate name.
885 // TODO(asanka): Skip this rename if AllDataSaved() is true. This avoids a 991 // TODO(asanka): Skip this rename if AllDataSaved() is true. This avoids a
886 // spurious rename when we can just rename to the final 992 // spurious rename when we can just rename to the final
887 // filename. Unnecessary renames may cause bugs like 993 // filename. Unnecessary renames may cause bugs like
888 // http://crbug.com/74187. 994 // http://crbug.com/74187.
889 DownloadFileManager::RenameCompletionCallback callback = 995 DCHECK(!is_save_package_download_);
996 CHECK(download_file_.get());
997 DownloadFile::RenameCompletionCallback callback =
890 base::Bind(&DownloadItemImpl::OnDownloadRenamedToIntermediateName, 998 base::Bind(&DownloadItemImpl::OnDownloadRenamedToIntermediateName,
891 weak_ptr_factory_.GetWeakPtr()); 999 weak_ptr_factory_.GetWeakPtr());
892 BrowserThread::PostTask( 1000 BrowserThread::PostTask(
893 BrowserThread::FILE, FROM_HERE, 1001 BrowserThread::FILE, FROM_HERE,
894 base::Bind(&DownloadFileManager::RenameDownloadFile, 1002 base::Bind(&DownloadFile::Rename,
895 delegate_->GetDownloadFileManager(), GetGlobalId(), 1003 // Safe because we control download file lifetime.
1004 base::Unretained(download_file_.get()),
896 intermediate_path, false, callback)); 1005 intermediate_path, false, callback));
897 } 1006 }
898 1007
899 void DownloadItemImpl::OnContentCheckCompleted( 1008 void DownloadItemImpl::OnContentCheckCompleted(
900 content::DownloadDangerType danger_type) { 1009 content::DownloadDangerType danger_type) {
901 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1010 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
902 DCHECK(AllDataSaved()); 1011 DCHECK(AllDataSaved());
903 SetDangerType(danger_type); 1012 SetDangerType(danger_type);
904 UpdateObservers(); 1013 UpdateObservers();
905 } 1014 }
(...skipping 10 matching lines...) Expand all
916 1025
917 void DownloadItemImpl::SetDisplayName(const FilePath& name) { 1026 void DownloadItemImpl::SetDisplayName(const FilePath& name) {
918 display_name_ = name; 1027 display_name_ = name;
919 } 1028 }
920 1029
921 FilePath DownloadItemImpl::GetUserVerifiedFilePath() const { 1030 FilePath DownloadItemImpl::GetUserVerifiedFilePath() const {
922 return (safety_state_ == DownloadItem::SAFE) ? 1031 return (safety_state_ == DownloadItem::SAFE) ?
923 GetTargetFilePath() : GetFullPath(); 1032 GetTargetFilePath() : GetFullPath();
924 } 1033 }
925 1034
926 void DownloadItemImpl::OffThreadCancel() { 1035 void DownloadItemImpl::DestinationUpdate(int64 bytes_so_far,
1036 int64 bytes_per_sec,
1037 const std::string& hash_state) {
927 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1038 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
928 request_handle_->CancelRequest();
929 1039
930 BrowserThread::PostTask( 1040 if (!IsInProgress()) {
931 BrowserThread::FILE, FROM_HERE, 1041 // Ignore if we're no longer in-progress. This can happen if we race a
932 base::Bind(&DownloadFileManager::CancelDownload, 1042 // Cancel on the UI thread with an update on the FILE thread.
933 delegate_->GetDownloadFileManager(), download_id_)); 1043 //
1044 // TODO(rdsmith): Arguably we should let this go through, as this means
1045 // the download really did get further than we know before it was
1046 // cancelled. But the gain isn't very large, and the code is more
1047 // fragile if it has to support in progress updates in a non-in-progress
1048 // state. This issue should be readdressed when we revamp performance
1049 // reporting.
1050 return;
1051 }
1052 bytes_per_sec_ = bytes_per_sec;
1053 hash_state_ = hash_state;
1054 received_bytes_ = bytes_so_far;
1055
1056 // If we've received more data than we were expecting (bad server info?),
1057 // revert to 'unknown size mode'.
1058 if (received_bytes_ > total_bytes_)
1059 total_bytes_ = 0;
1060
1061 if (bound_net_log_.IsLoggingAllEvents()) {
1062 bound_net_log_.AddEvent(
1063 net::NetLog::TYPE_DOWNLOAD_ITEM_UPDATED,
1064 net::NetLog::Int64Callback("bytes_so_far", received_bytes_));
1065 }
1066
1067 UpdateObservers();
1068 }
1069
1070 void DownloadItemImpl::DestinationError(
1071 content::DownloadInterruptReason reason) {
1072 // The DestinationError and Interrupt routines are being kept separate
1073 // to allow for a future merging of the Cancel and Interrupt routines..
1074 Interrupt(reason);
1075 }
1076
1077 void DownloadItemImpl::DestinationCompleted(const std::string& final_hash) {
1078 if (!IsInProgress())
1079 return;
1080 OnAllDataSaved(final_hash);
1081 delegate_->MaybeCompleteDownload(this);
934 } 1082 }
935 1083
936 void DownloadItemImpl::Init(bool active, 1084 void DownloadItemImpl::Init(bool active,
937 download_net_logs::DownloadType download_type) { 1085 download_net_logs::DownloadType download_type) {
938 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1086 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
939 1087
940 if (active) 1088 if (active)
941 download_stats::RecordDownloadCount(download_stats::START_COUNT); 1089 download_stats::RecordDownloadCount(download_stats::START_COUNT);
942 1090
943 if (target_path_.empty()) 1091 if (target_path_.empty())
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1033 " db_handle = %" PRId64 1181 " db_handle = %" PRId64
1034 " total = %" PRId64 1182 " total = %" PRId64
1035 " received = %" PRId64 1183 " received = %" PRId64
1036 " reason = %s" 1184 " reason = %s"
1037 " paused = %c" 1185 " paused = %c"
1038 " safety = %s" 1186 " safety = %s"
1039 " last_modified = '%s'" 1187 " last_modified = '%s'"
1040 " etag = '%s'" 1188 " etag = '%s'"
1041 " url_chain = \n\t\"%s\"\n\t" 1189 " url_chain = \n\t\"%s\"\n\t"
1042 " full_path = \"%" PRFilePath "\"" 1190 " full_path = \"%" PRFilePath "\""
1043 " target_path = \"%" PRFilePath "\"", 1191 " target_path = \"%" PRFilePath "\""
1192 " has download file = %s",
1044 GetDbHandle(), 1193 GetDbHandle(),
1045 GetTotalBytes(), 1194 GetTotalBytes(),
1046 GetReceivedBytes(), 1195 GetReceivedBytes(),
1047 InterruptReasonDebugString(last_reason_).c_str(), 1196 InterruptReasonDebugString(last_reason_).c_str(),
1048 IsPaused() ? 'T' : 'F', 1197 IsPaused() ? 'T' : 'F',
1049 DebugSafetyStateString(GetSafetyState()), 1198 DebugSafetyStateString(GetSafetyState()),
1050 GetLastModifiedTime().c_str(), 1199 GetLastModifiedTime().c_str(),
1051 GetETag().c_str(), 1200 GetETag().c_str(),
1052 url_list.c_str(), 1201 url_list.c_str(),
1053 GetFullPath().value().c_str(), 1202 GetFullPath().value().c_str(),
1054 GetTargetFilePath().value().c_str()); 1203 GetTargetFilePath().value().c_str(),
1204 download_file_.get() ? "true" : "false");
1055 } else { 1205 } else {
1056 description += base::StringPrintf(" url = \"%s\"", url_list.c_str()); 1206 description += base::StringPrintf(" url = \"%s\"", url_list.c_str());
1057 } 1207 }
1058 1208
1059 description += " }"; 1209 description += " }";
1060 1210
1061 return description; 1211 return description;
1062 } 1212 }
1063 1213
1064 bool DownloadItemImpl::AllDataSaved() const { return all_data_saved_; } 1214 bool DownloadItemImpl::AllDataSaved() const { return all_data_saved_; }
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1154 void DownloadItemImpl::SetOpened(bool opened) { opened_ = opened; } 1304 void DownloadItemImpl::SetOpened(bool opened) { opened_ = opened; }
1155 bool DownloadItemImpl::GetOpened() const { return opened_; } 1305 bool DownloadItemImpl::GetOpened() const { return opened_; }
1156 const std::string& DownloadItemImpl::GetLastModifiedTime() const { 1306 const std::string& DownloadItemImpl::GetLastModifiedTime() const {
1157 return last_modified_time_; 1307 return last_modified_time_;
1158 } 1308 }
1159 const std::string& DownloadItemImpl::GetETag() const { return etag_; } 1309 const std::string& DownloadItemImpl::GetETag() const { return etag_; }
1160 content::DownloadInterruptReason DownloadItemImpl::GetLastReason() const { 1310 content::DownloadInterruptReason DownloadItemImpl::GetLastReason() const {
1161 return last_reason_; 1311 return last_reason_;
1162 } 1312 }
1163 void DownloadItemImpl::MockDownloadOpenForTesting() { open_enabled_ = false; } 1313 void DownloadItemImpl::MockDownloadOpenForTesting() { open_enabled_ = false; }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698