| 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 |