Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2815)

Unified Diff: chrome/browser/download/chrome_download_manager_delegate.cc

Issue 11574006: Implement chrome.downloads.onDeterminingFilename() (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: @r183850 Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 d35309ad74ea7a0979c8a8c79d588071dbcb90c7..1b5133f05993a090ec13afe476aac93f057d83cc 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() {
@@ -621,6 +616,22 @@ void ChromeDownloadManagerDelegate::Observe(
callback.Run(installer->did_handle_successfully());
}
+struct ChromeDownloadManagerDelegate::ContinueFilenameDeterminationInfo {
asanka 2013/02/22 18:55:48 Shall we move this to the top of the source file?
benjhayden 2013/02/22 20:43:23 You mean to the anonymous namespace? Can't do -- i
+ 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,
@@ -636,12 +647,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,
@@ -678,6 +689,75 @@ 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)
+ 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);
+ }
+#else // defined(OS_ANDROID)
+ filename_determined.Run();
+#endif // defined(OS_ANDROID)
+}
+
+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));
asanka 2013/02/22 18:55:48 Also normalize path separators. Or we might end up
benjhayden 2013/02/22 20:43:23 Done.
+ net::GenerateSafeFileName(download->GetMimeType(), false, &temp_filename);
asanka 2013/02/22 18:55:48 This could prevent the extension from setting a fi
benjhayden 2013/02/22 20:43:23 Done.
+ // 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) {

Powered by Google App Engine
This is Rietveld 408576698