| 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/browser_thread.h" | 32 #include "content/public/browser/browser_thread.h" |
| 33 #include "content/public/browser/content_browser_client.h" | 33 #include "content/public/browser/content_browser_client.h" |
| 34 #include "content/public/browser/download_interrupt_reasons.h" | 34 #include "content/public/browser/download_interrupt_reasons.h" |
| 35 #include "content/public/browser/download_manager_delegate.h" | 35 #include "content/public/browser/download_manager_delegate.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 namespace content { | 48 namespace content { |
| 48 namespace { | 49 namespace { |
| 49 | 50 |
| 50 void BeginDownload(scoped_ptr<DownloadUrlParameters> params) { | 51 void BeginDownload(scoped_ptr<DownloadUrlParameters> params, |
| 52 DownloadId download_id) { |
| 51 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 53 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 52 // ResourceDispatcherHost{Base} is-not-a URLRequest::Delegate, and | 54 // ResourceDispatcherHost{Base} is-not-a URLRequest::Delegate, and |
| 53 // DownloadUrlParameters can-not include resource_dispatcher_host_impl.h, so | 55 // DownloadUrlParameters can-not include resource_dispatcher_host_impl.h, so |
| 54 // we must down cast. RDHI is the only subclass of RDH as of 2012 May 4. | 56 // we must down cast. RDHI is the only subclass of RDH as of 2012 May 4. |
| 55 scoped_ptr<net::URLRequest> request( | 57 scoped_ptr<net::URLRequest> request( |
| 56 params->resource_context()->GetRequestContext()->CreateRequest( | 58 params->resource_context()->GetRequestContext()->CreateRequest( |
| 57 params->url(), NULL)); | 59 params->url(), NULL)); |
| 58 request->set_referrer(params->referrer().url.spec()); | 60 request->set_referrer(params->referrer().url.spec()); |
| 59 webkit_glue::ConfigureURLRequestForReferrerPolicy( | 61 webkit_glue::ConfigureURLRequestForReferrerPolicy( |
| 60 request.get(), params->referrer().policy); | 62 request.get(), params->referrer().policy); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 save_info->file_stream = params->GetFileStream(); | 96 save_info->file_stream = params->GetFileStream(); |
| 95 | 97 |
| 96 params->resource_dispatcher_host()->BeginDownload( | 98 params->resource_dispatcher_host()->BeginDownload( |
| 97 request.Pass(), | 99 request.Pass(), |
| 98 params->content_initiated(), | 100 params->content_initiated(), |
| 99 params->resource_context(), | 101 params->resource_context(), |
| 100 params->render_process_host_id(), | 102 params->render_process_host_id(), |
| 101 params->render_view_host_routing_id(), | 103 params->render_view_host_routing_id(), |
| 102 params->prefer_cache(), | 104 params->prefer_cache(), |
| 103 save_info.Pass(), | 105 save_info.Pass(), |
| 106 params->last_modified(), |
| 107 params->etag(), |
| 108 download_id, |
| 104 params->callback()); | 109 params->callback()); |
| 105 } | 110 } |
| 106 | 111 |
| 107 class MapValueIteratorAdapter { | 112 class MapValueIteratorAdapter { |
| 108 public: | 113 public: |
| 109 explicit MapValueIteratorAdapter( | 114 explicit MapValueIteratorAdapter( |
| 110 base::hash_map<int64, DownloadItem*>::const_iterator iter) | 115 base::hash_map<int64, DownloadItem*>::const_iterator iter) |
| 111 : iter_(iter) { | 116 : iter_(iter) { |
| 112 } | 117 } |
| 113 ~MapValueIteratorAdapter() {} | 118 ~MapValueIteratorAdapter() {} |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 received_bytes, | 169 received_bytes, |
| 165 total_bytes, | 170 total_bytes, |
| 166 state, | 171 state, |
| 167 opened, | 172 opened, |
| 168 bound_net_log); | 173 bound_net_log); |
| 169 } | 174 } |
| 170 | 175 |
| 171 virtual DownloadItemImpl* CreateActiveItem( | 176 virtual DownloadItemImpl* CreateActiveItem( |
| 172 DownloadItemImplDelegate* delegate, | 177 DownloadItemImplDelegate* delegate, |
| 173 const DownloadCreateInfo& info, | 178 const DownloadCreateInfo& info, |
| 174 scoped_ptr<DownloadRequestHandleInterface> request_handle, | |
| 175 const net::BoundNetLog& bound_net_log) OVERRIDE { | 179 const net::BoundNetLog& bound_net_log) OVERRIDE { |
| 176 return new DownloadItemImpl(delegate, info, request_handle.Pass(), | 180 return new DownloadItemImpl(delegate, info, bound_net_log); |
| 177 bound_net_log); | |
| 178 } | 181 } |
| 179 | 182 |
| 180 virtual DownloadItemImpl* CreateSavePageItem( | 183 virtual DownloadItemImpl* CreateSavePageItem( |
| 181 DownloadItemImplDelegate* delegate, | 184 DownloadItemImplDelegate* delegate, |
| 182 const FilePath& path, | 185 const FilePath& path, |
| 183 const GURL& url, | 186 const GURL& url, |
| 184 DownloadId download_id, | 187 DownloadId download_id, |
| 185 const std::string& mime_type, | 188 const std::string& mime_type, |
| 186 const net::BoundNetLog& bound_net_log) OVERRIDE { | 189 const net::BoundNetLog& bound_net_log) OVERRIDE { |
| 187 return new DownloadItemImpl(delegate, path, url, download_id, | 190 return new DownloadItemImpl(delegate, path, url, download_id, |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 browser_context_ = browser_context; | 340 browser_context_ = browser_context; |
| 338 | 341 |
| 339 return true; | 342 return true; |
| 340 } | 343 } |
| 341 | 344 |
| 342 DownloadItem* DownloadManagerImpl::StartDownload( | 345 DownloadItem* DownloadManagerImpl::StartDownload( |
| 343 scoped_ptr<DownloadCreateInfo> info, | 346 scoped_ptr<DownloadCreateInfo> info, |
| 344 scoped_ptr<ByteStreamReader> stream) { | 347 scoped_ptr<ByteStreamReader> stream) { |
| 345 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 348 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 346 | 349 |
| 347 net::BoundNetLog bound_net_log = | |
| 348 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); | |
| 349 | |
| 350 FilePath default_download_directory; | 350 FilePath default_download_directory; |
| 351 if (delegate_) { | 351 if (delegate_) { |
| 352 FilePath website_save_directory; // Unused | 352 FilePath website_save_directory; // Unused |
| 353 bool skip_dir_check = false; // Unused | 353 bool skip_dir_check = false; // Unused |
| 354 delegate_->GetSaveDir(GetBrowserContext(), &website_save_directory, | 354 delegate_->GetSaveDir(GetBrowserContext(), &website_save_directory, |
| 355 &default_download_directory, &skip_dir_check); | 355 &default_download_directory, &skip_dir_check); |
| 356 } | 356 } |
| 357 | 357 |
| 358 // We create the DownloadItem before the DownloadFile because the | 358 // We create the DownloadItem before the DownloadFile because the |
| 359 // DownloadItem already needs to handle a state in which there is | 359 // DownloadItem already needs to handle a state in which there is |
| 360 // no associated DownloadFile (history downloads, !IN_PROGRESS downloads) | 360 // no associated DownloadFile (history downloads, !IN_PROGRESS downloads) |
| 361 DownloadItemImpl* download = | 361 DownloadItemImpl* download = CreateDownloadItem(info.get()); |
| 362 CreateDownloadItem(info.get(), bound_net_log); | 362 net::BoundNetLog bound_net_log = download->GetBoundNetLog(); |
| 363 scoped_ptr<DownloadFile> download_file( | 363 scoped_ptr<DownloadFile> download_file( |
| 364 file_factory_->CreateFile( | 364 file_factory_->CreateFile( |
| 365 info->save_info.Pass(), default_download_directory, | 365 info->save_info.Pass(), default_download_directory, |
| 366 info->url(), info->referrer_url, | 366 info->url(), info->referrer_url, |
| 367 delegate_->GenerateFileHash(), | 367 delegate_->GenerateFileHash(), |
| 368 stream.Pass(), bound_net_log, | 368 stream.Pass(), bound_net_log, |
| 369 download->DestinationObserverAsWeakPtr())); | 369 download->DestinationObserverAsWeakPtr())); |
| 370 download->Start(download_file.Pass()); | 370 scoped_ptr<DownloadRequestHandleInterface> req_handle( |
| 371 new DownloadRequestHandle(info->request_handle)); |
| 372 download->Start(download_file.Pass(), req_handle.Pass()); |
| 371 | 373 |
| 372 // Delay notification until after Start() so that download_file is bound | 374 // Delay notification until after Start() so that download_file is bound |
| 373 // to download and all the usual setters (e.g. Cancel) work. | 375 // to download and all the usual setters (e.g. Cancel) work. |
| 374 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); | 376 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); |
| 375 | 377 |
| 376 return download; | 378 return download; |
| 377 } | 379 } |
| 378 | 380 |
| 379 void DownloadManagerImpl::CheckForHistoryFilesRemoval() { | 381 void DownloadManagerImpl::CheckForHistoryFilesRemoval() { |
| 380 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 382 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 413 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 415 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 414 if (ContainsKey(downloads_, download_id)) | 416 if (ContainsKey(downloads_, download_id)) |
| 415 downloads_[download_id]->OnDownloadedFileRemoved(); | 417 downloads_[download_id]->OnDownloadedFileRemoved(); |
| 416 } | 418 } |
| 417 | 419 |
| 418 BrowserContext* DownloadManagerImpl::GetBrowserContext() const { | 420 BrowserContext* DownloadManagerImpl::GetBrowserContext() const { |
| 419 return browser_context_; | 421 return browser_context_; |
| 420 } | 422 } |
| 421 | 423 |
| 422 DownloadItemImpl* DownloadManagerImpl::CreateDownloadItem( | 424 DownloadItemImpl* DownloadManagerImpl::CreateDownloadItem( |
| 423 DownloadCreateInfo* info, const net::BoundNetLog& bound_net_log) { | 425 DownloadCreateInfo* info) { |
| 424 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 426 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 425 | 427 |
| 426 if (!info->download_id.IsValid()) | 428 if (!info->download_id.IsValid()) |
| 427 info->download_id = GetNextId(); | 429 info->download_id = GetNextId(); |
| 428 DownloadItemImpl* download = item_factory_->CreateActiveItem( | |
| 429 this, *info, | |
| 430 scoped_ptr<DownloadRequestHandleInterface>( | |
| 431 new DownloadRequestHandle(info->request_handle)).Pass(), | |
| 432 bound_net_log); | |
| 433 | 430 |
| 434 DCHECK(!ContainsKey(downloads_, download->GetId())); | 431 int32 download_id = info->download_id.local(); |
| 435 downloads_[download->GetId()] = download; | 432 DownloadItemImpl* download = NULL; |
| 433 bool resuming = ContainsKey(downloads_, download_id); |
| 434 if (resuming) { |
| 435 download = downloads_[download_id]; |
| 436 DCHECK(download != NULL); |
| 437 DCHECK(download->IsInProgress()); |
| 438 } |
| 439 |
| 440 if (download) { |
| 441 // Reuse an interrupted |DownloadItem|. |
| 442 DCHECK(download->IsInterrupted()); |
| 443 } else { |
| 444 // Create a new |DownloadItem|. |
| 445 // |bound_net_log| will be used for logging the both the download item's and |
| 446 // the download file's events. |
| 447 net::BoundNetLog bound_net_log = |
| 448 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); |
| 449 download = item_factory_->CreateActiveItem(this, *info, bound_net_log); |
| 450 |
| 451 DCHECK(!ContainsKey(downloads_, download->GetId())); |
| 452 downloads_[download->GetId()] = download; |
| 453 } |
| 454 |
| 455 DVLOG(20) << __FUNCTION__ << "()" |
| 456 << " info " << info->DebugString() |
| 457 << " download " << download->DebugString(true); |
| 458 |
| 436 DCHECK(!ContainsKey(active_downloads_, download->GetId())); | 459 DCHECK(!ContainsKey(active_downloads_, download->GetId())); |
| 437 active_downloads_[download->GetId()] = download; | 460 active_downloads_[download->GetId()] = download; |
| 438 | 461 |
| 439 return download; | 462 return download; |
| 440 } | 463 } |
| 441 | 464 |
| 442 DownloadItemImpl* DownloadManagerImpl::CreateSavePackageDownloadItem( | 465 DownloadItemImpl* DownloadManagerImpl::CreateSavePackageDownloadItem( |
| 443 const FilePath& main_file_path, | 466 const FilePath& main_file_path, |
| 444 const GURL& page_url, | 467 const GURL& page_url, |
| 445 const std::string& mime_type, | 468 const std::string& mime_type, |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 479 void DownloadManagerImpl::DownloadCompleted(DownloadItemImpl* download) { | 502 void DownloadManagerImpl::DownloadCompleted(DownloadItemImpl* download) { |
| 480 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 503 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 481 DCHECK(download); | 504 DCHECK(download); |
| 482 active_downloads_.erase(download->GetId()); | 505 active_downloads_.erase(download->GetId()); |
| 483 AssertStateConsistent(download); | 506 AssertStateConsistent(download); |
| 484 } | 507 } |
| 485 | 508 |
| 486 void DownloadManagerImpl::CancelDownload(int32 download_id) { | 509 void DownloadManagerImpl::CancelDownload(int32 download_id) { |
| 487 // A cancel at the right time could remove the download from the | 510 // A cancel at the right time could remove the download from the |
| 488 // |active_downloads_| map before we get here. | 511 // |active_downloads_| map before we get here. |
| 489 if (ContainsKey(active_downloads_, download_id)) | 512 if (!ContainsKey(active_downloads_, download_id)) |
| 490 active_downloads_[download_id]->Cancel(true); | 513 return; |
| 514 |
| 515 DownloadItem* download = active_downloads_[download_id]; |
| 516 |
| 517 VLOG(20) << __FUNCTION__ << "() download = " << download->DebugString(true); |
| 518 |
| 519 if (!download->IsInProgress()) |
| 520 return; |
| 521 |
| 522 download->Cancel(true); |
| 491 } | 523 } |
| 492 | 524 |
| 493 void DownloadManagerImpl::DownloadStopped(DownloadItemImpl* download) { | 525 void DownloadManagerImpl::DownloadStopped(DownloadItemImpl* download) { |
| 494 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 526 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 495 | 527 |
| 496 VLOG(20) << __FUNCTION__ << "()" | 528 VLOG(20) << __FUNCTION__ << "()" |
| 497 << " download = " << download->DebugString(true); | 529 << " download = " << download->DebugString(true); |
| 498 | 530 |
| 499 RemoveFromActiveList(download); | 531 RemoveFromActiveList(download); |
| 500 // This function is called from the DownloadItem, so DI state | 532 // This function is called from the DownloadItem, so DI state |
| 501 // should already have been updated. | 533 // should already have been updated. |
| 502 AssertStateConsistent(download); | 534 AssertStateConsistent(download); |
| 503 } | 535 } |
| 504 | 536 |
| 537 // Resume a download of a specific URL. We send the request to the |
| 538 // ResourceDispatcherHost, and let it send us responses like a regular |
| 539 // download. |
| 540 void DownloadManagerImpl::ResumeInterruptedDownload( |
| 541 scoped_ptr<content::DownloadUrlParameters> params, |
| 542 content::DownloadId id) { |
| 543 BrowserThread::PostTask( |
| 544 BrowserThread::IO, |
| 545 FROM_HERE, |
| 546 base::Bind(&BeginDownload, base::Passed(params.Pass()), id)); |
| 547 } |
| 548 |
| 505 void DownloadManagerImpl::RemoveFromActiveList(DownloadItemImpl* download) { | 549 void DownloadManagerImpl::RemoveFromActiveList(DownloadItemImpl* download) { |
| 506 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 550 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 507 DCHECK(download); | 551 DCHECK(download); |
| 508 active_downloads_.erase(download->GetId()); | 552 active_downloads_.erase(download->GetId()); |
| 509 } | 553 } |
| 510 | 554 |
| 511 void DownloadManagerImpl::SetDownloadItemFactoryForTesting( | 555 void DownloadManagerImpl::SetDownloadItemFactoryForTesting( |
| 512 scoped_ptr<DownloadItemFactory> item_factory) { | 556 scoped_ptr<DownloadItemFactory> item_factory) { |
| 513 item_factory_ = item_factory.Pass(); | 557 item_factory_ = item_factory.Pass(); |
| 514 } | 558 } |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 580 return num_deleted; | 624 return num_deleted; |
| 581 } | 625 } |
| 582 | 626 |
| 583 void DownloadManagerImpl::DownloadUrl( | 627 void DownloadManagerImpl::DownloadUrl( |
| 584 scoped_ptr<DownloadUrlParameters> params) { | 628 scoped_ptr<DownloadUrlParameters> params) { |
| 585 if (params->post_id() >= 0) { | 629 if (params->post_id() >= 0) { |
| 586 // Check this here so that the traceback is more useful. | 630 // Check this here so that the traceback is more useful. |
| 587 DCHECK(params->prefer_cache()); | 631 DCHECK(params->prefer_cache()); |
| 588 DCHECK(params->method() == "POST"); | 632 DCHECK(params->method() == "POST"); |
| 589 } | 633 } |
| 590 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( | 634 BrowserThread::PostTask( |
| 591 &BeginDownload, base::Passed(params.Pass()))); | 635 BrowserThread::IO, FROM_HERE, |
| 636 base::Bind( |
| 637 &BeginDownload, |
| 638 base::Passed(params.Pass()), |
| 639 DownloadId())); |
| 592 } | 640 } |
| 593 | 641 |
| 594 void DownloadManagerImpl::AddObserver(Observer* observer) { | 642 void DownloadManagerImpl::AddObserver(Observer* observer) { |
| 595 observers_.AddObserver(observer); | 643 observers_.AddObserver(observer); |
| 596 } | 644 } |
| 597 | 645 |
| 598 void DownloadManagerImpl::RemoveObserver(Observer* observer) { | 646 void DownloadManagerImpl::RemoveObserver(Observer* observer) { |
| 599 observers_.RemoveObserver(observer); | 647 observers_.RemoveObserver(observer); |
| 600 } | 648 } |
| 601 | 649 |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 709 it != downloads_.end(); ++it) { | 757 it != downloads_.end(); ++it) { |
| 710 DownloadItemImpl* item = it->second; | 758 DownloadItemImpl* item = it->second; |
| 711 if (item->IsComplete() && | 759 if (item->IsComplete() && |
| 712 !item->GetOpened()) | 760 !item->GetOpened()) |
| 713 ++num_unopened; | 761 ++num_unopened; |
| 714 } | 762 } |
| 715 RecordOpensOutstanding(num_unopened); | 763 RecordOpensOutstanding(num_unopened); |
| 716 } | 764 } |
| 717 | 765 |
| 718 } // namespace content | 766 } // namespace content |
| OLD | NEW |