OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } | |
OLD | NEW |