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

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 signed/unsigned compare issue. Created 8 years 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/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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « content/browser/download/download_manager_impl.h ('k') | content/browser/download/download_manager_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698