Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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.h" | 5 #include "content/browser/download/download_manager.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" |
| 11 #include "base/file_util.h" | 11 #include "base/file_util.h" |
| 12 #include "base/i18n/case_conversion.h" | 12 #include "base/i18n/case_conversion.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/stl_util.h" | 14 #include "base/stl_util.h" |
| 15 #include "base/stringprintf.h" | 15 #include "base/stringprintf.h" |
| 16 #include "base/synchronization/lock.h" | 16 #include "base/synchronization/lock.h" |
| 17 #include "base/sys_string_conversions.h" | 17 #include "base/sys_string_conversions.h" |
| 18 #include "base/task.h" | 18 #include "base/tuple.h" |
| 19 #include "build/build_config.h" | 19 #include "build/build_config.h" |
| 20 #include "content/browser/browser_context.h" | 20 #include "content/browser/browser_context.h" |
| 21 #include "content/browser/browser_thread.h" | 21 #include "content/browser/browser_thread.h" |
| 22 #include "content/browser/download/download_create_info.h" | 22 #include "content/browser/download/download_create_info.h" |
| 23 #include "content/browser/download/download_file_manager.h" | 23 #include "content/browser/download/download_file_manager.h" |
| 24 #include "content/browser/download/download_item.h" | 24 #include "content/browser/download/download_item.h" |
| 25 #include "content/browser/download/download_persistent_store_info.h" | 25 #include "content/browser/download/download_persistent_store_info.h" |
| 26 #include "content/browser/download/download_stats.h" | 26 #include "content/browser/download/download_stats.h" |
| 27 #include "content/browser/download/download_status_updater.h" | 27 #include "content/browser/download/download_status_updater.h" |
| 28 #include "content/browser/download/interrupt_reasons.h" | 28 #include "content/browser/download/interrupt_reasons.h" |
| 29 #include "content/browser/renderer_host/render_process_host.h" | 29 #include "content/browser/renderer_host/render_process_host.h" |
| 30 #include "content/browser/renderer_host/render_view_host.h" | 30 #include "content/browser/renderer_host/render_view_host.h" |
| 31 #include "content/browser/renderer_host/resource_dispatcher_host.h" | 31 #include "content/browser/renderer_host/resource_dispatcher_host.h" |
| 32 #include "content/browser/tab_contents/tab_contents.h" | 32 #include "content/browser/tab_contents/tab_contents.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_manager_delegate.h" | 34 #include "content/public/browser/download_manager_delegate.h" |
| 35 #include "content/public/browser/notification_service.h" | 35 #include "content/public/browser/notification_service.h" |
| 36 #include "content/public/browser/notification_types.h" | 36 #include "content/public/browser/notification_types.h" |
| 37 | 37 |
| 38 namespace { | 38 namespace { |
| 39 | 39 |
| 40 void BeginDownload( | 40 typedef Tuple7<GURL, // url |
| 41 const GURL& url, | 41 GURL, // referrer |
| 42 const GURL& referrer, | 42 DownloadSaveInfo, |
| 43 const DownloadSaveInfo& save_info, | 43 ResourceDispatcherHost*, |
| 44 ResourceDispatcherHost* resource_dispatcher_host, | 44 int, // render_process_id |
| 45 int render_process_id, | 45 int, // render_view_id |
| 46 int render_view_id, | 46 const content::ResourceContext*> BeginDownloadParams; |
|
Randy Smith (Not in Mondays)
2011/10/28 17:37:53
This is very sledgehammery, and the fact that we'r
achuithb
2011/10/28 19:51:05
Done.
| |
| 47 const content::ResourceContext* context) { | 47 |
| 48 net::URLRequest* request = new net::URLRequest(url, resource_dispatcher_host); | 48 void BeginDownload(const BeginDownloadParams& params) { |
| 49 request->set_referrer(referrer.spec()); | 49 net::URLRequest* request = new net::URLRequest(params.a, params.d); |
| 50 resource_dispatcher_host->BeginDownload( | 50 request->set_referrer(params.b.spec()); |
| 51 request, | 51 params.d->BeginDownload(request, params.c, true, |
| 52 save_info, | |
| 53 true, | |
| 54 DownloadResourceHandler::OnStartedCallback(), | 52 DownloadResourceHandler::OnStartedCallback(), |
| 55 render_process_id, | 53 params.e, params.f, *params.g); |
| 56 render_view_id, | |
| 57 *context); | |
| 58 } | 54 } |
| 59 | 55 |
| 60 } // namespace | 56 } // namespace |
| 61 | 57 |
| 62 DownloadManager::DownloadManager(content::DownloadManagerDelegate* delegate, | 58 DownloadManager::DownloadManager(content::DownloadManagerDelegate* delegate, |
| 63 DownloadStatusUpdater* status_updater) | 59 DownloadStatusUpdater* status_updater) |
| 64 : shutdown_needed_(false), | 60 : shutdown_needed_(false), |
| 65 browser_context_(NULL), | 61 browser_context_(NULL), |
| 66 next_id_(0), | 62 next_id_(0), |
| 67 file_manager_(NULL), | 63 file_manager_(NULL), |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 87 << " shutdown_needed_ = " << shutdown_needed_; | 83 << " shutdown_needed_ = " << shutdown_needed_; |
| 88 if (!shutdown_needed_) | 84 if (!shutdown_needed_) |
| 89 return; | 85 return; |
| 90 shutdown_needed_ = false; | 86 shutdown_needed_ = false; |
| 91 | 87 |
| 92 FOR_EACH_OBSERVER(Observer, observers_, ManagerGoingDown()); | 88 FOR_EACH_OBSERVER(Observer, observers_, ManagerGoingDown()); |
| 93 // TODO(benjhayden): Consider clearing observers_. | 89 // TODO(benjhayden): Consider clearing observers_. |
| 94 | 90 |
| 95 if (file_manager_) { | 91 if (file_manager_) { |
| 96 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 92 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| 97 NewRunnableMethod(file_manager_, | 93 base::Bind(&DownloadFileManager::OnDownloadManagerShutdown, |
| 98 &DownloadFileManager::OnDownloadManagerShutdown, | 94 file_manager_, make_scoped_refptr(this))); |
| 99 make_scoped_refptr(this))); | |
| 100 } | 95 } |
| 101 | 96 |
| 102 AssertContainersConsistent(); | 97 AssertContainersConsistent(); |
| 103 | 98 |
| 104 // Go through all downloads in downloads_. Dangerous ones we need to | 99 // Go through all downloads in downloads_. Dangerous ones we need to |
| 105 // remove on disk, and in progress ones we need to cancel. | 100 // remove on disk, and in progress ones we need to cancel. |
| 106 for (DownloadSet::iterator it = downloads_.begin(); it != downloads_.end();) { | 101 for (DownloadSet::iterator it = downloads_.begin(); it != downloads_.end();) { |
| 107 DownloadItem* download = *it; | 102 DownloadItem* download = *it; |
| 108 | 103 |
| 109 // Save iterator from potential erases in this set done by called code. | 104 // Save iterator from potential erases in this set done by called code. |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 256 CheckForFileRemoval(it->second); | 251 CheckForFileRemoval(it->second); |
| 257 } | 252 } |
| 258 } | 253 } |
| 259 | 254 |
| 260 void DownloadManager::CheckForFileRemoval(DownloadItem* download_item) { | 255 void DownloadManager::CheckForFileRemoval(DownloadItem* download_item) { |
| 261 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 256 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 262 if (download_item->IsComplete() && | 257 if (download_item->IsComplete() && |
| 263 !download_item->file_externally_removed()) { | 258 !download_item->file_externally_removed()) { |
| 264 BrowserThread::PostTask( | 259 BrowserThread::PostTask( |
| 265 BrowserThread::FILE, FROM_HERE, | 260 BrowserThread::FILE, FROM_HERE, |
| 266 NewRunnableMethod(this, | 261 base::Bind(&DownloadManager::CheckForFileRemovalOnFileThread, |
| 267 &DownloadManager::CheckForFileRemovalOnFileThread, | 262 this, download_item->db_handle(), |
| 268 download_item->db_handle(), | 263 download_item->GetTargetFilePath())); |
| 269 download_item->GetTargetFilePath())); | |
| 270 } | 264 } |
| 271 } | 265 } |
| 272 | 266 |
| 273 void DownloadManager::CheckForFileRemovalOnFileThread( | 267 void DownloadManager::CheckForFileRemovalOnFileThread( |
| 274 int64 db_handle, const FilePath& path) { | 268 int64 db_handle, const FilePath& path) { |
| 275 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 269 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 276 if (!file_util::PathExists(path)) { | 270 if (!file_util::PathExists(path)) { |
| 277 BrowserThread::PostTask( | 271 BrowserThread::PostTask( |
| 278 BrowserThread::UI, FROM_HERE, | 272 BrowserThread::UI, FROM_HERE, |
| 279 NewRunnableMethod(this, | 273 base::Bind(&DownloadManager::OnFileRemovalDetected, this, db_handle)); |
| 280 &DownloadManager::OnFileRemovalDetected, | |
| 281 db_handle)); | |
| 282 } | 274 } |
| 283 } | 275 } |
| 284 | 276 |
| 285 void DownloadManager::OnFileRemovalDetected(int64 db_handle) { | 277 void DownloadManager::OnFileRemovalDetected(int64 db_handle) { |
| 286 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 278 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 287 DownloadMap::iterator it = history_downloads_.find(db_handle); | 279 DownloadMap::iterator it = history_downloads_.find(db_handle); |
| 288 if (it != history_downloads_.end()) { | 280 if (it != history_downloads_.end()) { |
| 289 DownloadItem* download_item = it->second; | 281 DownloadItem* download_item = it->second; |
| 290 download_item->OnDownloadedFileRemoved(); | 282 download_item->OnDownloadedFileRemoved(); |
| 291 } | 283 } |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 364 in_progress_[download_id] = download; | 356 in_progress_[download_id] = download; |
| 365 UpdateDownloadProgress(); // Reflect entry into in_progress_. | 357 UpdateDownloadProgress(); // Reflect entry into in_progress_. |
| 366 | 358 |
| 367 // Rename to intermediate name. | 359 // Rename to intermediate name. |
| 368 FilePath download_path; | 360 FilePath download_path; |
| 369 if (!delegate_->OverrideIntermediatePath(download, &download_path)) | 361 if (!delegate_->OverrideIntermediatePath(download, &download_path)) |
| 370 download_path = download->full_path(); | 362 download_path = download->full_path(); |
| 371 | 363 |
| 372 BrowserThread::PostTask( | 364 BrowserThread::PostTask( |
| 373 BrowserThread::FILE, FROM_HERE, | 365 BrowserThread::FILE, FROM_HERE, |
| 374 NewRunnableMethod( | 366 base::Bind(&DownloadFileManager::RenameInProgressDownloadFile, |
| 375 file_manager_, &DownloadFileManager::RenameInProgressDownloadFile, | 367 file_manager_, download->global_id(), download_path)); |
| 376 download->global_id(), download_path)); | |
| 377 | 368 |
| 378 download->Rename(download_path); | 369 download->Rename(download_path); |
| 379 | 370 |
| 380 delegate_->AddItemToPersistentStore(download); | 371 delegate_->AddItemToPersistentStore(download); |
| 381 } | 372 } |
| 382 | 373 |
| 383 void DownloadManager::UpdateDownload(int32 download_id, int64 size) { | 374 void DownloadManager::UpdateDownload(int32 download_id, int64 size) { |
| 384 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 375 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 385 DownloadMap::iterator it = active_downloads_.find(download_id); | 376 DownloadMap::iterator it = active_downloads_.find(download_id); |
| 386 if (it != active_downloads_.end()) { | 377 if (it != active_downloads_.end()) { |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 527 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 518 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 528 | 519 |
| 529 DownloadItem* item = GetDownloadItem(download_id); | 520 DownloadItem* item = GetDownloadItem(download_id); |
| 530 if (!item) | 521 if (!item) |
| 531 return; | 522 return; |
| 532 | 523 |
| 533 if (item->safety_state() == DownloadItem::SAFE) { | 524 if (item->safety_state() == DownloadItem::SAFE) { |
| 534 DCHECK_EQ(0, uniquifier) << "We should not uniquify SAFE downloads twice"; | 525 DCHECK_EQ(0, uniquifier) << "We should not uniquify SAFE downloads twice"; |
| 535 } | 526 } |
| 536 | 527 |
| 537 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, NewRunnableMethod( | 528 BrowserThread::PostTask( |
| 538 file_manager_, | 529 BrowserThread::FILE, FROM_HERE, |
| 539 &DownloadFileManager::CompleteDownload, | 530 base::Bind(&DownloadFileManager::CompleteDownload, |
| 540 item->global_id())); | 531 file_manager_, item->global_id())); |
| 541 | 532 |
| 542 if (uniquifier) | 533 if (uniquifier) |
| 543 item->set_path_uniquifier(uniquifier); | 534 item->set_path_uniquifier(uniquifier); |
| 544 | 535 |
| 545 item->OnDownloadRenamedToFinalName(full_path); | 536 item->OnDownloadRenamedToFinalName(full_path); |
| 546 delegate_->UpdatePathForItemInPersistentStore(item, full_path); | 537 delegate_->UpdatePathForItemInPersistentStore(item, full_path); |
| 547 } | 538 } |
| 548 | 539 |
| 549 void DownloadManager::CancelDownload(int32 download_id) { | 540 void DownloadManager::CancelDownload(int32 download_id) { |
| 550 DownloadItem* download = GetActiveDownload(download_id); | 541 DownloadItem* download = GetActiveDownload(download_id); |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 711 void DownloadManager::DownloadUrlToFile(const GURL& url, | 702 void DownloadManager::DownloadUrlToFile(const GURL& url, |
| 712 const GURL& referrer, | 703 const GURL& referrer, |
| 713 const std::string& referrer_charset, | 704 const std::string& referrer_charset, |
| 714 const DownloadSaveInfo& save_info, | 705 const DownloadSaveInfo& save_info, |
| 715 TabContents* tab_contents) { | 706 TabContents* tab_contents) { |
| 716 DCHECK(tab_contents); | 707 DCHECK(tab_contents); |
| 717 ResourceDispatcherHost* resource_dispatcher_host = | 708 ResourceDispatcherHost* resource_dispatcher_host = |
| 718 content::GetContentClient()->browser()->GetResourceDispatcherHost(); | 709 content::GetContentClient()->browser()->GetResourceDispatcherHost(); |
| 719 // We send a pointer to content::ResourceContext, instead of the usual | 710 // We send a pointer to content::ResourceContext, instead of the usual |
| 720 // reference, so that a copy of the object isn't made. | 711 // reference, so that a copy of the object isn't made. |
| 721 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 712 // We use Tuple7 because base::Bind can't handle 7 arguments. |
| 722 NewRunnableFunction(&BeginDownload, | 713 BrowserThread::PostTask( |
| 723 url, | 714 BrowserThread::IO, FROM_HERE, |
| 724 referrer, | 715 base::Bind(&BeginDownload, MakeTuple( |
| 725 save_info, | 716 url, referrer, save_info, resource_dispatcher_host, |
| 726 resource_dispatcher_host, | 717 tab_contents->GetRenderProcessHost()->id(), |
| 727 tab_contents->GetRenderProcessHost()->id(), | 718 tab_contents->render_view_host()->routing_id(), |
| 728 tab_contents->render_view_host()->routing_id(), | 719 &tab_contents->browser_context()->GetResourceContext()))); |
| 729 &tab_contents->browser_context()-> | |
| 730 GetResourceContext())); | |
| 731 } | 720 } |
| 732 | 721 |
| 733 void DownloadManager::AddObserver(Observer* observer) { | 722 void DownloadManager::AddObserver(Observer* observer) { |
| 734 observers_.AddObserver(observer); | 723 observers_.AddObserver(observer); |
| 735 observer->ModelChanged(); | 724 observer->ModelChanged(); |
| 736 } | 725 } |
| 737 | 726 |
| 738 void DownloadManager::RemoveObserver(Observer* observer) { | 727 void DownloadManager::RemoveObserver(Observer* observer) { |
| 739 observers_.RemoveObserver(observer); | 728 observers_.RemoveObserver(observer); |
| 740 } | 729 } |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1085 void DownloadManager::MarkDownloadOpened(DownloadItem* download) { | 1074 void DownloadManager::MarkDownloadOpened(DownloadItem* download) { |
| 1086 delegate_->UpdateItemInPersistentStore(download); | 1075 delegate_->UpdateItemInPersistentStore(download); |
| 1087 int num_unopened = 0; | 1076 int num_unopened = 0; |
| 1088 for (DownloadMap::iterator it = history_downloads_.begin(); | 1077 for (DownloadMap::iterator it = history_downloads_.begin(); |
| 1089 it != history_downloads_.end(); ++it) { | 1078 it != history_downloads_.end(); ++it) { |
| 1090 if (it->second->IsComplete() && !it->second->opened()) | 1079 if (it->second->IsComplete() && !it->second->opened()) |
| 1091 ++num_unopened; | 1080 ++num_unopened; |
| 1092 } | 1081 } |
| 1093 download_stats::RecordOpensOutstanding(num_unopened); | 1082 download_stats::RecordOpensOutstanding(num_unopened); |
| 1094 } | 1083 } |
| OLD | NEW |