OLD | NEW |
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 "chrome/browser/download/chrome_download_manager_delegate.h" | 5 #include "chrome/browser/download/chrome_download_manager_delegate.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 } | 128 } |
129 | 129 |
130 DownloadId ChromeDownloadManagerDelegate::GetNextId() { | 130 DownloadId ChromeDownloadManagerDelegate::GetNextId() { |
131 if (!profile_->IsOffTheRecord()) | 131 if (!profile_->IsOffTheRecord()) |
132 return DownloadId(this, next_download_id_++); | 132 return DownloadId(this, next_download_id_++); |
133 | 133 |
134 return BrowserContext::GetDownloadManager(profile_->GetOriginalProfile())-> | 134 return BrowserContext::GetDownloadManager(profile_->GetOriginalProfile())-> |
135 GetDelegate()->GetNextId(); | 135 GetDelegate()->GetNextId(); |
136 } | 136 } |
137 | 137 |
138 bool ChromeDownloadManagerDelegate::ShouldStartDownload(int32 download_id) { | 138 bool ChromeDownloadManagerDelegate::DetermineDownloadTarget( |
| 139 DownloadItem* download) { |
139 // We create a download item and store it in our download map, and inform the | 140 // We create a download item and store it in our download map, and inform the |
140 // history system of a new download. Since this method can be called while the | 141 // history system of a new download. Since this method can be called while the |
141 // history service thread is still reading the persistent state, we do not | 142 // history service thread is still reading the persistent state, we do not |
142 // insert the new DownloadItem into 'history_downloads_' or inform our | 143 // insert the new DownloadItem into 'history_downloads_' or inform our |
143 // observers at this point. OnCreateDownloadEntryComplete() handles that | 144 // observers at this point. OnCreateDownloadEntryComplete() handles that |
144 // finalization of the the download creation as a callback from the history | 145 // finalization of the the download creation as a callback from the history |
145 // thread. | 146 // thread. |
146 DownloadItem* download = | |
147 download_manager_->GetActiveDownloadItem(download_id); | |
148 if (!download) | |
149 return false; | |
150 | |
151 #if defined(ENABLE_SAFE_BROWSING) | 147 #if defined(ENABLE_SAFE_BROWSING) |
152 DownloadProtectionService* service = GetDownloadProtectionService(); | 148 DownloadProtectionService* service = GetDownloadProtectionService(); |
153 if (service) { | 149 if (service) { |
154 VLOG(2) << __FUNCTION__ << "() Start SB URL check for download = " | 150 VLOG(2) << __FUNCTION__ << "() Start SB URL check for download = " |
155 << download->DebugString(false); | 151 << download->DebugString(false); |
156 service->CheckDownloadUrl( | 152 service->CheckDownloadUrl( |
157 DownloadProtectionService::DownloadInfo::FromDownloadItem(*download), | 153 DownloadProtectionService::DownloadInfo::FromDownloadItem(*download), |
158 base::Bind( | 154 base::Bind( |
159 &ChromeDownloadManagerDelegate::CheckDownloadUrlDone, | 155 &ChromeDownloadManagerDelegate::CheckDownloadUrlDone, |
160 this, | 156 this, |
161 download->GetId())); | 157 download->GetId())); |
162 return false; | 158 return true; |
163 } | 159 } |
164 #endif | 160 #endif |
165 CheckDownloadUrlDone(download_id, DownloadProtectionService::SAFE); | 161 CheckDownloadUrlDone(download->GetId(), DownloadProtectionService::SAFE); |
166 return false; | 162 return true; |
167 } | 163 } |
168 | 164 |
169 void ChromeDownloadManagerDelegate::ChooseDownloadPath(DownloadItem* item) { | 165 void ChromeDownloadManagerDelegate::ChooseDownloadPath( |
| 166 DownloadItem* item, |
| 167 const FilePath& suggested_path, |
| 168 const base::Callback<void(const FilePath&)>& file_selected_callback) { |
170 // Deletes itself. | 169 // Deletes itself. |
171 DownloadFilePicker* file_picker = | 170 DownloadFilePicker* file_picker = |
172 #if defined(OS_CHROMEOS) | 171 #if defined(OS_CHROMEOS) |
173 new DownloadFilePickerChromeOS(); | 172 new DownloadFilePickerChromeOS(); |
174 #else | 173 #else |
175 new DownloadFilePicker(); | 174 new DownloadFilePicker(); |
176 #endif | 175 #endif |
177 file_picker->Init(download_manager_, item); | 176 file_picker->Init(download_manager_, item, suggested_path, |
| 177 file_selected_callback); |
178 } | 178 } |
179 | 179 |
180 FilePath ChromeDownloadManagerDelegate::GetIntermediatePath( | 180 FilePath ChromeDownloadManagerDelegate::GetIntermediatePath( |
181 const DownloadItem& download) { | 181 const FilePath& target_path, |
| 182 content::DownloadDangerType danger_type) { |
182 // If the download is not dangerous, just append .crdownload to the target | 183 // If the download is not dangerous, just append .crdownload to the target |
183 // path. | 184 // path. |
184 if (download.GetDangerType() == content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) | 185 if (danger_type == content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) |
185 return download_util::GetCrDownloadPath(download.GetTargetFilePath()); | 186 return download_util::GetCrDownloadPath(target_path); |
186 | 187 |
187 // If the download is potentially dangerous we create a filename of the form | 188 // If the download is potentially dangerous we create a filename of the form |
188 // 'Unconfirmed <random>.crdownload'. | 189 // 'Unconfirmed <random>.crdownload'. |
189 FilePath::StringType file_name; | 190 FilePath::StringType file_name; |
190 FilePath dir = download.GetTargetFilePath().DirName(); | 191 FilePath dir = target_path.DirName(); |
191 #if defined(OS_WIN) | 192 #if defined(OS_WIN) |
192 string16 unconfirmed_prefix = | 193 string16 unconfirmed_prefix = |
193 l10n_util::GetStringUTF16(IDS_DOWNLOAD_UNCONFIRMED_PREFIX); | 194 l10n_util::GetStringUTF16(IDS_DOWNLOAD_UNCONFIRMED_PREFIX); |
194 #else | 195 #else |
195 std::string unconfirmed_prefix = | 196 std::string unconfirmed_prefix = |
196 l10n_util::GetStringUTF8(IDS_DOWNLOAD_UNCONFIRMED_PREFIX); | 197 l10n_util::GetStringUTF8(IDS_DOWNLOAD_UNCONFIRMED_PREFIX); |
197 #endif | 198 #endif |
198 base::SStringPrintf( | 199 base::SStringPrintf( |
199 &file_name, | 200 &file_name, |
200 unconfirmed_prefix.append( | 201 unconfirmed_prefix.append( |
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
648 !ShouldOpenFileBasedOnExtension(generated_name)) | 649 !ShouldOpenFileBasedOnExtension(generated_name)) |
649 should_prompt = true; | 650 should_prompt = true; |
650 } | 651 } |
651 if (download_prefs_->IsDownloadPathManaged()) | 652 if (download_prefs_->IsDownloadPathManaged()) |
652 should_prompt = false; | 653 should_prompt = false; |
653 | 654 |
654 // Determine the proper path for a download, by either one of the following: | 655 // Determine the proper path for a download, by either one of the following: |
655 // 1) using the default download directory. | 656 // 1) using the default download directory. |
656 // 2) prompting the user. | 657 // 2) prompting the user. |
657 FilePath target_directory; | 658 FilePath target_directory; |
658 if (should_prompt && !download_manager_->LastDownloadPath().empty()) | 659 if (should_prompt && !last_download_path_.empty()) |
659 target_directory = download_manager_->LastDownloadPath(); | 660 target_directory = last_download_path_; |
660 else | 661 else |
661 target_directory = download_prefs_->download_path(); | 662 target_directory = download_prefs_->download_path(); |
662 suggested_path = target_directory.Append(generated_name); | 663 suggested_path = target_directory.Append(generated_name); |
663 } else { | 664 } else { |
664 DCHECK(!should_prompt); | 665 DCHECK(!should_prompt); |
665 suggested_path = download->GetForcedFilePath(); | 666 suggested_path = download->GetForcedFilePath(); |
666 } | 667 } |
667 | 668 |
668 // If the download hasn't already been marked dangerous (could be | 669 // If the download hasn't already been marked dangerous (could be |
669 // DANGEROUS_URL), check if it is a dangerous file. | 670 // DANGEROUS_URL), check if it is a dangerous file. |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
703 #else | 704 #else |
704 GetReservedPath( | 705 GetReservedPath( |
705 *download, suggested_path, download_prefs_->download_path(), | 706 *download, suggested_path, download_prefs_->download_path(), |
706 !is_forced_path, | 707 !is_forced_path, |
707 base::Bind(&ChromeDownloadManagerDelegate::OnPathReservationAvailable, | 708 base::Bind(&ChromeDownloadManagerDelegate::OnPathReservationAvailable, |
708 this, download->GetId(), should_prompt, danger_type)); | 709 this, download->GetId(), should_prompt, danger_type)); |
709 #endif | 710 #endif |
710 } | 711 } |
711 | 712 |
712 #if defined (OS_CHROMEOS) | 713 #if defined (OS_CHROMEOS) |
| 714 // TODO(asanka): Merge this logic with the logic in DownloadFilePickerChromeOS. |
713 void ChromeDownloadManagerDelegate::SubstituteGDataDownloadPathCallback( | 715 void ChromeDownloadManagerDelegate::SubstituteGDataDownloadPathCallback( |
714 int32 download_id, | 716 int32 download_id, |
715 bool should_prompt, | 717 bool should_prompt, |
716 bool is_forced_path, | 718 bool is_forced_path, |
717 content::DownloadDangerType danger_type, | 719 content::DownloadDangerType danger_type, |
718 const FilePath& suggested_path) { | 720 const FilePath& suggested_path) { |
719 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 721 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
720 DownloadItem* download = | 722 DownloadItem* download = |
721 download_manager_->GetActiveDownloadItem(download_id); | 723 download_manager_->GetActiveDownloadItem(download_id); |
722 if (!download) | 724 if (!download) |
723 return; | 725 return; |
724 | 726 |
725 GetReservedPath( | 727 GetReservedPath( |
726 *download, suggested_path, download_prefs_->download_path(), | 728 *download, suggested_path, download_prefs_->download_path(), |
727 !is_forced_path, | 729 !is_forced_path, |
728 base::Bind(&ChromeDownloadManagerDelegate::OnPathReservationAvailable, | 730 base::Bind(&ChromeDownloadManagerDelegate::OnPathReservationAvailable, |
729 this, download->GetId(), should_prompt, danger_type)); | 731 this, download->GetId(), should_prompt, danger_type)); |
730 } | 732 } |
731 #endif | 733 #endif |
732 | 734 |
733 void ChromeDownloadManagerDelegate::OnPathReservationAvailable( | 735 void ChromeDownloadManagerDelegate::OnPathReservationAvailable( |
734 int32 download_id, | 736 int32 download_id, |
735 bool should_prompt, | 737 bool should_prompt, |
736 content::DownloadDangerType danger_type, | 738 content::DownloadDangerType danger_type, |
737 const FilePath& target_path, | 739 const FilePath& reserved_path, |
738 bool target_path_verified) { | 740 bool reserved_path_verified) { |
739 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 741 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
740 DownloadItem* download = | 742 DownloadItem* download = |
741 download_manager_->GetActiveDownloadItem(download_id); | 743 download_manager_->GetActiveDownloadItem(download_id); |
742 if (!download) | 744 if (!download) |
743 return; | 745 return; |
744 DownloadItem::TargetDisposition disposition; | 746 if (should_prompt || !reserved_path_verified) { |
745 // If the target path could not be verified then the path was non-existant, | 747 // If the target path could not be verified then the path was non-existant, |
746 // non writeable or could not be uniquified. Prompt the user. | 748 // non writeable or could not be uniquified. Prompt the user. |
747 if (should_prompt || !target_path_verified) | 749 ChooseDownloadPath( |
748 disposition = DownloadItem::TARGET_DISPOSITION_PROMPT; | 750 download, reserved_path, |
749 else | 751 base::Bind(&ChromeDownloadManagerDelegate::OnTargetPathAvailable, |
750 disposition = DownloadItem::TARGET_DISPOSITION_OVERWRITE; | 752 this, download_id, DownloadItem::TARGET_DISPOSITION_PROMPT, |
751 download->OnTargetPathDetermined(target_path, disposition, danger_type); | 753 danger_type)); |
752 download_manager_->RestartDownload(download_id); | 754 } else { |
| 755 OnTargetPathAvailable(download_id, |
| 756 DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 757 danger_type, reserved_path); |
| 758 } |
| 759 } |
| 760 |
| 761 void ChromeDownloadManagerDelegate::OnTargetPathAvailable( |
| 762 int32 download_id, |
| 763 DownloadItem::TargetDisposition disposition, |
| 764 content::DownloadDangerType danger_type, |
| 765 const FilePath& target_path) { |
| 766 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 767 DownloadItem* download = |
| 768 download_manager_->GetActiveDownloadItem(download_id); |
| 769 if (!download) |
| 770 return; |
| 771 |
| 772 // If |target_path| is empty, then that means that the user wants to cancel |
| 773 // the download. |
| 774 if (target_path.empty()) { |
| 775 DCHECK_EQ(DownloadItem::TARGET_DISPOSITION_PROMPT, disposition); |
| 776 download->Cancel(true); |
| 777 return; |
| 778 } |
| 779 |
| 780 // Retain the last directory. Exclude temporary downloads since the path |
| 781 // likely points at the location of a temporary file. |
| 782 if (disposition == DownloadItem::TARGET_DISPOSITION_PROMPT && |
| 783 !download->IsTemporary()) |
| 784 last_download_path_ = target_path.DirName(); |
| 785 |
| 786 FilePath intermediate_path = GetIntermediatePath(target_path, danger_type); |
| 787 download->OnDownloadTargetDetermined(target_path, disposition, danger_type, |
| 788 intermediate_path); |
753 } | 789 } |
754 | 790 |
755 void ChromeDownloadManagerDelegate::OnItemAddedToPersistentStore( | 791 void ChromeDownloadManagerDelegate::OnItemAddedToPersistentStore( |
756 int32 download_id, int64 db_handle) { | 792 int32 download_id, int64 db_handle) { |
757 // It's not immediately obvious, but HistoryBackend::CreateDownload() can | 793 // It's not immediately obvious, but HistoryBackend::CreateDownload() can |
758 // call this function with an invalid |db_handle|. For instance, this can | 794 // call this function with an invalid |db_handle|. For instance, this can |
759 // happen when the history database is offline. We cannot have multiple | 795 // happen when the history database is offline. We cannot have multiple |
760 // DownloadItems with the same invalid db_handle, so we need to assign a | 796 // DownloadItems with the same invalid db_handle, so we need to assign a |
761 // unique |db_handle| here. | 797 // unique |db_handle| here. |
762 if (db_handle == DownloadItem::kUninitializedHandle) | 798 if (db_handle == DownloadItem::kUninitializedHandle) |
763 db_handle = download_history_->GetNextFakeDbHandle(); | 799 db_handle = download_history_->GetNextFakeDbHandle(); |
764 download_manager_->OnItemAddedToPersistentStore(download_id, db_handle); | 800 download_manager_->OnItemAddedToPersistentStore(download_id, db_handle); |
765 } | 801 } |
| 802 |
| 803 void ChromeDownloadManagerDelegate::ClearTransientState() { |
| 804 last_download_path_.clear(); |
| 805 } |
OLD | NEW |