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 "grit/generated_resources.h" | 47 #include "grit/generated_resources.h" |
46 #include "grit/theme_resources.h" | 48 #include "grit/theme_resources.h" |
47 #include "net/base/mime_util.h" | 49 #include "net/base/mime_util.h" |
48 #include "net/base/net_util.h" | 50 #include "net/base/net_util.h" |
49 #include "ui/base/l10n/l10n_util.h" | 51 #include "ui/base/l10n/l10n_util.h" |
50 #include "ui/base/resource/resource_bundle.h" | 52 #include "ui/base/resource/resource_bundle.h" |
51 | 53 |
52 DownloadManager::DownloadManager(DownloadManagerDelegate* delegate, | 54 DownloadManager::DownloadManager(DownloadManagerDelegate* delegate, |
53 DownloadStatusUpdater* status_updater) | 55 DownloadStatusUpdater* status_updater) |
54 : shutdown_needed_(false), | 56 : shutdown_needed_(false), |
| 57 next_id_(0), |
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 next_save_page_id_(0), | 61 next_save_page_id_(0), |
59 delegate_(delegate) { | 62 delegate_(delegate) { |
60 if (status_updater_) | 63 if (status_updater_) |
61 status_updater_->AddDelegate(this); | 64 status_updater_->AddDelegate(this); |
62 } | 65 } |
63 | 66 |
64 DownloadManager::~DownloadManager() { | 67 DownloadManager::~DownloadManager() { |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 if (download_item->MatchesQuery(query_lower)) | 214 if (download_item->MatchesQuery(query_lower)) |
212 result->push_back(download_item); | 215 result->push_back(download_item); |
213 } | 216 } |
214 | 217 |
215 // If we have a parent profile, let it add its downloads to the results. | 218 // If we have a parent profile, let it add its downloads to the results. |
216 Profile* original_profile = profile_->GetOriginalProfile(); | 219 Profile* original_profile = profile_->GetOriginalProfile(); |
217 if (original_profile != profile_) | 220 if (original_profile != profile_) |
218 original_profile->GetDownloadManager()->SearchDownloads(query, result); | 221 original_profile->GetDownloadManager()->SearchDownloads(query, result); |
219 } | 222 } |
220 | 223 |
| 224 void DownloadManager::OnHistoryGetNextId(int next_id) { |
| 225 DVLOG(1) << __FUNCTION__ << " " << next_id; |
| 226 base::AutoLock lock(next_id_lock_); |
| 227 // TODO(benjhayden) Delay Profile initialization until here, and set next_id_ |
| 228 // = next_id. The '+=' works for now because these ids are not yet persisted |
| 229 // to the database. GetNextId() can allocate zero or more ids starting from 0, |
| 230 // then this callback can increment next_id_, and the items with lower ids |
| 231 // won't clash with any other items even though there may be items loaded from |
| 232 // the history because items from the history don't have valid ids. |
| 233 next_id_ += next_id; |
| 234 } |
| 235 |
| 236 DownloadId DownloadManager::GetNextId() { |
| 237 // May be called on any thread via the GetNextIdThunk. |
| 238 // TODO(benjhayden) If otr, forward to parent DM. |
| 239 base::AutoLock lock(next_id_lock_); |
| 240 return DownloadId(this, next_id_++); |
| 241 } |
| 242 |
| 243 DownloadManager::GetNextIdThunkType DownloadManager::GetNextIdThunk() { |
| 244 // TODO(benjhayden) If otr, forward to parent DM. |
| 245 return base::Bind(&DownloadManager::GetNextId, this); |
| 246 } |
| 247 |
221 // Query the history service for information about all persisted downloads. | 248 // Query the history service for information about all persisted downloads. |
222 bool DownloadManager::Init(Profile* profile) { | 249 bool DownloadManager::Init(Profile* profile) { |
223 DCHECK(profile); | 250 DCHECK(profile); |
224 DCHECK(!shutdown_needed_) << "DownloadManager already initialized."; | 251 DCHECK(!shutdown_needed_) << "DownloadManager already initialized."; |
225 shutdown_needed_ = true; | 252 shutdown_needed_ = true; |
226 | 253 |
227 profile_ = profile; | 254 profile_ = profile; |
228 download_history_.reset(new DownloadHistory(profile)); | 255 download_history_.reset(new DownloadHistory(profile)); |
| 256 // DownloadHistory does not guarantee that these callbacks will be run. These |
| 257 // callbacks won't be run if the user has disabled history or history |
| 258 // initialization failed. |
| 259 download_history_->GetNextId(NewCallback( |
| 260 this, &DownloadManager::OnHistoryGetNextId)); |
229 download_history_->Load( | 261 download_history_->Load( |
230 NewCallback(this, &DownloadManager::OnQueryDownloadEntriesComplete)); | 262 NewCallback(this, &DownloadManager::OnQueryDownloadEntriesComplete)); |
231 | 263 |
232 download_prefs_.reset(new DownloadPrefs(profile_->GetPrefs())); | 264 download_prefs_.reset(new DownloadPrefs(profile_->GetPrefs())); |
233 | 265 |
234 // In test mode, there may be no ResourceDispatcherHost. In this case it's | 266 // In test mode, there may be no ResourceDispatcherHost. In this case it's |
235 // safe to avoid setting |file_manager_| because we only call a small set of | 267 // safe to avoid setting |file_manager_| because we only call a small set of |
236 // functions, none of which need it. | 268 // functions, none of which need it. |
237 ResourceDispatcherHost* rdh = g_browser_process->resource_dispatcher_host(); | 269 ResourceDispatcherHost* rdh = g_browser_process->resource_dispatcher_host(); |
238 if (rdh) { | 270 if (rdh) { |
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
581 // name after user confirmation will be set from | 613 // name after user confirmation will be set from |
582 // DownloadItem::OnDownloadCompleting. | 614 // DownloadItem::OnDownloadCompleting. |
583 download_path = | 615 download_path = |
584 download_util::GetCrDownloadPath(download->full_path()); | 616 download_util::GetCrDownloadPath(download->full_path()); |
585 } | 617 } |
586 | 618 |
587 BrowserThread::PostTask( | 619 BrowserThread::PostTask( |
588 BrowserThread::FILE, FROM_HERE, | 620 BrowserThread::FILE, FROM_HERE, |
589 NewRunnableMethod( | 621 NewRunnableMethod( |
590 file_manager_, &DownloadFileManager::RenameInProgressDownloadFile, | 622 file_manager_, &DownloadFileManager::RenameInProgressDownloadFile, |
591 download->id(), download_path)); | 623 download->global_id(), download_path)); |
592 | 624 |
593 download->Rename(download_path); | 625 download->Rename(download_path); |
594 | 626 |
595 download_history_->AddEntry(download, | 627 download_history_->AddEntry(download, |
596 NewCallback(this, &DownloadManager::OnCreateDownloadEntryComplete)); | 628 NewCallback(this, &DownloadManager::OnCreateDownloadEntryComplete)); |
597 } | 629 } |
598 | 630 |
599 void DownloadManager::UpdateDownload(int32 download_id, int64 size) { | 631 void DownloadManager::UpdateDownload(int32 download_id, int64 size) { |
600 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 632 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
601 DownloadMap::iterator it = active_downloads_.find(download_id); | 633 DownloadMap::iterator it = active_downloads_.find(download_id); |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
785 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 817 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
786 | 818 |
787 DownloadItem* item = GetDownloadItem(download_id); | 819 DownloadItem* item = GetDownloadItem(download_id); |
788 if (!item) | 820 if (!item) |
789 return; | 821 return; |
790 | 822 |
791 if (item->safety_state() == DownloadItem::SAFE) { | 823 if (item->safety_state() == DownloadItem::SAFE) { |
792 DCHECK_EQ(0, uniquifier) << "We should not uniquify SAFE downloads twice"; | 824 DCHECK_EQ(0, uniquifier) << "We should not uniquify SAFE downloads twice"; |
793 } | 825 } |
794 | 826 |
795 BrowserThread::PostTask( | 827 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, NewRunnableMethod( |
796 BrowserThread::FILE, FROM_HERE, | 828 file_manager_, |
797 NewRunnableMethod( | 829 &DownloadFileManager::CompleteDownload, |
798 file_manager_, &DownloadFileManager::CompleteDownload, download_id)); | 830 item->global_id())); |
799 | 831 |
800 if (uniquifier) | 832 if (uniquifier) |
801 item->set_path_uniquifier(uniquifier); | 833 item->set_path_uniquifier(uniquifier); |
802 | 834 |
803 item->OnDownloadRenamedToFinalName(full_path); | 835 item->OnDownloadRenamedToFinalName(full_path); |
804 download_history_->UpdateDownloadPath(item, full_path); | 836 download_history_->UpdateDownloadPath(item, full_path); |
805 } | 837 } |
806 | 838 |
807 void DownloadManager::DownloadCancelled(int32 download_id) { | 839 void DownloadManager::DownloadCancelled(int32 download_id) { |
808 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 840 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
(...skipping 15 matching lines...) Expand all Loading... |
824 } | 856 } |
825 | 857 |
826 DownloadCancelledInternal(download_id, download->request_handle()); | 858 DownloadCancelledInternal(download_id, download->request_handle()); |
827 } | 859 } |
828 | 860 |
829 void DownloadManager::DownloadCancelledInternal( | 861 void DownloadManager::DownloadCancelledInternal( |
830 int download_id, const DownloadRequestHandle& request_handle) { | 862 int download_id, const DownloadRequestHandle& request_handle) { |
831 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 863 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
832 request_handle.CancelRequest(); | 864 request_handle.CancelRequest(); |
833 | 865 |
834 BrowserThread::PostTask( | 866 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, NewRunnableMethod( |
835 BrowserThread::FILE, FROM_HERE, | 867 file_manager_, &DownloadFileManager::CancelDownload, |
836 NewRunnableMethod( | 868 DownloadId(this, download_id))); |
837 file_manager_, &DownloadFileManager::CancelDownload, download_id)); | |
838 } | 869 } |
839 | 870 |
840 void DownloadManager::OnDownloadError(int32 download_id, | 871 void DownloadManager::OnDownloadError(int32 download_id, |
841 int64 size, | 872 int64 size, |
842 int os_error) { | 873 int os_error) { |
843 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 874 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
844 DownloadMap::iterator it = active_downloads_.find(download_id); | 875 DownloadMap::iterator it = active_downloads_.find(download_id); |
845 // A cancel at the right time could remove the download from the | 876 // A cancel at the right time could remove the download from the |
846 // |active_downloads_| map before we get here. | 877 // |active_downloads_| map before we get here. |
847 if (it == active_downloads_.end()) | 878 if (it == active_downloads_.end()) |
(...skipping 12 matching lines...) Expand all Loading... |
860 // | 891 // |
861 // Clean up will happen when the history system create callback runs if we | 892 // Clean up will happen when the history system create callback runs if we |
862 // don't have a valid db_handle yet. | 893 // don't have a valid db_handle yet. |
863 if (download->db_handle() != DownloadHistory::kUninitializedHandle) { | 894 if (download->db_handle() != DownloadHistory::kUninitializedHandle) { |
864 in_progress_.erase(download_id); | 895 in_progress_.erase(download_id); |
865 active_downloads_.erase(download_id); | 896 active_downloads_.erase(download_id); |
866 UpdateAppIcon(); // Reflect removal from in_progress_. | 897 UpdateAppIcon(); // Reflect removal from in_progress_. |
867 download_history_->UpdateEntry(download); | 898 download_history_->UpdateEntry(download); |
868 } | 899 } |
869 | 900 |
870 BrowserThread::PostTask( | 901 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, NewRunnableMethod( |
871 BrowserThread::FILE, FROM_HERE, | 902 file_manager_, |
872 NewRunnableMethod( | 903 &DownloadFileManager::CancelDownload, |
873 file_manager_, &DownloadFileManager::CancelDownload, download_id)); | 904 download->global_id())); |
874 } | 905 } |
875 | 906 |
876 void DownloadManager::UpdateAppIcon() { | 907 void DownloadManager::UpdateAppIcon() { |
877 if (status_updater_) | 908 if (status_updater_) |
878 status_updater_->Update(); | 909 status_updater_->Update(); |
879 } | 910 } |
880 | 911 |
881 int DownloadManager::RemoveDownloadItems( | 912 int DownloadManager::RemoveDownloadItems( |
882 const DownloadVector& pending_deletes) { | 913 const DownloadVector& pending_deletes) { |
883 if (pending_deletes.empty()) | 914 if (pending_deletes.empty()) |
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1366 Source<DownloadManager>(this), | 1397 Source<DownloadManager>(this), |
1367 Details<DownloadItem>(download)); | 1398 Details<DownloadItem>(download)); |
1368 } | 1399 } |
1369 } | 1400 } |
1370 | 1401 |
1371 int32 DownloadManager::GetNextSavePageId() { | 1402 int32 DownloadManager::GetNextSavePageId() { |
1372 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1403 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1373 return next_save_page_id_++; | 1404 return next_save_page_id_++; |
1374 } | 1405 } |
1375 | 1406 |
OLD | NEW |