| 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 4c6d779e58ac508d9c68cf58a43d06c7a2914e29..f22aa6f303413f17f1dccb3e5b6fcab9c93335fb 100644
|
| --- a/chrome/browser/download/chrome_download_manager_delegate.cc
|
| +++ b/chrome/browser/download/chrome_download_manager_delegate.cc
|
| @@ -24,6 +24,8 @@
|
| #include "chrome/browser/download/download_history.h"
|
| #include "chrome/browser/download/download_path_reservation_tracker.h"
|
| #include "chrome/browser/download/download_prefs.h"
|
| +#include "chrome/browser/download/download_service.h"
|
| +#include "chrome/browser/download/download_service_factory.h"
|
| #include "chrome/browser/download/download_status_updater.h"
|
| #include "chrome/browser/download/download_util.h"
|
| #include "chrome/browser/download/save_package_file_picker.h"
|
| @@ -208,17 +210,10 @@ ChromeDownloadManagerDelegate::~ChromeDownloadManagerDelegate() {
|
|
|
| void ChromeDownloadManagerDelegate::SetDownloadManager(DownloadManager* dm) {
|
| download_manager_ = dm;
|
| -#if !defined(OS_ANDROID)
|
| - extension_event_router_.reset(new ExtensionDownloadsEventRouter(
|
| - profile_, download_manager_));
|
| -#endif
|
| }
|
|
|
| void ChromeDownloadManagerDelegate::Shutdown() {
|
| download_prefs_.reset();
|
| -#if !defined(OS_ANDROID)
|
| - extension_event_router_.reset();
|
| -#endif
|
| }
|
|
|
| DownloadId ChromeDownloadManagerDelegate::GetNextId() {
|
| @@ -630,6 +625,22 @@ void ChromeDownloadManagerDelegate::Observe(
|
| callback.Run(installer->did_handle_successfully());
|
| }
|
|
|
| +struct ChromeDownloadManagerDelegate::ContinueFilenameDeterminationInfo {
|
| + ContinueFilenameDeterminationInfo();
|
| + ~ContinueFilenameDeterminationInfo();
|
| +
|
| + int32 download_id;
|
| + content::DownloadTargetCallback callback;
|
| + content::DownloadDangerType danger_type;
|
| + bool visited_referrer_before;
|
| + bool should_prompt;
|
| +};
|
| +
|
| +ChromeDownloadManagerDelegate::ContinueFilenameDeterminationInfo::
|
| + ContinueFilenameDeterminationInfo() {}
|
| +ChromeDownloadManagerDelegate::ContinueFilenameDeterminationInfo::
|
| + ~ContinueFilenameDeterminationInfo() {}
|
| +
|
| void ChromeDownloadManagerDelegate::CheckVisitedReferrerBeforeDone(
|
| int32 download_id,
|
| const content::DownloadTargetCallback& callback,
|
| @@ -645,12 +656,12 @@ void ChromeDownloadManagerDelegate::CheckVisitedReferrerBeforeDone(
|
| bool should_prompt = (download->GetTargetDisposition() ==
|
| DownloadItem::TARGET_DISPOSITION_PROMPT);
|
| bool is_forced_path = !download->GetForcedFilePath().empty();
|
| + base::FilePath generated_name;
|
| base::FilePath suggested_path;
|
|
|
| // Check whether this download is for an extension install or not.
|
| // Allow extensions to be explicitly saved.
|
| if (!is_forced_path) {
|
| - base::FilePath generated_name;
|
| GenerateFileNameFromRequest(
|
| *download,
|
| &generated_name,
|
| @@ -687,6 +698,78 @@ void ChromeDownloadManagerDelegate::CheckVisitedReferrerBeforeDone(
|
| suggested_path = download->GetForcedFilePath();
|
| }
|
|
|
| + ContinueFilenameDeterminationInfo continue_info;
|
| + continue_info.download_id = download_id;
|
| + continue_info.callback = callback;
|
| + continue_info.danger_type = danger_type;
|
| + continue_info.visited_referrer_before = visited_referrer_before;
|
| + continue_info.should_prompt = should_prompt;
|
| +
|
| + base::Closure filename_determined = base::Bind(
|
| + &ChromeDownloadManagerDelegate::ContinueDeterminingFilename,
|
| + this, continue_info, suggested_path, is_forced_path);
|
| +#if defined(OS_ANDROID)
|
| + filename_determined.Run();
|
| +#else
|
| + if (is_forced_path ||
|
| + !DownloadServiceFactory::GetForProfile(profile_)
|
| + ->GetExtensionEventRouter()) {
|
| + filename_determined.Run();
|
| + } else {
|
| + DownloadService* service = DownloadServiceFactory::GetForProfile(profile_);
|
| + ExtensionDownloadsEventRouter* router = service->GetExtensionEventRouter();
|
| + ExtensionDownloadsEventRouter::FilenameChangedCallback overriding =
|
| + base::Bind(&ChromeDownloadManagerDelegate::OnExtensionOverridingFilename,
|
| + this, continue_info);
|
| + router->OnDeterminingFilename(
|
| + download, generated_name, filename_determined, overriding);
|
| + }
|
| +#endif
|
| +}
|
| +
|
| +void ChromeDownloadManagerDelegate::OnExtensionOverridingFilename(
|
| + const ContinueFilenameDeterminationInfo& continue_info,
|
| + const base::FilePath& changed_filename,
|
| + bool overwrite) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + DownloadItem* download =
|
| + download_manager_->GetDownload(continue_info.download_id);
|
| + if (!download || (download->GetState() != DownloadItem::IN_PROGRESS))
|
| + return;
|
| + // If an extension overrides the filename, then the target directory will be
|
| + // forced to download_prefs_->DownloadPath() since extensions cannot place
|
| + // downloaded files anywhere except there. This prevents subdirectories from
|
| + // accumulating: if an extension is allowed to say that a file should go in
|
| + // last_download_path/music/foo.mp3, then last_download_path will accumulate
|
| + // the subdirectory /music/ so that the next download may end up in
|
| + // Downloads/music/music/music/bar.mp3.
|
| + base::FilePath temp_filename(download_prefs_->DownloadPath().Append(
|
| + changed_filename).NormalizePathSeparators());
|
| + // Do not pass a mime type to GenerateSafeFileName so that it does not force
|
| + // the filename to have an extension if the (chrome) extension does not
|
| + // suggest it.
|
| + net::GenerateSafeFileName(std::string(), false, &temp_filename);
|
| + // If |is_forced_path| were true, then extensions would not have been
|
| + // consulted, so use |overwrite| instead of |is_forced_path|. This does NOT
|
| + // set DownloadItem::GetForcedFilePath()!
|
| + ContinueDeterminingFilename(continue_info, temp_filename, overwrite);
|
| +}
|
| +
|
| +void ChromeDownloadManagerDelegate::ContinueDeterminingFilename(
|
| + const ContinueFilenameDeterminationInfo& continue_info,
|
| + const base::FilePath& suggested_path,
|
| + bool is_forced_path) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + int32 download_id = continue_info.download_id;
|
| + const content::DownloadTargetCallback& callback = continue_info.callback;
|
| + content::DownloadDangerType danger_type = continue_info.danger_type;
|
| + bool visited_referrer_before = continue_info.visited_referrer_before;
|
| + bool should_prompt = continue_info.should_prompt;
|
| + DownloadItem* download =
|
| + download_manager_->GetDownload(download_id);
|
| + if (!download || (download->GetState() != DownloadItem::IN_PROGRESS))
|
| + return;
|
| +
|
| // If the download hasn't already been marked dangerous (could be
|
| // DANGEROUS_URL), check if it is a dangerous file.
|
| if (danger_type == content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) {
|
|
|