| Index: chrome/browser/download/chrome_download_manager_delegate.cc
|
| diff --git a/chrome/browser/download/chrome_download_manager_delegate.cc b/chrome/browser/download/chrome_download_manager_delegate.cc
|
| index ed4157b47e5b02e224b4cfc51ddd8dd01c350957..b292590d2916d7db682f2a8612c28dce43e0b46b 100644
|
| --- a/chrome/browser/download/chrome_download_manager_delegate.cc
|
| +++ b/chrome/browser/download/chrome_download_manager_delegate.cc
|
| @@ -59,6 +59,8 @@
|
|
|
| #if defined(OS_ANDROID)
|
| #include "chrome/browser/android/download/chrome_duplicate_download_infobar_delegate.h"
|
| +#include "chrome/browser/android/download/download_controller.h"
|
| +#include "chrome/browser/android/download/download_manager_service.h"
|
| #include "chrome/browser/infobars/infobar_service.h"
|
| #endif
|
|
|
| @@ -193,6 +195,16 @@ enum DangerousFileReason {
|
| DANGEROUS_FILE_REASON_MAX
|
| };
|
|
|
| +// On Android, Chrome wants to warn the user of file overwrites rather than
|
| +// uniquify.
|
| +#if defined(OS_ANDROID)
|
| +const DownloadPathReservationTracker::FilenameConflictAction
|
| + kDefaultPlatformConflictAction = DownloadPathReservationTracker::PROMPT;
|
| +#else
|
| +const DownloadPathReservationTracker::FilenameConflictAction
|
| + kDefaultPlatformConflictAction = DownloadPathReservationTracker::UNIQUIFY;
|
| +#endif
|
| +
|
| } // namespace
|
|
|
| ChromeDownloadManagerDelegate::ChromeDownloadManagerDelegate(Profile* profile)
|
| @@ -278,8 +290,7 @@ bool ChromeDownloadManagerDelegate::DetermineDownloadTarget(
|
| DownloadTargetDeterminer::Start(
|
| download,
|
| GetPlatformDownloadPath(profile_, download, PLATFORM_TARGET_PATH),
|
| - download_prefs_.get(),
|
| - this,
|
| + kDefaultPlatformConflictAction, download_prefs_.get(), this,
|
| target_determined_callback);
|
| return true;
|
| }
|
| @@ -599,7 +610,7 @@ void ChromeDownloadManagerDelegate::ReserveVirtualPath(
|
| // TODO(asanka): Handle path reservations for virtual paths as well.
|
| // http://crbug.com/151618
|
| if (drive::util::IsUnderDriveMountPoint(virtual_path)) {
|
| - callback.Run(virtual_path, true);
|
| + callback.Run(PathValidationResult::SUCCESS, virtual_path);
|
| return;
|
| }
|
| #endif
|
| @@ -612,23 +623,64 @@ void ChromeDownloadManagerDelegate::ReserveVirtualPath(
|
| callback);
|
| }
|
|
|
| -void ChromeDownloadManagerDelegate::PromptUserForDownloadPath(
|
| +void ChromeDownloadManagerDelegate::RequestConfirmation(
|
| DownloadItem* download,
|
| const base::FilePath& suggested_path,
|
| - const DownloadTargetDeterminerDelegate::FileSelectedCallback& callback) {
|
| + DownloadConfirmationReason reason,
|
| + const DownloadTargetDeterminerDelegate::ConfirmationCallback& callback) {
|
| DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| #if defined(OS_ANDROID)
|
| - content::WebContents* web_contents = download->GetWebContents();
|
| - if (!web_contents) {
|
| - callback.Run(base::FilePath());
|
| - return;
|
| + switch (reason) {
|
| + case DownloadConfirmationReason::NONE:
|
| + NOTREACHED();
|
| + return;
|
| +
|
| + case DownloadConfirmationReason::TARGET_PATH_NOT_WRITEABLE:
|
| + DownloadManagerService::OnDownloadCanceled(
|
| + download, DownloadController::CANCEL_REASON_NO_EXTERNAL_STORAGE);
|
| + callback.Run(DownloadConfirmationResult::CANCELED, base::FilePath());
|
| + return;
|
| +
|
| + case DownloadConfirmationReason::NAME_TOO_LONG:
|
| + case DownloadConfirmationReason::TARGET_NO_SPACE:
|
| + // These are errors. But rather than cancel the download we are going to
|
| + // continue with the current path so that the download will get
|
| + // interrupted again.
|
| + //
|
| + // Ideally we'd allow the user to try another location, but on Android,
|
| + // the user doesn't have much of a choice (currently). So we skip the
|
| + // prompt and try the same location.
|
| +
|
| + case DownloadConfirmationReason::SAVE_AS:
|
| + case DownloadConfirmationReason::PREFERENCE:
|
| + callback.Run(DownloadConfirmationResult::CONTINUE_WITHOUT_CONFIRMATION,
|
| + suggested_path);
|
| + return;
|
| +
|
| + case DownloadConfirmationReason::TARGET_CONFLICT:
|
| + if (download->GetWebContents()) {
|
| + chrome::android::ChromeDuplicateDownloadInfoBarDelegate::Create(
|
| + InfoBarService::FromWebContents(download->GetWebContents()),
|
| + download, suggested_path, callback);
|
| + }
|
| + // Fallthrough
|
| +
|
| + // If we cannot reserve the path and the WebContent is already gone, there
|
| + // is no way to prompt user for an infobar. This could happen after chrome
|
| + // gets killed, and user tries to resume a download while another app has
|
| + // created the target file (not the temporary .crdownload file).
|
| + case DownloadConfirmationReason::UNEXPECTED:
|
| + DownloadManagerService::OnDownloadCanceled(
|
| + download,
|
| + DownloadController::CANCEL_REASON_CANNOT_DETERMINE_DOWNLOAD_TARGET);
|
| + callback.Run(DownloadConfirmationResult::CANCELED, base::FilePath());
|
| + return;
|
| }
|
| - chrome::android::ChromeDuplicateDownloadInfoBarDelegate::Create(
|
| - InfoBarService::FromWebContents(web_contents), download,
|
| - suggested_path, callback);
|
| -#else
|
| +#else // !OS_ANDROID
|
| + // Desktop Chrome displays a file picker for all confirmation needs. We can do
|
| + // better.
|
| DownloadFilePicker::ShowFilePicker(download, suggested_path, callback);
|
| -#endif
|
| +#endif // !OS_ANDROID
|
| }
|
|
|
| void ChromeDownloadManagerDelegate::DetermineLocalPath(
|
| @@ -784,10 +836,9 @@ void ChromeDownloadManagerDelegate::OnDownloadTargetDetermined(
|
|
|
| DownloadItemModel(item).SetDangerLevel(target_info->danger_level);
|
| }
|
| - callback.Run(target_info->target_path,
|
| - target_info->target_disposition,
|
| - target_info->danger_type,
|
| - target_info->intermediate_path);
|
| + callback.Run(target_info->target_path, target_info->target_disposition,
|
| + target_info->danger_type, target_info->intermediate_path,
|
| + target_info->result);
|
| }
|
|
|
| bool ChromeDownloadManagerDelegate::IsOpenInBrowserPreferreredForFile(
|
|
|