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 "chrome/browser/download/download_manager.h" | 5 #include "chrome/browser/download/download_manager.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | |
| 7 #include "base/callback.h" | 8 #include "base/callback.h" |
| 8 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 9 #include "base/i18n/case_conversion.h" | 10 #include "base/i18n/case_conversion.h" |
| 10 #include "base/logging.h" | 11 #include "base/logging.h" |
| 11 #include "base/path_service.h" | 12 #include "base/path_service.h" |
| 12 #include "base/rand_util.h" | 13 #include "base/rand_util.h" |
| 13 #include "base/stl_util.h" | 14 #include "base/stl_util.h" |
| 14 #include "base/stringprintf.h" | 15 #include "base/stringprintf.h" |
| 16 #include "base/synchronization/lock.h" | |
| 15 #include "base/sys_string_conversions.h" | 17 #include "base/sys_string_conversions.h" |
| 16 #include "base/task.h" | 18 #include "base/task.h" |
| 17 #include "base/utf_string_conversions.h" | 19 #include "base/utf_string_conversions.h" |
| 18 #include "build/build_config.h" | 20 #include "build/build_config.h" |
| 19 #include "chrome/browser/browser_process.h" | 21 #include "chrome/browser/browser_process.h" |
| 20 #include "chrome/browser/download/download_create_info.h" | 22 #include "chrome/browser/download/download_create_info.h" |
| 21 #include "chrome/browser/download/download_extensions.h" | 23 #include "chrome/browser/download/download_extensions.h" |
| 22 #include "chrome/browser/download/download_file_manager.h" | 24 #include "chrome/browser/download/download_file_manager.h" |
| 23 #include "chrome/browser/download/download_history.h" | 25 #include "chrome/browser/download/download_history.h" |
| 24 #include "chrome/browser/download/download_item.h" | 26 #include "chrome/browser/download/download_item.h" |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 45 #include "googleurl/src/gurl.h" | 47 #include "googleurl/src/gurl.h" |
| 46 #include "grit/generated_resources.h" | 48 #include "grit/generated_resources.h" |
| 47 #include "grit/theme_resources.h" | 49 #include "grit/theme_resources.h" |
| 48 #include "net/base/mime_util.h" | 50 #include "net/base/mime_util.h" |
| 49 #include "net/base/net_util.h" | 51 #include "net/base/net_util.h" |
| 50 #include "ui/base/l10n/l10n_util.h" | 52 #include "ui/base/l10n/l10n_util.h" |
| 51 #include "ui/base/resource/resource_bundle.h" | 53 #include "ui/base/resource/resource_bundle.h" |
| 52 | 54 |
| 53 DownloadManager::DownloadManager(DownloadStatusUpdater* status_updater) | 55 DownloadManager::DownloadManager(DownloadStatusUpdater* status_updater) |
| 54 : shutdown_needed_(false), | 56 : shutdown_needed_(false), |
| 57 next_id_(-1), | |
| 55 profile_(NULL), | 58 profile_(NULL), |
| 56 file_manager_(NULL), | 59 file_manager_(NULL), |
| 57 status_updater_(status_updater->AsWeakPtr()) { | 60 status_updater_(status_updater->AsWeakPtr()) { |
| 58 if (status_updater_) | 61 if (status_updater_) |
| 59 status_updater_->AddDelegate(this); | 62 status_updater_->AddDelegate(this); |
| 60 } | 63 } |
| 61 | 64 |
| 62 DownloadManager::~DownloadManager() { | 65 DownloadManager::~DownloadManager() { |
| 63 DCHECK(!shutdown_needed_); | 66 DCHECK(!shutdown_needed_); |
| 64 if (status_updater_) | 67 if (status_updater_) |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 215 if (download_item->MatchesQuery(query_lower)) | 218 if (download_item->MatchesQuery(query_lower)) |
| 216 result->push_back(download_item); | 219 result->push_back(download_item); |
| 217 } | 220 } |
| 218 | 221 |
| 219 // If we have a parent profile, let it add its downloads to the results. | 222 // If we have a parent profile, let it add its downloads to the results. |
| 220 Profile* original_profile = profile_->GetOriginalProfile(); | 223 Profile* original_profile = profile_->GetOriginalProfile(); |
| 221 if (original_profile != profile_) | 224 if (original_profile != profile_) |
| 222 original_profile->GetDownloadManager()->SearchDownloads(query, result); | 225 original_profile->GetDownloadManager()->SearchDownloads(query, result); |
| 223 } | 226 } |
| 224 | 227 |
| 228 void DownloadManager::OnHistoryGetNextId(int next_id) { | |
| 229 DVLOG(1) << __FUNCTION__ << " " << next_id; | |
| 230 next_id_ = next_id; | |
| 231 } | |
| 232 | |
| 233 DownloadId DownloadManager::GetNextId() { | |
| 234 // May be called on any thread via the GetNextIdThunk. | |
| 235 DCHECK(next_id_ >= 0) << "Uh oh, OnHistoryGetNextId hasn't happened yet!"; | |
|
Randy Smith (Not in Mondays)
2011/07/25 20:20:12
I see nothing architectural preventing this DCHECK
benjhayden
2011/07/27 19:40:54
I think we decided to do this in the next CL.
| |
| 236 base::AutoLock _(next_id_lock_); | |
| 237 return DownloadId(this, next_id_++); | |
| 238 } | |
| 239 | |
| 240 base::Callback<DownloadId(void)> DownloadManager::GetNextIdThunk() { | |
| 241 return base::Bind(&DownloadManager::GetNextId, this); | |
| 242 } | |
| 243 | |
| 225 // Query the history service for information about all persisted downloads. | 244 // Query the history service for information about all persisted downloads. |
| 226 bool DownloadManager::Init(Profile* profile) { | 245 bool DownloadManager::Init(Profile* profile) { |
| 227 DCHECK(profile); | 246 DCHECK(profile); |
| 228 DCHECK(!shutdown_needed_) << "DownloadManager already initialized."; | 247 DCHECK(!shutdown_needed_) << "DownloadManager already initialized."; |
| 229 shutdown_needed_ = true; | 248 shutdown_needed_ = true; |
| 230 | 249 |
| 231 profile_ = profile; | 250 profile_ = profile; |
| 232 download_history_.reset(new DownloadHistory(profile)); | 251 download_history_.reset(new DownloadHistory(profile)); |
| 252 download_history_->GetNextId(NewCallback( | |
| 253 this, &DownloadManager::OnHistoryGetNextId)); | |
| 233 download_history_->Load( | 254 download_history_->Load( |
| 234 NewCallback(this, &DownloadManager::OnQueryDownloadEntriesComplete)); | 255 NewCallback(this, &DownloadManager::OnQueryDownloadEntriesComplete)); |
| 235 | 256 |
| 236 download_prefs_.reset(new DownloadPrefs(profile_->GetPrefs())); | 257 download_prefs_.reset(new DownloadPrefs(profile_->GetPrefs())); |
| 237 | 258 |
| 238 // In test mode, there may be no ResourceDispatcherHost. In this case it's | 259 // In test mode, there may be no ResourceDispatcherHost. In this case it's |
| 239 // safe to avoid setting |file_manager_| because we only call a small set of | 260 // safe to avoid setting |file_manager_| because we only call a small set of |
| 240 // functions, none of which need it. | 261 // functions, none of which need it. |
| 241 ResourceDispatcherHost* rdh = g_browser_process->resource_dispatcher_host(); | 262 ResourceDispatcherHost* rdh = g_browser_process->resource_dispatcher_host(); |
| 242 if (rdh) { | 263 if (rdh) { |
| (...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 602 // name after user confirmation will be set from | 623 // name after user confirmation will be set from |
| 603 // DownloadItem::OnDownloadCompleting. | 624 // DownloadItem::OnDownloadCompleting. |
| 604 download_path = | 625 download_path = |
| 605 download_util::GetCrDownloadPath(download->full_path()); | 626 download_util::GetCrDownloadPath(download->full_path()); |
| 606 } | 627 } |
| 607 | 628 |
| 608 BrowserThread::PostTask( | 629 BrowserThread::PostTask( |
| 609 BrowserThread::FILE, FROM_HERE, | 630 BrowserThread::FILE, FROM_HERE, |
| 610 NewRunnableMethod( | 631 NewRunnableMethod( |
| 611 file_manager_, &DownloadFileManager::RenameInProgressDownloadFile, | 632 file_manager_, &DownloadFileManager::RenameInProgressDownloadFile, |
| 612 download->id(), download_path)); | 633 download->gid(), download_path)); |
| 613 | 634 |
| 614 download->Rename(download_path); | 635 download->Rename(download_path); |
| 615 | 636 |
| 616 download_history_->AddEntry(download, | 637 download_history_->AddEntry(download, |
| 617 NewCallback(this, &DownloadManager::OnCreateDownloadEntryComplete)); | 638 NewCallback(this, &DownloadManager::OnCreateDownloadEntryComplete)); |
| 618 } | 639 } |
| 619 | 640 |
| 620 void DownloadManager::UpdateDownload(int32 download_id, int64 size) { | 641 void DownloadManager::UpdateDownload(int32 download_id, int64 size) { |
| 621 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 642 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 622 DownloadMap::iterator it = active_downloads_.find(download_id); | 643 DownloadMap::iterator it = active_downloads_.find(download_id); |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 752 // file rename, and UI display) then it's not ready for completion. | 773 // file rename, and UI display) then it's not ready for completion. |
| 753 if (download->db_handle() == DownloadHistory::kUninitializedHandle) | 774 if (download->db_handle() == DownloadHistory::kUninitializedHandle) |
| 754 return false; | 775 return false; |
| 755 | 776 |
| 756 return true; | 777 return true; |
| 757 } | 778 } |
| 758 | 779 |
| 759 void DownloadManager::MaybeCompleteDownload(DownloadItem* download) { | 780 void DownloadManager::MaybeCompleteDownload(DownloadItem* download) { |
| 760 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 781 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 761 VLOG(20) << __FUNCTION__ << "()" << " download = " | 782 VLOG(20) << __FUNCTION__ << "()" << " download = " |
| 762 << download->DebugString(false); | 783 << download->DebugString(true); |
|
Randy Smith (Not in Mondays)
2011/07/25 20:20:12
Why change the logging? I don't particularly care
benjhayden
2011/07/27 19:40:54
Done.
| |
| 763 | 784 |
| 764 if (!IsDownloadReadyForCompletion(download)) | 785 if (!IsDownloadReadyForCompletion(download)) |
| 765 return; | 786 return; |
| 766 | 787 |
| 767 // TODO(rdsmith): DCHECK that we only pass through this point | 788 // TODO(rdsmith): DCHECK that we only pass through this point |
| 768 // once per download. The natural way to do this is by a state | 789 // once per download. The natural way to do this is by a state |
| 769 // transition on the DownloadItem. | 790 // transition on the DownloadItem. |
| 770 | 791 |
| 771 // Confirm we're in the proper set of states to be here; | 792 // Confirm we're in the proper set of states to be here; |
| 772 // in in_progress_, have all data, have a history handle, (validated or safe). | 793 // in in_progress_, have all data, have a history handle, (validated or safe). |
| 773 DCHECK_NE(DownloadItem::DANGEROUS, download->safety_state()); | 794 DCHECK_NE(DownloadItem::DANGEROUS, download->safety_state()); |
| 774 DCHECK_EQ(1u, in_progress_.count(download->id())); | 795 DCHECK_EQ(1u, in_progress_.count(download->id())); |
| 775 DCHECK(download->all_data_saved()); | 796 DCHECK(download->all_data_saved()); |
| 776 DCHECK(download->db_handle() != DownloadHistory::kUninitializedHandle); | 797 DCHECK(download->db_handle() != DownloadHistory::kUninitializedHandle); |
| 777 DCHECK_EQ(1u, history_downloads_.count(download->db_handle())); | 798 DCHECK_EQ(1u, history_downloads_.count(download->db_handle())); |
| 778 | 799 |
| 779 VLOG(20) << __FUNCTION__ << "()" << " executing: download = " | 800 VLOG(20) << __FUNCTION__ << "()" << " executing: download = " |
| 780 << download->DebugString(false); | 801 << download->DebugString(true); |
| 781 | 802 |
| 782 // Remove the id from in_progress | 803 // Remove the id from in_progress |
| 783 in_progress_.erase(download->id()); | 804 in_progress_.erase(download->id()); |
| 784 UpdateAppIcon(); // Reflect removal from in_progress_. | 805 UpdateAppIcon(); // Reflect removal from in_progress_. |
| 785 | 806 |
| 786 download_history_->UpdateEntry(download); | 807 download_history_->UpdateEntry(download); |
| 787 | 808 |
| 788 // Finish the download. | 809 // Finish the download. |
| 789 download->OnDownloadCompleting(file_manager_); | 810 download->OnDownloadCompleting(file_manager_); |
| 790 } | 811 } |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 809 if (!item) | 830 if (!item) |
| 810 return; | 831 return; |
| 811 | 832 |
| 812 if (item->safety_state() == DownloadItem::SAFE) { | 833 if (item->safety_state() == DownloadItem::SAFE) { |
| 813 DCHECK_EQ(0, uniquifier) << "We should not uniquify SAFE downloads twice"; | 834 DCHECK_EQ(0, uniquifier) << "We should not uniquify SAFE downloads twice"; |
| 814 } | 835 } |
| 815 | 836 |
| 816 BrowserThread::PostTask( | 837 BrowserThread::PostTask( |
| 817 BrowserThread::FILE, FROM_HERE, | 838 BrowserThread::FILE, FROM_HERE, |
| 818 NewRunnableMethod( | 839 NewRunnableMethod( |
| 819 file_manager_, &DownloadFileManager::CompleteDownload, download_id)); | 840 file_manager_, &DownloadFileManager::CompleteDownload, item->gid())); |
| 820 | 841 |
| 821 if (uniquifier) | 842 if (uniquifier) |
| 822 item->set_path_uniquifier(uniquifier); | 843 item->set_path_uniquifier(uniquifier); |
| 823 | 844 |
| 824 item->OnDownloadRenamedToFinalName(full_path); | 845 item->OnDownloadRenamedToFinalName(full_path); |
| 825 download_history_->UpdateDownloadPath(item, full_path); | 846 download_history_->UpdateDownloadPath(item, full_path); |
| 826 } | 847 } |
| 827 | 848 |
| 828 void DownloadManager::DownloadCancelled(int32 download_id) { | 849 void DownloadManager::DownloadCancelled(int32 download_id) { |
| 829 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 850 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 845 } | 866 } |
| 846 | 867 |
| 847 DownloadCancelledInternal(download_id, download->request_handle()); | 868 DownloadCancelledInternal(download_id, download->request_handle()); |
| 848 } | 869 } |
| 849 | 870 |
| 850 void DownloadManager::DownloadCancelledInternal( | 871 void DownloadManager::DownloadCancelledInternal( |
| 851 int download_id, const DownloadRequestHandle& request_handle) { | 872 int download_id, const DownloadRequestHandle& request_handle) { |
| 852 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 873 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 853 request_handle.CancelRequest(); | 874 request_handle.CancelRequest(); |
| 854 | 875 |
| 855 BrowserThread::PostTask( | 876 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, NewRunnableMethod( |
| 856 BrowserThread::FILE, FROM_HERE, | 877 file_manager_, &DownloadFileManager::CancelDownload, |
| 857 NewRunnableMethod( | 878 DownloadId(this, download_id))); |
| 858 file_manager_, &DownloadFileManager::CancelDownload, download_id)); | |
| 859 } | 879 } |
| 860 | 880 |
| 861 void DownloadManager::OnDownloadError(int32 download_id, | 881 void DownloadManager::OnDownloadError(int32 download_id, |
| 862 int64 size, | 882 int64 size, |
| 863 int os_error) { | 883 int os_error) { |
| 864 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 884 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 865 DownloadMap::iterator it = active_downloads_.find(download_id); | 885 DownloadMap::iterator it = active_downloads_.find(download_id); |
| 866 // A cancel at the right time could remove the download from the | 886 // A cancel at the right time could remove the download from the |
| 867 // |active_downloads_| map before we get here. | 887 // |active_downloads_| map before we get here. |
| 868 if (it == active_downloads_.end()) | 888 if (it == active_downloads_.end()) |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 881 // | 901 // |
| 882 // Clean up will happen when the history system create callback runs if we | 902 // Clean up will happen when the history system create callback runs if we |
| 883 // don't have a valid db_handle yet. | 903 // don't have a valid db_handle yet. |
| 884 if (download->db_handle() != DownloadHistory::kUninitializedHandle) { | 904 if (download->db_handle() != DownloadHistory::kUninitializedHandle) { |
| 885 in_progress_.erase(download_id); | 905 in_progress_.erase(download_id); |
| 886 active_downloads_.erase(download_id); | 906 active_downloads_.erase(download_id); |
| 887 UpdateAppIcon(); // Reflect removal from in_progress_. | 907 UpdateAppIcon(); // Reflect removal from in_progress_. |
| 888 download_history_->UpdateEntry(download); | 908 download_history_->UpdateEntry(download); |
| 889 } | 909 } |
| 890 | 910 |
| 891 BrowserThread::PostTask( | 911 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, NewRunnableMethod( |
| 892 BrowserThread::FILE, FROM_HERE, | 912 file_manager_, &DownloadFileManager::CancelDownload, download->gid())); |
| 893 NewRunnableMethod( | |
| 894 file_manager_, &DownloadFileManager::CancelDownload, download_id)); | |
| 895 } | 913 } |
| 896 | 914 |
| 897 void DownloadManager::UpdateAppIcon() { | 915 void DownloadManager::UpdateAppIcon() { |
| 898 if (status_updater_) | 916 if (status_updater_) |
| 899 status_updater_->Update(); | 917 status_updater_->Update(); |
| 900 } | 918 } |
| 901 | 919 |
| 902 void DownloadManager::RemoveDownload(int64 download_handle) { | 920 void DownloadManager::RemoveDownload(int64 download_handle) { |
| 903 DownloadMap::iterator it = history_downloads_.find(download_handle); | 921 DownloadMap::iterator it = history_downloads_.find(download_handle); |
| 904 if (it == history_downloads_.end()) | 922 if (it == history_downloads_.end()) |
| (...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1346 observed_download_manager_->RemoveObserver(this); | 1364 observed_download_manager_->RemoveObserver(this); |
| 1347 } | 1365 } |
| 1348 | 1366 |
| 1349 void DownloadManager::OtherDownloadManagerObserver::ModelChanged() { | 1367 void DownloadManager::OtherDownloadManagerObserver::ModelChanged() { |
| 1350 observing_download_manager_->NotifyModelChanged(); | 1368 observing_download_manager_->NotifyModelChanged(); |
| 1351 } | 1369 } |
| 1352 | 1370 |
| 1353 void DownloadManager::OtherDownloadManagerObserver::ManagerGoingDown() { | 1371 void DownloadManager::OtherDownloadManagerObserver::ManagerGoingDown() { |
| 1354 observed_download_manager_ = NULL; | 1372 observed_download_manager_ = NULL; |
| 1355 } | 1373 } |
| OLD | NEW |