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 |