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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
51 #include "content/public/browser/download_item.h" | 51 #include "content/public/browser/download_item.h" |
52 #include "content/public/browser/download_manager.h" | 52 #include "content/public/browser/download_manager.h" |
53 #include "content/public/browser/notification_source.h" | 53 #include "content/public/browser/notification_source.h" |
54 #include "content/public/browser/page_navigator.h" | 54 #include "content/public/browser/page_navigator.h" |
55 #include "net/base/filename_util.h" | 55 #include "net/base/filename_util.h" |
56 #include "net/base/mime_util.h" | 56 #include "net/base/mime_util.h" |
57 #include "ui/base/l10n/l10n_util.h" | 57 #include "ui/base/l10n/l10n_util.h" |
58 | 58 |
59 #if BUILDFLAG(ANDROID_JAVA_UI) | 59 #if BUILDFLAG(ANDROID_JAVA_UI) |
60 #include "chrome/browser/android/download/chrome_download_manager_overwrite_info bar_delegate.h" | 60 #include "chrome/browser/android/download/chrome_download_manager_overwrite_info bar_delegate.h" |
61 #include "chrome/browser/android/download/download_controller.h" | |
62 #include "chrome/browser/android/download/download_manager_service.h" | |
61 #include "chrome/browser/infobars/infobar_service.h" | 63 #include "chrome/browser/infobars/infobar_service.h" |
62 #endif | 64 #endif |
63 | 65 |
64 #if defined(OS_CHROMEOS) | 66 #if defined(OS_CHROMEOS) |
65 #include "chrome/browser/chromeos/drive/download_handler.h" | 67 #include "chrome/browser/chromeos/drive/download_handler.h" |
66 #include "chrome/browser/chromeos/drive/file_system_util.h" | 68 #include "chrome/browser/chromeos/drive/file_system_util.h" |
67 #endif | 69 #endif |
68 | 70 |
69 #if defined(ENABLE_EXTENSIONS) | 71 #if defined(ENABLE_EXTENSIONS) |
70 #include "chrome/browser/extensions/api/downloads/downloads_api.h" | 72 #include "chrome/browser/extensions/api/downloads/downloads_api.h" |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
185 // Reason for why danger type is DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE. | 187 // Reason for why danger type is DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE. |
186 // Used by "Download.DangerousFile.Reason" UMA metric. | 188 // Used by "Download.DangerousFile.Reason" UMA metric. |
187 // Do not change the ordering or remove items. | 189 // Do not change the ordering or remove items. |
188 enum DangerousFileReason { | 190 enum DangerousFileReason { |
189 SB_NOT_AVAILABLE = 0, | 191 SB_NOT_AVAILABLE = 0, |
190 SB_RETURNS_UNKOWN = 1, | 192 SB_RETURNS_UNKOWN = 1, |
191 SB_RETURNS_SAFE = 2, | 193 SB_RETURNS_SAFE = 2, |
192 DANGEROUS_FILE_REASON_MAX | 194 DANGEROUS_FILE_REASON_MAX |
193 }; | 195 }; |
194 | 196 |
197 // On Android, Chrome wants to warn the user of file overwrites rather than | |
198 // uniquify. | |
199 #if BUILDFLAG(ANDROID_JAVA_UI) | |
200 const DownloadPathReservationTracker::FilenameConflictAction | |
201 kDefaultPlatformConflictAction = DownloadPathReservationTracker::PROMPT; | |
202 #else | |
203 const DownloadPathReservationTracker::FilenameConflictAction | |
204 kDefaultPlatformConflictAction = DownloadPathReservationTracker::UNIQUIFY; | |
205 #endif | |
206 | |
195 } // namespace | 207 } // namespace |
196 | 208 |
197 ChromeDownloadManagerDelegate::ChromeDownloadManagerDelegate(Profile* profile) | 209 ChromeDownloadManagerDelegate::ChromeDownloadManagerDelegate(Profile* profile) |
198 : profile_(profile), | 210 : profile_(profile), |
199 next_download_id_(content::DownloadItem::kInvalidId), | 211 next_download_id_(content::DownloadItem::kInvalidId), |
200 download_prefs_(new DownloadPrefs(profile)), | 212 download_prefs_(new DownloadPrefs(profile)), |
201 weak_ptr_factory_(this) { | 213 weak_ptr_factory_(this) { |
202 } | 214 } |
203 | 215 |
204 ChromeDownloadManagerDelegate::~ChromeDownloadManagerDelegate() { | 216 ChromeDownloadManagerDelegate::~ChromeDownloadManagerDelegate() { |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
270 DownloadItem* download, | 282 DownloadItem* download, |
271 const content::DownloadTargetCallback& callback) { | 283 const content::DownloadTargetCallback& callback) { |
272 DownloadTargetDeterminer::CompletionCallback target_determined_callback = | 284 DownloadTargetDeterminer::CompletionCallback target_determined_callback = |
273 base::Bind(&ChromeDownloadManagerDelegate::OnDownloadTargetDetermined, | 285 base::Bind(&ChromeDownloadManagerDelegate::OnDownloadTargetDetermined, |
274 weak_ptr_factory_.GetWeakPtr(), | 286 weak_ptr_factory_.GetWeakPtr(), |
275 download->GetId(), | 287 download->GetId(), |
276 callback); | 288 callback); |
277 DownloadTargetDeterminer::Start( | 289 DownloadTargetDeterminer::Start( |
278 download, | 290 download, |
279 GetPlatformDownloadPath(profile_, download, PLATFORM_TARGET_PATH), | 291 GetPlatformDownloadPath(profile_, download, PLATFORM_TARGET_PATH), |
280 download_prefs_.get(), | 292 kDefaultPlatformConflictAction, download_prefs_.get(), this, |
281 this, | |
282 target_determined_callback); | 293 target_determined_callback); |
283 return true; | 294 return true; |
284 } | 295 } |
285 | 296 |
286 bool ChromeDownloadManagerDelegate::ShouldOpenFileBasedOnExtension( | 297 bool ChromeDownloadManagerDelegate::ShouldOpenFileBasedOnExtension( |
287 const base::FilePath& path) { | 298 const base::FilePath& path) { |
288 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 299 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
289 if (path.Extension().empty()) | 300 if (path.Extension().empty()) |
290 return false; | 301 return false; |
291 #if defined(ENABLE_EXTENSIONS) | 302 #if defined(ENABLE_EXTENSIONS) |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
591 const base::FilePath& virtual_path, | 602 const base::FilePath& virtual_path, |
592 bool create_directory, | 603 bool create_directory, |
593 DownloadPathReservationTracker::FilenameConflictAction conflict_action, | 604 DownloadPathReservationTracker::FilenameConflictAction conflict_action, |
594 const DownloadTargetDeterminerDelegate::ReservedPathCallback& callback) { | 605 const DownloadTargetDeterminerDelegate::ReservedPathCallback& callback) { |
595 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 606 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
596 DCHECK(!virtual_path.empty()); | 607 DCHECK(!virtual_path.empty()); |
597 #if defined(OS_CHROMEOS) | 608 #if defined(OS_CHROMEOS) |
598 // TODO(asanka): Handle path reservations for virtual paths as well. | 609 // TODO(asanka): Handle path reservations for virtual paths as well. |
599 // http://crbug.com/151618 | 610 // http://crbug.com/151618 |
600 if (drive::util::IsUnderDriveMountPoint(virtual_path)) { | 611 if (drive::util::IsUnderDriveMountPoint(virtual_path)) { |
601 callback.Run(virtual_path, true); | 612 callback.Run(virtual_path, DownloadTargetResult::SUCCESS); |
602 return; | 613 return; |
603 } | 614 } |
604 #endif | 615 #endif |
605 DownloadPathReservationTracker::GetReservedPath( | 616 DownloadPathReservationTracker::GetReservedPath( |
606 download, | 617 download, |
607 virtual_path, | 618 virtual_path, |
608 download_prefs_->DownloadPath(), | 619 download_prefs_->DownloadPath(), |
609 create_directory, | 620 create_directory, |
610 conflict_action, | 621 conflict_action, |
611 callback); | 622 callback); |
612 } | 623 } |
613 | 624 |
614 void ChromeDownloadManagerDelegate::PromptUserForDownloadPath( | 625 void ChromeDownloadManagerDelegate::RequestConfirmation( |
615 DownloadItem* download, | 626 DownloadItem* download, |
616 const base::FilePath& suggested_path, | 627 const base::FilePath& suggested_path, |
628 DownloadConfirmationReason reason, | |
617 const DownloadTargetDeterminerDelegate::FileSelectedCallback& callback) { | 629 const DownloadTargetDeterminerDelegate::FileSelectedCallback& callback) { |
618 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 630 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
631 | |
619 #if BUILDFLAG(ANDROID_JAVA_UI) | 632 #if BUILDFLAG(ANDROID_JAVA_UI) |
620 chrome::android::ChromeDownloadManagerOverwriteInfoBarDelegate::Create( | 633 switch (reason) { |
621 InfoBarService::FromWebContents(download->GetWebContents()), download, | 634 case DownloadConfirmationReason::NONE: |
622 suggested_path, callback); | 635 NOTREACHED(); |
623 #else | 636 return; |
637 | |
638 case DownloadConfirmationReason::TARGET_NOT_WRITEABLE: | |
639 DownloadManagerService::OnDownloadCanceled( | |
640 download, DownloadController::CANCEL_REASON_NO_EXTERNAL_STORAGE); | |
641 callback.Run(DownloadConfirmationResult::CANCELED, base::FilePath()); | |
642 return; | |
643 | |
644 case DownloadConfirmationReason::NAME_TOO_LONG: | |
645 case DownloadConfirmationReason::TARGET_NO_SPACE: | |
svaldez
2016/10/28 17:29:35
Should this actually continue?
asanka
2016/11/07 19:50:15
This one's a bit odd in that the purpose of contin
| |
646 case DownloadConfirmationReason::SAVE_AS: | |
647 case DownloadConfirmationReason::PREFERENCE: | |
648 callback.Run(DownloadConfirmationResult::CONTINUE_WITHOUT_CONFIRMATION, | |
649 suggested_path); | |
650 return; | |
651 | |
652 case DownloadConfirmationReason::TARGET_CONFLICT: | |
653 if (download->GetWebContents()) { | |
654 chrome::android::ChromeDownloadManagerOverwriteInfoBarDelegate::Create( | |
655 InfoBarService::FromWebContents(download->GetWebContents()), | |
656 download, suggested_path, callback); | |
657 return; | |
658 } | |
659 // Fallthrough | |
660 | |
661 // If we cannot reserve the path and the WebContent is already gone, there | |
662 // is no way to prompt user for an infobar. This could happen after chrome | |
663 // gets killed, and user tries to resume a download while another app has | |
664 // created the target file (not the temporary .crdownload file). | |
665 case DownloadConfirmationReason::UNEXPECTED: | |
666 DownloadManagerService::OnDownloadCanceled( | |
667 download, | |
668 DownloadController::CANCEL_REASON_CANNOT_DETERMINE_DOWNLOAD_TARGET); | |
669 callback.Run(DownloadConfirmationResult::CANCELED, base::FilePath()); | |
670 return; | |
671 } | |
672 #else // !ANDROID_JAVA_UI | |
624 DownloadFilePicker::ShowFilePicker(download, suggested_path, callback); | 673 DownloadFilePicker::ShowFilePicker(download, suggested_path, callback); |
625 #endif | 674 #endif // !ANDROID_JAVA_UI |
626 } | 675 } |
627 | 676 |
628 void ChromeDownloadManagerDelegate::DetermineLocalPath( | 677 void ChromeDownloadManagerDelegate::DetermineLocalPath( |
629 DownloadItem* download, | 678 DownloadItem* download, |
630 const base::FilePath& virtual_path, | 679 const base::FilePath& virtual_path, |
631 const DownloadTargetDeterminerDelegate::LocalPathCallback& callback) { | 680 const DownloadTargetDeterminerDelegate::LocalPathCallback& callback) { |
632 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 681 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
633 #if defined(OS_CHROMEOS) | 682 #if defined(OS_CHROMEOS) |
634 drive::DownloadHandler* drive_download_handler = | 683 drive::DownloadHandler* drive_download_handler = |
635 drive::DownloadHandler::GetForProfile(profile_); | 684 drive::DownloadHandler::GetForProfile(profile_); |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
753 | 802 |
754 scoped_refptr<extensions::CrxInstaller> installer = | 803 scoped_refptr<extensions::CrxInstaller> installer = |
755 content::Source<extensions::CrxInstaller>(source).ptr(); | 804 content::Source<extensions::CrxInstaller>(source).ptr(); |
756 content::DownloadOpenDelayedCallback callback = | 805 content::DownloadOpenDelayedCallback callback = |
757 crx_installers_[installer.get()]; | 806 crx_installers_[installer.get()]; |
758 crx_installers_.erase(installer.get()); | 807 crx_installers_.erase(installer.get()); |
759 callback.Run(installer->did_handle_successfully()); | 808 callback.Run(installer->did_handle_successfully()); |
760 #endif | 809 #endif |
761 } | 810 } |
762 | 811 |
812 namespace { | |
813 | |
814 content::DownloadInterruptReason TargetResultToInterruptReasonAfterCompletion( | |
815 DownloadTargetResult result) { | |
816 switch (result) { | |
817 case DownloadTargetResult::SUCCESS: | |
818 return content::DOWNLOAD_INTERRUPT_REASON_NONE; | |
819 | |
820 case DownloadTargetResult::USER_CANCELED: | |
821 return content::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED; | |
822 | |
823 case DownloadTargetResult::NAME_TOO_LONG: | |
824 case DownloadTargetResult::CONFLICT: | |
825 case DownloadTargetResult::PATH_NOT_WRITEABLE: | |
826 NOTREACHED(); // These cases should've caused a confirmation prompt. | |
827 // fallthrough | |
828 | |
829 case DownloadTargetResult::UNEXPECTED: | |
830 return content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED; | |
831 } | |
832 NOTREACHED(); | |
svaldez
2016/10/28 17:29:35
Can these lines be removed so that there's a compi
asanka
2016/11/07 19:50:15
This is already the case. I.e. the switch above st
| |
833 return content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED; | |
834 } | |
835 | |
836 } // namespace | |
837 | |
763 void ChromeDownloadManagerDelegate::OnDownloadTargetDetermined( | 838 void ChromeDownloadManagerDelegate::OnDownloadTargetDetermined( |
764 int32_t download_id, | 839 int32_t download_id, |
765 const content::DownloadTargetCallback& callback, | 840 const content::DownloadTargetCallback& callback, |
766 std::unique_ptr<DownloadTargetInfo> target_info) { | 841 std::unique_ptr<DownloadTargetInfo> target_info) { |
767 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 842 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
768 DownloadItem* item = download_manager_->GetDownload(download_id); | 843 DownloadItem* item = download_manager_->GetDownload(download_id); |
769 if (item) { | 844 if (item) { |
770 if (!target_info->target_path.empty() && | 845 if (!target_info->target_path.empty() && |
771 IsOpenInBrowserPreferreredForFile(target_info->target_path) && | 846 IsOpenInBrowserPreferreredForFile(target_info->target_path) && |
772 target_info->is_filetype_handled_safely) | 847 target_info->is_filetype_handled_safely) |
773 DownloadItemModel(item).SetShouldPreferOpeningInBrowser(true); | 848 DownloadItemModel(item).SetShouldPreferOpeningInBrowser(true); |
774 | 849 |
775 #if defined(OS_LINUX) || defined(OS_CHROMEOS) | 850 #if defined(OS_LINUX) || defined(OS_CHROMEOS) |
776 if (item->GetOriginalMimeType() == "application/x-x509-user-cert") | 851 if (item->GetOriginalMimeType() == "application/x-x509-user-cert") |
777 DownloadItemModel(item).SetShouldPreferOpeningInBrowser(true); | 852 DownloadItemModel(item).SetShouldPreferOpeningInBrowser(true); |
778 #endif | 853 #endif |
779 | 854 |
780 DownloadItemModel(item).SetDangerLevel(target_info->danger_level); | 855 DownloadItemModel(item).SetDangerLevel(target_info->danger_level); |
781 } | 856 } |
782 callback.Run(target_info->target_path, | 857 callback.Run( |
783 target_info->target_disposition, | 858 target_info->target_path, target_info->target_disposition, |
784 target_info->danger_type, | 859 target_info->danger_type, target_info->intermediate_path, |
785 target_info->intermediate_path); | 860 TargetResultToInterruptReasonAfterCompletion(target_info->result)); |
786 } | 861 } |
787 | 862 |
788 bool ChromeDownloadManagerDelegate::IsOpenInBrowserPreferreredForFile( | 863 bool ChromeDownloadManagerDelegate::IsOpenInBrowserPreferreredForFile( |
789 const base::FilePath& path) { | 864 const base::FilePath& path) { |
790 #if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_MACOSX) | 865 #if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_MACOSX) |
791 if (path.MatchesExtension(FILE_PATH_LITERAL(".pdf"))) { | 866 if (path.MatchesExtension(FILE_PATH_LITERAL(".pdf"))) { |
792 return !download_prefs_->ShouldOpenPdfInSystemReader(); | 867 return !download_prefs_->ShouldOpenPdfInSystemReader(); |
793 } | 868 } |
794 #endif | 869 #endif |
795 | 870 |
(...skipping 11 matching lines...) Expand all Loading... | |
807 path.MatchesExtension(FILE_PATH_LITERAL(".xht")) || | 882 path.MatchesExtension(FILE_PATH_LITERAL(".xht")) || |
808 path.MatchesExtension(FILE_PATH_LITERAL(".xhtm")) || | 883 path.MatchesExtension(FILE_PATH_LITERAL(".xhtm")) || |
809 path.MatchesExtension(FILE_PATH_LITERAL(".xhtml")) || | 884 path.MatchesExtension(FILE_PATH_LITERAL(".xhtml")) || |
810 path.MatchesExtension(FILE_PATH_LITERAL(".xsl")) || | 885 path.MatchesExtension(FILE_PATH_LITERAL(".xsl")) || |
811 path.MatchesExtension(FILE_PATH_LITERAL(".xslt"))) { | 886 path.MatchesExtension(FILE_PATH_LITERAL(".xslt"))) { |
812 return true; | 887 return true; |
813 } | 888 } |
814 #endif | 889 #endif |
815 return false; | 890 return false; |
816 } | 891 } |
OLD | NEW |