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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 #include "content/public/browser/notification_source.h" | 52 #include "content/public/browser/notification_source.h" |
53 #include "content/public/browser/page_navigator.h" | 53 #include "content/public/browser/page_navigator.h" |
54 #include "extensions/features/features.h" | 54 #include "extensions/features/features.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 "ppapi/features/features.h" | 57 #include "ppapi/features/features.h" |
58 #include "ui/base/l10n/l10n_util.h" | 58 #include "ui/base/l10n/l10n_util.h" |
59 | 59 |
60 #if defined(OS_ANDROID) | 60 #if defined(OS_ANDROID) |
61 #include "chrome/browser/android/download/chrome_duplicate_download_infobar_dele
gate.h" | 61 #include "chrome/browser/android/download/chrome_duplicate_download_infobar_dele
gate.h" |
| 62 #include "chrome/browser/android/download/download_controller.h" |
| 63 #include "chrome/browser/android/download/download_manager_service.h" |
62 #include "chrome/browser/infobars/infobar_service.h" | 64 #include "chrome/browser/infobars/infobar_service.h" |
63 #endif | 65 #endif |
64 | 66 |
65 #if defined(OS_CHROMEOS) | 67 #if defined(OS_CHROMEOS) |
66 #include "chrome/browser/chromeos/drive/download_handler.h" | 68 #include "chrome/browser/chromeos/drive/download_handler.h" |
67 #include "chrome/browser/chromeos/drive/file_system_util.h" | 69 #include "chrome/browser/chromeos/drive/file_system_util.h" |
68 #endif | 70 #endif |
69 | 71 |
70 #if BUILDFLAG(ENABLE_EXTENSIONS) | 72 #if BUILDFLAG(ENABLE_EXTENSIONS) |
71 #include "chrome/browser/extensions/api/downloads/downloads_api.h" | 73 #include "chrome/browser/extensions/api/downloads/downloads_api.h" |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 // Reason for why danger type is DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE. | 188 // Reason for why danger type is DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE. |
187 // Used by "Download.DangerousFile.Reason" UMA metric. | 189 // Used by "Download.DangerousFile.Reason" UMA metric. |
188 // Do not change the ordering or remove items. | 190 // Do not change the ordering or remove items. |
189 enum DangerousFileReason { | 191 enum DangerousFileReason { |
190 SB_NOT_AVAILABLE = 0, | 192 SB_NOT_AVAILABLE = 0, |
191 SB_RETURNS_UNKOWN = 1, | 193 SB_RETURNS_UNKOWN = 1, |
192 SB_RETURNS_SAFE = 2, | 194 SB_RETURNS_SAFE = 2, |
193 DANGEROUS_FILE_REASON_MAX | 195 DANGEROUS_FILE_REASON_MAX |
194 }; | 196 }; |
195 | 197 |
| 198 // On Android, Chrome wants to warn the user of file overwrites rather than |
| 199 // uniquify. |
| 200 #if defined(OS_ANDROID) |
| 201 const DownloadPathReservationTracker::FilenameConflictAction |
| 202 kDefaultPlatformConflictAction = DownloadPathReservationTracker::PROMPT; |
| 203 #else |
| 204 const DownloadPathReservationTracker::FilenameConflictAction |
| 205 kDefaultPlatformConflictAction = DownloadPathReservationTracker::UNIQUIFY; |
| 206 #endif |
| 207 |
196 } // namespace | 208 } // namespace |
197 | 209 |
198 ChromeDownloadManagerDelegate::ChromeDownloadManagerDelegate(Profile* profile) | 210 ChromeDownloadManagerDelegate::ChromeDownloadManagerDelegate(Profile* profile) |
199 : profile_(profile), | 211 : profile_(profile), |
200 next_download_id_(content::DownloadItem::kInvalidId), | 212 next_download_id_(content::DownloadItem::kInvalidId), |
201 download_prefs_(new DownloadPrefs(profile)), | 213 download_prefs_(new DownloadPrefs(profile)), |
202 weak_ptr_factory_(this) { | 214 weak_ptr_factory_(this) { |
203 } | 215 } |
204 | 216 |
205 ChromeDownloadManagerDelegate::~ChromeDownloadManagerDelegate() { | 217 ChromeDownloadManagerDelegate::~ChromeDownloadManagerDelegate() { |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 DownloadItem* download, | 283 DownloadItem* download, |
272 const content::DownloadTargetCallback& callback) { | 284 const content::DownloadTargetCallback& callback) { |
273 DownloadTargetDeterminer::CompletionCallback target_determined_callback = | 285 DownloadTargetDeterminer::CompletionCallback target_determined_callback = |
274 base::Bind(&ChromeDownloadManagerDelegate::OnDownloadTargetDetermined, | 286 base::Bind(&ChromeDownloadManagerDelegate::OnDownloadTargetDetermined, |
275 weak_ptr_factory_.GetWeakPtr(), | 287 weak_ptr_factory_.GetWeakPtr(), |
276 download->GetId(), | 288 download->GetId(), |
277 callback); | 289 callback); |
278 DownloadTargetDeterminer::Start( | 290 DownloadTargetDeterminer::Start( |
279 download, | 291 download, |
280 GetPlatformDownloadPath(profile_, download, PLATFORM_TARGET_PATH), | 292 GetPlatformDownloadPath(profile_, download, PLATFORM_TARGET_PATH), |
281 download_prefs_.get(), | 293 kDefaultPlatformConflictAction, download_prefs_.get(), this, |
282 this, | |
283 target_determined_callback); | 294 target_determined_callback); |
284 return true; | 295 return true; |
285 } | 296 } |
286 | 297 |
287 bool ChromeDownloadManagerDelegate::ShouldOpenFileBasedOnExtension( | 298 bool ChromeDownloadManagerDelegate::ShouldOpenFileBasedOnExtension( |
288 const base::FilePath& path) { | 299 const base::FilePath& path) { |
289 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 300 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
290 if (path.Extension().empty()) | 301 if (path.Extension().empty()) |
291 return false; | 302 return false; |
292 #if BUILDFLAG(ENABLE_EXTENSIONS) | 303 #if BUILDFLAG(ENABLE_EXTENSIONS) |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
592 const base::FilePath& virtual_path, | 603 const base::FilePath& virtual_path, |
593 bool create_directory, | 604 bool create_directory, |
594 DownloadPathReservationTracker::FilenameConflictAction conflict_action, | 605 DownloadPathReservationTracker::FilenameConflictAction conflict_action, |
595 const DownloadTargetDeterminerDelegate::ReservedPathCallback& callback) { | 606 const DownloadTargetDeterminerDelegate::ReservedPathCallback& callback) { |
596 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 607 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
597 DCHECK(!virtual_path.empty()); | 608 DCHECK(!virtual_path.empty()); |
598 #if defined(OS_CHROMEOS) | 609 #if defined(OS_CHROMEOS) |
599 // TODO(asanka): Handle path reservations for virtual paths as well. | 610 // TODO(asanka): Handle path reservations for virtual paths as well. |
600 // http://crbug.com/151618 | 611 // http://crbug.com/151618 |
601 if (drive::util::IsUnderDriveMountPoint(virtual_path)) { | 612 if (drive::util::IsUnderDriveMountPoint(virtual_path)) { |
602 callback.Run(virtual_path, true); | 613 callback.Run(PathValidationResult::SUCCESS, virtual_path); |
603 return; | 614 return; |
604 } | 615 } |
605 #endif | 616 #endif |
606 DownloadPathReservationTracker::GetReservedPath( | 617 DownloadPathReservationTracker::GetReservedPath( |
607 download, | 618 download, |
608 virtual_path, | 619 virtual_path, |
609 download_prefs_->DownloadPath(), | 620 download_prefs_->DownloadPath(), |
610 create_directory, | 621 create_directory, |
611 conflict_action, | 622 conflict_action, |
612 callback); | 623 callback); |
613 } | 624 } |
614 | 625 |
615 void ChromeDownloadManagerDelegate::PromptUserForDownloadPath( | 626 void ChromeDownloadManagerDelegate::RequestConfirmation( |
616 DownloadItem* download, | 627 DownloadItem* download, |
617 const base::FilePath& suggested_path, | 628 const base::FilePath& suggested_path, |
618 const DownloadTargetDeterminerDelegate::FileSelectedCallback& callback) { | 629 DownloadConfirmationReason reason, |
| 630 const DownloadTargetDeterminerDelegate::ConfirmationCallback& callback) { |
619 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 631 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
620 #if defined(OS_ANDROID) | 632 #if defined(OS_ANDROID) |
621 content::WebContents* web_contents = download->GetWebContents(); | 633 switch (reason) { |
622 if (!web_contents) { | 634 case DownloadConfirmationReason::NONE: |
623 callback.Run(base::FilePath()); | 635 NOTREACHED(); |
624 return; | 636 return; |
| 637 |
| 638 case DownloadConfirmationReason::TARGET_PATH_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: |
| 646 // These are errors. But rather than cancel the download we are going to |
| 647 // continue with the current path so that the download will get |
| 648 // interrupted again. |
| 649 // |
| 650 // Ideally we'd allow the user to try another location, but on Android, |
| 651 // the user doesn't have much of a choice (currently). So we skip the |
| 652 // prompt and try the same location. |
| 653 |
| 654 case DownloadConfirmationReason::SAVE_AS: |
| 655 case DownloadConfirmationReason::PREFERENCE: |
| 656 callback.Run(DownloadConfirmationResult::CONTINUE_WITHOUT_CONFIRMATION, |
| 657 suggested_path); |
| 658 return; |
| 659 |
| 660 case DownloadConfirmationReason::TARGET_CONFLICT: |
| 661 if (download->GetWebContents()) { |
| 662 chrome::android::ChromeDuplicateDownloadInfoBarDelegate::Create( |
| 663 InfoBarService::FromWebContents(download->GetWebContents()), |
| 664 download, suggested_path, callback); |
| 665 } |
| 666 // Fallthrough |
| 667 |
| 668 // If we cannot reserve the path and the WebContent is already gone, there |
| 669 // is no way to prompt user for an infobar. This could happen after chrome |
| 670 // gets killed, and user tries to resume a download while another app has |
| 671 // created the target file (not the temporary .crdownload file). |
| 672 case DownloadConfirmationReason::UNEXPECTED: |
| 673 DownloadManagerService::OnDownloadCanceled( |
| 674 download, |
| 675 DownloadController::CANCEL_REASON_CANNOT_DETERMINE_DOWNLOAD_TARGET); |
| 676 callback.Run(DownloadConfirmationResult::CANCELED, base::FilePath()); |
| 677 return; |
625 } | 678 } |
626 chrome::android::ChromeDuplicateDownloadInfoBarDelegate::Create( | 679 #else // !OS_ANDROID |
627 InfoBarService::FromWebContents(web_contents), download, | 680 // Desktop Chrome displays a file picker for all confirmation needs. We can do |
628 suggested_path, callback); | 681 // better. |
629 #else | |
630 DownloadFilePicker::ShowFilePicker(download, suggested_path, callback); | 682 DownloadFilePicker::ShowFilePicker(download, suggested_path, callback); |
631 #endif | 683 #endif // !OS_ANDROID |
632 } | 684 } |
633 | 685 |
634 void ChromeDownloadManagerDelegate::DetermineLocalPath( | 686 void ChromeDownloadManagerDelegate::DetermineLocalPath( |
635 DownloadItem* download, | 687 DownloadItem* download, |
636 const base::FilePath& virtual_path, | 688 const base::FilePath& virtual_path, |
637 const DownloadTargetDeterminerDelegate::LocalPathCallback& callback) { | 689 const DownloadTargetDeterminerDelegate::LocalPathCallback& callback) { |
638 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 690 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
639 #if defined(OS_CHROMEOS) | 691 #if defined(OS_CHROMEOS) |
640 drive::DownloadHandler* drive_download_handler = | 692 drive::DownloadHandler* drive_download_handler = |
641 drive::DownloadHandler::GetForProfile(profile_); | 693 drive::DownloadHandler::GetForProfile(profile_); |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
777 target_info->is_filetype_handled_safely) | 829 target_info->is_filetype_handled_safely) |
778 DownloadItemModel(item).SetShouldPreferOpeningInBrowser(true); | 830 DownloadItemModel(item).SetShouldPreferOpeningInBrowser(true); |
779 | 831 |
780 #if defined(OS_LINUX) || defined(OS_CHROMEOS) | 832 #if defined(OS_LINUX) || defined(OS_CHROMEOS) |
781 if (item->GetOriginalMimeType() == "application/x-x509-user-cert") | 833 if (item->GetOriginalMimeType() == "application/x-x509-user-cert") |
782 DownloadItemModel(item).SetShouldPreferOpeningInBrowser(true); | 834 DownloadItemModel(item).SetShouldPreferOpeningInBrowser(true); |
783 #endif | 835 #endif |
784 | 836 |
785 DownloadItemModel(item).SetDangerLevel(target_info->danger_level); | 837 DownloadItemModel(item).SetDangerLevel(target_info->danger_level); |
786 } | 838 } |
787 callback.Run(target_info->target_path, | 839 callback.Run(target_info->target_path, target_info->target_disposition, |
788 target_info->target_disposition, | 840 target_info->danger_type, target_info->intermediate_path, |
789 target_info->danger_type, | 841 target_info->result); |
790 target_info->intermediate_path); | |
791 } | 842 } |
792 | 843 |
793 bool ChromeDownloadManagerDelegate::IsOpenInBrowserPreferreredForFile( | 844 bool ChromeDownloadManagerDelegate::IsOpenInBrowserPreferreredForFile( |
794 const base::FilePath& path) { | 845 const base::FilePath& path) { |
795 #if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_MACOSX) | 846 #if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_MACOSX) |
796 if (path.MatchesExtension(FILE_PATH_LITERAL(".pdf"))) { | 847 if (path.MatchesExtension(FILE_PATH_LITERAL(".pdf"))) { |
797 return !download_prefs_->ShouldOpenPdfInSystemReader(); | 848 return !download_prefs_->ShouldOpenPdfInSystemReader(); |
798 } | 849 } |
799 #endif | 850 #endif |
800 | 851 |
(...skipping 11 matching lines...) Expand all Loading... |
812 path.MatchesExtension(FILE_PATH_LITERAL(".xht")) || | 863 path.MatchesExtension(FILE_PATH_LITERAL(".xht")) || |
813 path.MatchesExtension(FILE_PATH_LITERAL(".xhtm")) || | 864 path.MatchesExtension(FILE_PATH_LITERAL(".xhtm")) || |
814 path.MatchesExtension(FILE_PATH_LITERAL(".xhtml")) || | 865 path.MatchesExtension(FILE_PATH_LITERAL(".xhtml")) || |
815 path.MatchesExtension(FILE_PATH_LITERAL(".xsl")) || | 866 path.MatchesExtension(FILE_PATH_LITERAL(".xsl")) || |
816 path.MatchesExtension(FILE_PATH_LITERAL(".xslt"))) { | 867 path.MatchesExtension(FILE_PATH_LITERAL(".xslt"))) { |
817 return true; | 868 return true; |
818 } | 869 } |
819 #endif | 870 #endif |
820 return false; | 871 return false; |
821 } | 872 } |
OLD | NEW |