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

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

Issue 10831302: Download resumption - Preliminary (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Fixed content unit tests. Created 8 years, 2 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
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_manager_impl.h" 5 #include "content/browser/download/download_manager_impl.h"
6 6
7 #include <iterator> 7 #include <iterator>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
(...skipping 21 matching lines...) Expand all
32 #include "content/public/browser/content_browser_client.h" 32 #include "content/public/browser/content_browser_client.h"
33 #include "content/public/browser/download_interrupt_reasons.h" 33 #include "content/public/browser/download_interrupt_reasons.h"
34 #include "content/public/browser/download_manager_delegate.h" 34 #include "content/public/browser/download_manager_delegate.h"
35 #include "content/public/browser/download_persistent_store_info.h" 35 #include "content/public/browser/download_persistent_store_info.h"
36 #include "content/public/browser/download_url_parameters.h" 36 #include "content/public/browser/download_url_parameters.h"
37 #include "content/public/browser/notification_service.h" 37 #include "content/public/browser/notification_service.h"
38 #include "content/public/browser/notification_types.h" 38 #include "content/public/browser/notification_types.h"
39 #include "content/public/browser/render_process_host.h" 39 #include "content/public/browser/render_process_host.h"
40 #include "content/public/browser/resource_context.h" 40 #include "content/public/browser/resource_context.h"
41 #include "content/public/browser/web_contents_delegate.h" 41 #include "content/public/browser/web_contents_delegate.h"
42 #include "content/public/common/referrer.h"
42 #include "net/base/load_flags.h" 43 #include "net/base/load_flags.h"
43 #include "net/base/upload_data.h" 44 #include "net/base/upload_data.h"
44 #include "net/url_request/url_request_context.h" 45 #include "net/url_request/url_request_context.h"
45 #include "webkit/glue/webkit_glue.h" 46 #include "webkit/glue/webkit_glue.h"
46 47
47 using content::BrowserThread; 48 using content::BrowserThread;
48 using content::DownloadId; 49 using content::DownloadId;
49 using content::DownloadItem; 50 using content::DownloadItem;
50 using content::DownloadPersistentStoreInfo; 51 using content::DownloadPersistentStoreInfo;
51 using content::ResourceDispatcherHostImpl; 52 using content::ResourceDispatcherHostImpl;
(...skipping 16 matching lines...) Expand all
68 virtual ~SavePageData() {} 69 virtual ~SavePageData() {}
69 70
70 private: 71 private:
71 static const char kKey[]; 72 static const char kKey[];
72 73
73 DISALLOW_COPY_AND_ASSIGN(SavePageData); 74 DISALLOW_COPY_AND_ASSIGN(SavePageData);
74 }; 75 };
75 76
76 const char SavePageData::kKey[] = "DownloadItem SavePageData"; 77 const char SavePageData::kKey[] = "DownloadItem SavePageData";
77 78
78 void BeginDownload(content::DownloadUrlParameters* params) { 79 void BeginDownload(content::DownloadUrlParameters* params,
80 DownloadId download_id) {
79 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 81 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
80 // ResourceDispatcherHost{Base} is-not-a URLRequest::Delegate, and 82 // ResourceDispatcherHost{Base} is-not-a URLRequest::Delegate, and
81 // DownloadUrlParameters can-not include resource_dispatcher_host_impl.h, so 83 // DownloadUrlParameters can-not include resource_dispatcher_host_impl.h, so
82 // we must down cast. RDHI is the only subclass of RDH as of 2012 May 4. 84 // we must down cast. RDHI is the only subclass of RDH as of 2012 May 4.
83 scoped_ptr<net::URLRequest> request( 85 scoped_ptr<net::URLRequest> request(
84 params->resource_context()->GetRequestContext()->CreateRequest( 86 params->resource_context()->GetRequestContext()->CreateRequest(
85 params->url(), NULL)); 87 params->url(), NULL));
86 request->set_referrer(params->referrer().url.spec()); 88 request->set_referrer(params->referrer().url.spec());
87 webkit_glue::ConfigureURLRequestForReferrerPolicy( 89 webkit_glue::ConfigureURLRequestForReferrerPolicy(
88 request.get(), params->referrer().policy); 90 request.get(), params->referrer().policy);
(...skipping 21 matching lines...) Expand all
110 iter->first, iter->second, false/*overwrite*/); 112 iter->first, iter->second, false/*overwrite*/);
111 } 113 }
112 params->resource_dispatcher_host()->BeginDownload( 114 params->resource_dispatcher_host()->BeginDownload(
113 request.Pass(), 115 request.Pass(),
114 params->content_initiated(), 116 params->content_initiated(),
115 params->resource_context(), 117 params->resource_context(),
116 params->render_process_host_id(), 118 params->render_process_host_id(),
117 params->render_view_host_routing_id(), 119 params->render_view_host_routing_id(),
118 params->prefer_cache(), 120 params->prefer_cache(),
119 params->save_info(), 121 params->save_info(),
122 params->last_modified(),
123 params->etag(),
124 download_id,
120 params->callback()); 125 params->callback());
121 } 126 }
122 127
123 class MapValueIteratorAdapter { 128 class MapValueIteratorAdapter {
124 public: 129 public:
125 explicit MapValueIteratorAdapter( 130 explicit MapValueIteratorAdapter(
126 base::hash_map<int64, DownloadItem*>::const_iterator iter) 131 base::hash_map<int64, DownloadItem*>::const_iterator iter)
127 : iter_(iter) { 132 : iter_(iter) {
128 } 133 }
129 ~MapValueIteratorAdapter() {} 134 ~MapValueIteratorAdapter() {}
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 DownloadItemImplDelegate* delegate, 175 DownloadItemImplDelegate* delegate,
171 content::DownloadId download_id, 176 content::DownloadId download_id,
172 const content::DownloadPersistentStoreInfo& info, 177 const content::DownloadPersistentStoreInfo& info,
173 const net::BoundNetLog& bound_net_log) OVERRIDE { 178 const net::BoundNetLog& bound_net_log) OVERRIDE {
174 return new DownloadItemImpl(delegate, download_id, info, bound_net_log); 179 return new DownloadItemImpl(delegate, download_id, info, bound_net_log);
175 } 180 }
176 181
177 virtual DownloadItemImpl* CreateActiveItem( 182 virtual DownloadItemImpl* CreateActiveItem(
178 DownloadItemImplDelegate* delegate, 183 DownloadItemImplDelegate* delegate,
179 const DownloadCreateInfo& info, 184 const DownloadCreateInfo& info,
180 scoped_ptr<DownloadRequestHandleInterface> request_handle,
181 const net::BoundNetLog& bound_net_log) OVERRIDE { 185 const net::BoundNetLog& bound_net_log) OVERRIDE {
182 return new DownloadItemImpl(delegate, info, request_handle.Pass(), 186 return new DownloadItemImpl(delegate, info, bound_net_log);
183 bound_net_log);
184 } 187 }
185 188
186 virtual DownloadItemImpl* CreateSavePageItem( 189 virtual DownloadItemImpl* CreateSavePageItem(
187 DownloadItemImplDelegate* delegate, 190 DownloadItemImplDelegate* delegate,
188 const FilePath& path, 191 const FilePath& path,
189 const GURL& url, 192 const GURL& url,
190 content::DownloadId download_id, 193 content::DownloadId download_id,
191 const std::string& mime_type, 194 const std::string& mime_type,
192 const net::BoundNetLog& bound_net_log) OVERRIDE { 195 const net::BoundNetLog& bound_net_log) OVERRIDE {
193 return new DownloadItemImpl(delegate, path, url, download_id, 196 return new DownloadItemImpl(delegate, path, url, download_id,
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 349
347 return true; 350 return true;
348 } 351 }
349 352
350 // We have received a message from DownloadFileManager about a new download. 353 // We have received a message from DownloadFileManager about a new download.
351 DownloadItem* DownloadManagerImpl::StartDownload( 354 DownloadItem* DownloadManagerImpl::StartDownload(
352 scoped_ptr<DownloadCreateInfo> info, 355 scoped_ptr<DownloadCreateInfo> info,
353 scoped_ptr<content::ByteStreamReader> stream) { 356 scoped_ptr<content::ByteStreamReader> stream) {
354 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 357 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
355 358
359 bool resuming =
360 (downloads_.find(info->download_id.local()) != downloads_.end());
361
356 // |bound_net_log| will be used for logging both the download item's and 362 // |bound_net_log| will be used for logging both the download item's and
357 // the download file's events. 363 // the download file's events.
358 net::BoundNetLog bound_net_log = CreateDownloadItem(info.get()); 364 net::BoundNetLog bound_net_log = CreateDownloadItem(info.get());
359 365
360 // If info->download_id was unknown on entry to this function, it was 366 // If info->download_id was unknown on entry to this function, it was
361 // assigned in CreateDownloadItem. 367 // assigned in CreateDownloadItem.
362 DownloadId download_id = info->download_id; 368 DownloadId download_id = info->download_id;
363 369
364 if (delegate_) { 370 if (delegate_) {
365 FilePath website_save_directory; // Unused 371 FilePath website_save_directory; // Unused
366 bool skip_dir_check = false; // Unused 372 bool skip_dir_check = false; // Unused
367 delegate_->GetSaveDir(GetBrowserContext(), &website_save_directory, 373 delegate_->GetSaveDir(GetBrowserContext(), &website_save_directory,
368 &info->default_download_directory, &skip_dir_check); 374 &info->default_download_directory, &skip_dir_check);
369 } 375 }
370 376
371 DownloadFileManager::CreateDownloadFileCallback callback( 377 DownloadFileManager::CreateDownloadFileCallback callback(
372 base::Bind(&DownloadManagerImpl::OnDownloadFileCreated, 378 base::Bind(resuming ?
379 &DownloadManagerImpl::ContinueStartingDownload :
380 &DownloadManagerImpl::OnDownloadFileCreated,
373 this, download_id.local())); 381 this, download_id.local()));
374 382
375 BrowserThread::PostTask( 383 BrowserThread::PostTask(
376 BrowserThread::FILE, FROM_HERE, 384 BrowserThread::FILE, FROM_HERE,
377 base::Bind(&DownloadFileManager::CreateDownloadFile, 385 base::Bind(&DownloadFileManager::CreateDownloadFile,
378 file_manager_, base::Passed(info.Pass()), 386 file_manager_, base::Passed(info.Pass()),
379 base::Passed(stream.Pass()), make_scoped_refptr(this), 387 base::Passed(stream.Pass()), make_scoped_refptr(this),
380 (delegate_ && delegate_->GenerateFileHash()), bound_net_log, 388 (delegate_ && delegate_->GenerateFileHash()), bound_net_log,
381 callback)); 389 callback));
382 390
383 return GetDownload(download_id.local()); 391 return GetDownload(download_id.local());
384 } 392 }
385 393
394 // We have received a message from DownloadFileManager about a new download.
395 void DownloadManagerImpl::ContinueStartingDownload(
396 int32 download_id, content::DownloadInterruptReason reason) {
397 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
398
399 if (reason != content::DOWNLOAD_INTERRUPT_REASON_NONE) {
400 OnDownloadInterrupted(download_id, reason);
401 // TODO(rdsmith): It makes no sense to continue along the
402 // regular download path after we've gotten an error. But it's
403 // the way the code has historically worked, and this allows us
404 // to get the download persisted and observers of the download manager
405 // notified, so tests work. When we execute all side effects of cancel
406 // (including queue removal) immedately rather than waiting for
407 // persistence we should replace this comment with a "return;".
408 }
409
410 DownloadItem* download = GetActiveDownload(download_id);
411 if (!download)
412 return;
413
414 MaybeCompleteDownload(download_id);
415 }
416
386 void DownloadManagerImpl::OnDownloadFileCreated( 417 void DownloadManagerImpl::OnDownloadFileCreated(
387 int32 download_id, content::DownloadInterruptReason reason) { 418 int32 download_id, content::DownloadInterruptReason reason) {
419 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
388 if (reason != content::DOWNLOAD_INTERRUPT_REASON_NONE) { 420 if (reason != content::DOWNLOAD_INTERRUPT_REASON_NONE) {
389 OnDownloadInterrupted(download_id, reason); 421 OnDownloadInterrupted(download_id, reason);
390 // TODO(rdsmith): It makes no sense to continue along the 422 // TODO(rdsmith): It makes no sense to continue along the
391 // regular download path after we've gotten an error. But it's 423 // regular download path after we've gotten an error. But it's
392 // the way the code has historically worked, and this allows us 424 // the way the code has historically worked, and this allows us
393 // to get the download persisted and observers of the download manager 425 // to get the download persisted and observers of the download manager
394 // notified, so tests work. When we execute all side effects of cancel 426 // notified, so tests work. When we execute all side effects of cancel
395 // (including queue removal) immedately rather than waiting for 427 // (including queue removal) immedately rather than waiting for
396 // persistence we should replace this comment with a "return;". 428 // persistence we should replace this comment with a "return;".
397 } 429 }
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
472 } 504 }
473 505
474 content::BrowserContext* DownloadManagerImpl::GetBrowserContext() const { 506 content::BrowserContext* DownloadManagerImpl::GetBrowserContext() const {
475 return browser_context_; 507 return browser_context_;
476 } 508 }
477 509
478 net::BoundNetLog DownloadManagerImpl::CreateDownloadItem( 510 net::BoundNetLog DownloadManagerImpl::CreateDownloadItem(
479 DownloadCreateInfo* info) { 511 DownloadCreateInfo* info) {
480 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 512 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
481 513
482 net::BoundNetLog bound_net_log = 514 // |bound_net_log| will be used for logging the both the download item's and
483 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); 515 // the download file's events.
516 net::BoundNetLog bound_net_log;
517
484 if (!info->download_id.IsValid()) 518 if (!info->download_id.IsValid())
485 info->download_id = GetNextId(); 519 info->download_id = GetNextId();
486 DownloadItemImpl* download = factory_->CreateActiveItem(
487 this, *info,
488 scoped_ptr<DownloadRequestHandleInterface>(
489 new DownloadRequestHandle(info->request_handle)).Pass(),
490 bound_net_log);
491 520
492 DCHECK(!ContainsKey(downloads_, download->GetId())); 521 int32 download_id = info->download_id.local();
493 downloads_[download->GetId()] = download; 522 DownloadItemImpl* download = NULL;
523 scoped_ptr<DownloadRequestHandleInterface> req_handle(
524 new DownloadRequestHandle(info->request_handle));
525 bool resuming = (downloads_.find(download_id) != downloads_.end());
526 if (resuming) {
527 download = downloads_[download_id];
528 DCHECK(download != NULL);
529 }
530
531 if (download) {
532 // Reuse an interrupted |DownloadItem|.
533 DCHECK(download->IsInterrupted());
534 bound_net_log = download->GetBoundNetLog(); // Connect to its net log.
535 download->Resume(req_handle.Pass());
536 } else {
537 // Create a new |DownloadItem|.
538 bound_net_log =
539 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD);
540 download = factory_->CreateActiveItem(this, *info, bound_net_log);
541
542 download->SetRequest(req_handle.Pass());
543
544 DCHECK(!ContainsKey(downloads_, download->GetId()));
545 downloads_[download->GetId()] = download;
546 }
547
548 DVLOG(20) << __FUNCTION__ << "()"
549 << " info " << info->DebugString()
550 << " download " << download->DebugString(true);
551
494 DCHECK(!ContainsKey(active_downloads_, download->GetId())); 552 DCHECK(!ContainsKey(active_downloads_, download->GetId()));
495 active_downloads_[download->GetId()] = download; 553 active_downloads_[download->GetId()] = download;
496 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); 554 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download));
497 555
498 return bound_net_log; 556 return bound_net_log;
499 } 557 }
500 558
501 DownloadItemImpl* DownloadManagerImpl::CreateSavePackageDownloadItem( 559 DownloadItemImpl* DownloadManagerImpl::CreateSavePackageDownloadItem(
502 const FilePath& main_file_path, 560 const FilePath& main_file_path,
503 const GURL& page_url, 561 const GURL& page_url,
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 << " size = " << size; 612 << " size = " << size;
555 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 613 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
556 614
557 // If it's not in active_downloads_, that means it was cancelled; just 615 // If it's not in active_downloads_, that means it was cancelled; just
558 // ignore the notification. 616 // ignore the notification.
559 if (active_downloads_.count(download_id) == 0) 617 if (active_downloads_.count(download_id) == 0)
560 return; 618 return;
561 619
562 DownloadItemImpl* download = active_downloads_[download_id]; 620 DownloadItemImpl* download = active_downloads_[download_id];
563 download->OnAllDataSaved(size, hash); 621 download->OnAllDataSaved(size, hash);
564 MaybeCompleteDownload(download); 622 MaybeCompleteDownload(download_id);
565 } 623 }
566 624
567 void DownloadManagerImpl::AssertStateConsistent( 625 void DownloadManagerImpl::AssertStateConsistent(
568 DownloadItemImpl* download) const { 626 DownloadItemImpl* download) const {
569 CHECK(ContainsKey(downloads_, download->GetId())); 627 CHECK(ContainsKey(downloads_, download->GetId()));
570 628
571 int64 state = download->GetState(); 629 int64 state = download->GetState();
572 base::debug::Alias(&state); 630 base::debug::Alias(&state);
573 if (ContainsKey(active_downloads_, download->GetId())) { 631 if (ContainsKey(active_downloads_, download->GetId())) {
574 if (download->IsPersisted()) 632 if (download->IsPersisted())
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 // When SavePackage downloads MHTML to GData (see 667 // When SavePackage downloads MHTML to GData (see
610 // SavePackageFilePickerChromeOS), GData calls MaybeCompleteDownload() like it 668 // SavePackageFilePickerChromeOS), GData calls MaybeCompleteDownload() like it
611 // does for non-SavePackage downloads, but SavePackage downloads never satisfy 669 // does for non-SavePackage downloads, but SavePackage downloads never satisfy
612 // IsDownloadReadyForCompletion(). GDataDownloadObserver manually calls 670 // IsDownloadReadyForCompletion(). GDataDownloadObserver manually calls
613 // DownloadItem::UpdateObservers() when the upload completes so that SavePackage 671 // DownloadItem::UpdateObservers() when the upload completes so that SavePackage
614 // notices that the upload has completed and runs its normal Finish() pathway. 672 // notices that the upload has completed and runs its normal Finish() pathway.
615 // MaybeCompleteDownload() is never the mechanism by which SavePackage completes 673 // MaybeCompleteDownload() is never the mechanism by which SavePackage completes
616 // downloads. SavePackage always uses its own Finish() to mark downloads 674 // downloads. SavePackage always uses its own Finish() to mark downloads
617 // complete. 675 // complete.
618 676
619 void DownloadManagerImpl::MaybeCompleteDownload( 677 void DownloadManagerImpl::MaybeCompleteDownload(int32 download_id) {
620 DownloadItemImpl* download) {
621 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 678 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
679
680 // This can be called from |DownloadItemImpl::OnDownloadedFileRemoved()|,
681 // without the download being active.
682 DCHECK(ContainsKey(downloads_, download_id));
683 if (!ContainsKey(active_downloads_, download_id))
684 return;
685 DownloadItemImpl* download = active_downloads_[download_id];
686
622 VLOG(20) << __FUNCTION__ << "()" << " download = " 687 VLOG(20) << __FUNCTION__ << "()" << " download = "
623 << download->DebugString(false); 688 << download->DebugString(true);
624 689
625 if (!IsDownloadReadyForCompletion(download)) 690 if (!IsDownloadReadyForCompletion(download))
626 return; 691 return;
627 692
628 // TODO(rdsmith): DCHECK that we only pass through this point 693 // TODO(rdsmith): DCHECK that we only pass through this point
629 // once per download. The natural way to do this is by a state 694 // once per download. The natural way to do this is by a state
630 // transition on the DownloadItem. 695 // transition on the DownloadItem.
631 696
632 // Confirm we're in the proper set of states to be here; 697 // Confirm we're in the proper set of states to be here;
633 // have all data, have a history handle, (validated or safe). 698 // have all data, have a history handle, (validated or safe).
(...skipping 15 matching lines...) Expand all
649 VLOG(20) << __FUNCTION__ << "()" << " executing: download = " 714 VLOG(20) << __FUNCTION__ << "()" << " executing: download = "
650 << download->DebugString(false); 715 << download->DebugString(false);
651 716
652 if (delegate_) 717 if (delegate_)
653 delegate_->UpdateItemInPersistentStore(download); 718 delegate_->UpdateItemInPersistentStore(download);
654 download->OnDownloadCompleting(); 719 download->OnDownloadCompleting();
655 } 720 }
656 721
657 void DownloadManagerImpl::MaybeCompleteDownloadById(int download_id) { 722 void DownloadManagerImpl::MaybeCompleteDownloadById(int download_id) {
658 if (ContainsKey(active_downloads_, download_id)) 723 if (ContainsKey(active_downloads_, download_id))
659 MaybeCompleteDownload(active_downloads_[download_id]); 724 MaybeCompleteDownload(download_id);
660 } 725 }
661 726
662 void DownloadManagerImpl::DownloadCompleted(DownloadItemImpl* download) { 727 void DownloadManagerImpl::DownloadCompleted(DownloadItemImpl* download) {
663 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 728 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
664 DCHECK(download); 729 DCHECK(download);
665 if (delegate_) 730 if (delegate_)
666 delegate_->UpdateItemInPersistentStore(download); 731 delegate_->UpdateItemInPersistentStore(download);
667 active_downloads_.erase(download->GetId()); 732 active_downloads_.erase(download->GetId());
668 AssertStateConsistent(download); 733 AssertStateConsistent(download);
669 } 734 }
670 735
671 void DownloadManagerImpl::CancelDownload(int32 download_id) { 736 void DownloadManagerImpl::CancelDownload(int32 download_id) {
737 DownloadItem* download = GetActiveDownload(download_id);
672 // A cancel at the right time could remove the download from the 738 // A cancel at the right time could remove the download from the
673 // |active_downloads_| map before we get here. 739 // |active_downloads_| map before we get here.
674 if (ContainsKey(active_downloads_, download_id)) 740 if (!download)
675 active_downloads_[download_id]->Cancel(true); 741 return;
742
743 download->Cancel(true);
676 } 744 }
677 745
678 void DownloadManagerImpl::DownloadStopped(DownloadItemImpl* download) { 746 void DownloadManagerImpl::DownloadStopped(DownloadItemImpl* download) {
679 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 747 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
680 748
681 VLOG(20) << __FUNCTION__ << "()" 749 VLOG(20) << __FUNCTION__ << "()"
682 << " download = " << download->DebugString(true); 750 << " download = " << download->DebugString(true);
683 751
684 RemoveFromActiveList(download); 752 RemoveFromActiveList(download);
685 // This function is called from the DownloadItem, so DI state 753 // This function is called from the DownloadItem, so DI state
686 // should already have been updated. 754 // should already have been updated.
687 AssertStateConsistent(download); 755 AssertStateConsistent(download);
688 756
689 DCHECK(file_manager_); 757 DCHECK(file_manager_);
690 download->OffThreadCancel(); 758
759 if (download->IsInterrupted())
760 download->OffThreadInterrupt();
761 else
762 download->OffThreadCancel();
691 } 763 }
692 764
693 void DownloadManagerImpl::OnDownloadInterrupted( 765 void DownloadManagerImpl::OnDownloadInterrupted(
694 int32 download_id, 766 int32 download_id,
695 content::DownloadInterruptReason reason) { 767 content::DownloadInterruptReason reason) {
696 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 768 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
697 769
698 if (!ContainsKey(active_downloads_, download_id)) 770 if (!ContainsKey(active_downloads_, download_id))
699 return; 771 return;
772
773 VLOG(20) << __FUNCTION__ << "()"
774 << " reason " << InterruptReasonDebugString(reason)
775 << " download = "
776 << active_downloads_[download_id]->DebugString(true);
777
700 active_downloads_[download_id]->Interrupt(reason); 778 active_downloads_[download_id]->Interrupt(reason);
701 } 779 }
702 780
781 // Resume a download of a specific URL. We send the request to the
782 // ResourceDispatcherHost, and let it send us responses like a regular
783 // download.
784 void DownloadManagerImpl::RestartInterruptedDownload(
785 DownloadItemImpl* download,
786 const content::DownloadUrlParameters::OnStartedCallback& callback) {
Randy Smith (Not in Mondays) 2012/10/15 00:36:08 If we've already got a download item, let's not us
787 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
788 // Handle the case of clicking 'Resume' in the download shelf.
789 DCHECK(download);
790 DCHECK(download->IsInterrupted());
791
792 DVLOG(20) << __FUNCTION__ << "()"
793 << " download = " << download->DebugString(true);
794
795 // Restart the download.
796 WebContents* contents = GetWebContents(download);
797 if (!contents) {
798 if (!callback.is_null())
799 callback.Run(download, net::ERR_ACCESS_DENIED);
800 return;
801 }
802
803 content::DownloadSaveInfo save_info;
804 save_info.file_path = download->GetFullPath();
805 save_info.offset = download->GetReceivedBytes();
806 save_info.hash_state = download->GetHashState();
807
808 content::DownloadUrlParameters* download_params =
809 new content::DownloadUrlParameters(
810 download->GetOriginalUrl(),
811 contents->GetRenderProcessHost()->GetID(),
812 contents->GetRenderViewHost()->GetRoutingID(),
813 contents->GetBrowserContext()->GetResourceContext(),
814 save_info);
815
816 content::Referrer referrer(download->GetReferrerUrl(),
817 WebKit::WebReferrerPolicyDefault);
818 download_params->set_referrer(referrer);
819 download_params->set_last_modified(download->GetLastModifiedTime());
820 download_params->set_etag(download->GetETag());
821 download_params->set_callback(callback);
822
823 BrowserThread::PostTask(
824 BrowserThread::IO,
825 FROM_HERE,
826 base::Bind(
827 &BeginDownload,
828 base::Owned(download_params),
829 download->GetGlobalId()));
830 }
831
832 DownloadItem* DownloadManagerImpl::GetActiveDownload(int32 download_id) {
833 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
834 DownloadMap::iterator it = active_downloads_.find(download_id);
835 if (it == active_downloads_.end())
836 return NULL;
837
838 DownloadItem* download = it->second;
839
840 DCHECK(download);
841 DCHECK_EQ(download_id, download->GetId());
842
843 return download;
844 }
845
703 void DownloadManagerImpl::RemoveFromActiveList(DownloadItemImpl* download) { 846 void DownloadManagerImpl::RemoveFromActiveList(DownloadItemImpl* download) {
704 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 847 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
705 DCHECK(download); 848 DCHECK(download);
706 849
707 // Clean up will happen when the history system create callback runs if we 850 // Clean up will happen when the history system create callback runs if we
708 // don't have a valid db_handle yet. 851 // don't have a valid db_handle yet.
709 if (download->IsPersisted()) { 852 if (download->IsPersisted()) {
710 active_downloads_.erase(download->GetId()); 853 active_downloads_.erase(download->GetId());
711 if (delegate_) 854 if (delegate_)
712 delegate_->UpdateItemInPersistentStore(download); 855 delegate_->UpdateItemInPersistentStore(download);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
784 return num_deleted; 927 return num_deleted;
785 } 928 }
786 929
787 void DownloadManagerImpl::DownloadUrl( 930 void DownloadManagerImpl::DownloadUrl(
788 scoped_ptr<content::DownloadUrlParameters> params) { 931 scoped_ptr<content::DownloadUrlParameters> params) {
789 if (params->post_id() >= 0) { 932 if (params->post_id() >= 0) {
790 // Check this here so that the traceback is more useful. 933 // Check this here so that the traceback is more useful.
791 DCHECK(params->prefer_cache()); 934 DCHECK(params->prefer_cache());
792 DCHECK(params->method() == "POST"); 935 DCHECK(params->method() == "POST");
793 } 936 }
794 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( 937 BrowserThread::PostTask(
795 &BeginDownload, base::Owned(params.release()))); 938 BrowserThread::IO, FROM_HERE,
939 base::Bind(
940 &BeginDownload,
941 base::Owned(params.release()),
942 DownloadId()));
796 } 943 }
797 944
798 void DownloadManagerImpl::AddObserver(Observer* observer) { 945 void DownloadManagerImpl::AddObserver(Observer* observer) {
799 observers_.AddObserver(observer); 946 observers_.AddObserver(observer);
800 // TODO: It is the responsibility of the observers to query the 947 // TODO: It is the responsibility of the observers to query the
801 // DownloadManager. Remove the following call from here and update all 948 // DownloadManager. Remove the following call from here and update all
802 // observers. 949 // observers.
803 observer->ModelChanged(this); 950 observer->ModelChanged(this);
804 } 951 }
805 952
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
882 << " download = " << item->DebugString(true); 1029 << " download = " << item->DebugString(true);
883 1030
884 // If the download is still in progress, try to complete it. 1031 // If the download is still in progress, try to complete it.
885 // 1032 //
886 // Otherwise, download has been cancelled or interrupted before we've 1033 // Otherwise, download has been cancelled or interrupted before we've
887 // received the DB handle. We post one final message to the history 1034 // received the DB handle. We post one final message to the history
888 // service so that it can be properly in sync with the DownloadItem's 1035 // service so that it can be properly in sync with the DownloadItem's
889 // completion status, and also inform any observers so that they get 1036 // completion status, and also inform any observers so that they get
890 // more than just the start notification. 1037 // more than just the start notification.
891 if (item->IsInProgress()) { 1038 if (item->IsInProgress()) {
892 MaybeCompleteDownload(item); 1039 MaybeCompleteDownload(item->GetId());
893 } else { 1040 } else {
894 DCHECK(item->IsCancelled()); 1041 DCHECK(item->IsCancelled() || item->IsInterrupted())
1042 << " download = " << item->DebugString(true);
895 active_downloads_.erase(item->GetId()); 1043 active_downloads_.erase(item->GetId());
896 if (delegate_) 1044 if (delegate_)
897 delegate_->UpdateItemInPersistentStore(item); 1045 delegate_->UpdateItemInPersistentStore(item);
898 item->UpdateObservers(); 1046 item->UpdateObservers();
899 } 1047 }
900 } 1048 }
901 1049
902 void DownloadManagerImpl::ShowDownloadInBrowser(DownloadItemImpl* download) { 1050 void DownloadManagerImpl::ShowDownloadInBrowser(DownloadItemImpl* download) {
903 // The 'contents' may no longer exist if the user closed the contents before 1051 // The 'contents' may no longer exist if the user closed the contents before
904 // we get this start completion event. 1052 // we get this start completion event.
905 WebContents* content = download->GetWebContents(); 1053 WebContents* content = GetWebContents(download);
906
907 // If the contents no longer exists, we ask the embedder to suggest another
908 // contents.
909 if (!content && delegate_)
910 content = delegate_->GetAlternativeWebContentsToNotifyForDownload();
911 1054
912 if (content && content->GetDelegate()) 1055 if (content && content->GetDelegate())
913 content->GetDelegate()->OnStartDownload(content, download); 1056 content->GetDelegate()->OnStartDownload(content, download);
914 } 1057 }
915 1058
916 int DownloadManagerImpl::InProgressCount() const { 1059 int DownloadManagerImpl::InProgressCount() const {
917 // Don't use active_downloads_.count() because Cancel() leaves items in 1060 // Don't use active_downloads_.count() because Cancel() leaves items in
918 // active_downloads_ if they haven't made it into the persistent store yet. 1061 // active_downloads_ if they haven't made it into the persistent store yet.
919 // Need to actually look at each item's state. 1062 // Need to actually look at each item's state.
920 int count = 0; 1063 int count = 0;
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1039 void DownloadManagerImpl::DownloadRenamedToFinalName( 1182 void DownloadManagerImpl::DownloadRenamedToFinalName(
1040 DownloadItemImpl* download) { 1183 DownloadItemImpl* download) {
1041 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1184 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1042 // If the rename failed, we receive an OnDownloadInterrupted() call before we 1185 // If the rename failed, we receive an OnDownloadInterrupted() call before we
1043 // receive the DownloadRenamedToFinalName() call. 1186 // receive the DownloadRenamedToFinalName() call.
1044 if (delegate_) { 1187 if (delegate_) {
1045 delegate_->UpdatePathForItemInPersistentStore( 1188 delegate_->UpdatePathForItemInPersistentStore(
1046 download, download->GetFullPath()); 1189 download, download->GetFullPath());
1047 } 1190 }
1048 } 1191 }
1192
1193 WebContents* DownloadManagerImpl::GetWebContents(const DownloadItem* download) {
1194 WebContents* web_contents = download->GetWebContents();
1195 // If the original download_id was created from the history DB, its
1196 // |DownloadRequestHandle| will not be valid, and we won't get a proper
1197 // |WebContents| pointer from it.
1198 if (!web_contents)
1199 web_contents = delegate_->GetAlternativeWebContentsToNotifyForDownload();
1200
1201 return web_contents;
1202 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698