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 |