Chromium Code Reviews| 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 |