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

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

Issue 12850002: Move download filename determintion into a separate class. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 8 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 20334cd6b5d7e1b9c6dc6893566da83652f412e3..e9897bf5e4f35f02f5bf0ca758b0dda93967e59c 100644
--- a/chrome/browser/download/chrome_download_manager_delegate.cc
+++ b/chrome/browser/download/chrome_download_manager_delegate.cc
@@ -19,45 +19,30 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/download/download_completion_blocker.h"
#include "chrome/browser/download/download_crx_util.h"
-#include "chrome/browser/download/download_extensions.h"
#include "chrome/browser/download/download_file_picker.h"
#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_target_determiner.h"
#include "chrome/browser/download/download_util.h"
#include "chrome/browser/download/save_package_file_picker.h"
-#include "chrome/browser/extensions/api/downloads/downloads_api.h"
#include "chrome/browser/extensions/crx_installer.h"
-#include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/extensions/extension_system.h"
-#include "chrome/browser/history/history_service.h"
-#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/platform_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/safe_browsing/safe_browsing_service.h"
-#include "chrome/browser/ui/host_desktop.h"
-#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_notification_types.h"
-#include "chrome/common/extensions/feature_switch.h"
-#include "chrome/common/extensions/user_script.h"
+#include "chrome/common/extensions/extension.h"
#include "chrome/common/pref_names.h"
#include "components/user_prefs/pref_registry_syncable.h"
#include "content/public/browser/download_item.h"
#include "content/public/browser/download_manager.h"
#include "content/public/browser/notification_source.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_delegate.h"
-#include "grit/generated_resources.h"
-#include "net/base/net_util.h"
-#include "ui/base/l10n/l10n_util.h"
#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/drive/drive_download_handler.h"
#include "chrome/browser/chromeos/drive/drive_file_system_util.h"
-#include "chrome/browser/download/download_file_picker_chromeos.h"
#include "chrome/browser/download/save_package_file_picker_chromeos.h"
#endif
@@ -66,7 +51,6 @@ using content::BrowserThread;
using content::DownloadId;
using content::DownloadItem;
using content::DownloadManager;
-using content::WebContents;
using safe_browsing::DownloadProtectionService;
namespace {
@@ -103,68 +87,6 @@ class SafeBrowsingState : public DownloadCompletionBlocker {
SafeBrowsingState::~SafeBrowsingState() {}
-// Generate a filename based on the response from the server. Similar
-// in operation to net::GenerateFileName(), but uses a localized
-// default name.
-void GenerateFileNameFromRequest(const DownloadItem& download_item,
- base::FilePath* generated_name,
- std::string referrer_charset) {
- std::string default_file_name(
- l10n_util::GetStringUTF8(IDS_DEFAULT_DOWNLOAD_FILENAME));
-
- *generated_name = net::GenerateFileName(download_item.GetURL(),
- download_item.GetContentDisposition(),
- referrer_charset,
- download_item.GetSuggestedFilename(),
- download_item.GetMimeType(),
- default_file_name);
-}
-
-typedef base::Callback<void(bool)> VisitedBeforeCallback;
-
-// Condenses the results from HistoryService::GetVisibleVisitCountToHost() to a
-// single bool so that VisitedBeforeCallback can curry up to 5 other parameters
-// without a struct.
-void VisitCountsToVisitedBefore(
- const VisitedBeforeCallback& callback,
- HistoryService::Handle unused_handle,
- bool found_visits,
- int count,
- base::Time first_visit) {
- callback.Run(found_visits && count &&
- (first_visit.LocalMidnight() < base::Time::Now().LocalMidnight()));
-}
-
-base::FilePath GetIntermediatePath(const base::FilePath& target_path,
- content::DownloadDangerType danger_type,
- bool is_forced_path) {
- // If the download is not dangerous, just append .crdownload to the target
- // path.
- if (danger_type == content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) {
- if (is_forced_path)
- return target_path;
- return download_util::GetCrDownloadPath(target_path);
- }
-
- // If the download is potentially dangerous we create a filename of the form
- // 'Unconfirmed <random>.crdownload'.
- base::FilePath::StringType file_name;
- base::FilePath dir = target_path.DirName();
-#if defined(OS_WIN)
- string16 unconfirmed_prefix =
- l10n_util::GetStringUTF16(IDS_DOWNLOAD_UNCONFIRMED_PREFIX);
-#else
- std::string unconfirmed_prefix =
- l10n_util::GetStringUTF8(IDS_DOWNLOAD_UNCONFIRMED_PREFIX);
-#endif
- base::SStringPrintf(
- &file_name,
- unconfirmed_prefix.append(
- FILE_PATH_LITERAL(" %d.crdownload")).c_str(),
- base::RandInt(0, 1000000));
- return dir.Append(file_name);
-}
-
// Returns a file path in the form that is expected by
// platform_util::OpenItem/ShowItemInFolder, including any transformation
// required for download abstractions layered on top of the core system,
@@ -221,52 +143,28 @@ DownloadId ChromeDownloadManagerDelegate::GetNextId() {
bool ChromeDownloadManagerDelegate::DetermineDownloadTarget(
DownloadItem* download,
const content::DownloadTargetCallback& callback) {
-#if defined(FULL_SAFE_BROWSING)
- DownloadProtectionService* service = GetDownloadProtectionService();
- if (service) {
- VLOG(2) << __FUNCTION__ << "() Start SB URL check for download = "
- << download->DebugString(false);
- service->CheckDownloadUrl(
- *download,
- base::Bind(
- &ChromeDownloadManagerDelegate::CheckDownloadUrlDone,
- this,
- download->GetId(),
- callback));
- return true;
- }
-#endif
- CheckDownloadUrlDone(download->GetId(), callback,
- DownloadProtectionService::SAFE);
+ DownloadTargetDeterminer::CompletionCallback destination_callback =
+ base::Bind(&ChromeDownloadManagerDelegate::OnDetermineDownloadTargetDone,
+ this, callback);
+ DownloadTargetDeterminer::Start(download,
+ download_prefs_.get(),
+ last_download_path_,
+ this,
+ destination_callback);
return true;
}
-void ChromeDownloadManagerDelegate::ChooseDownloadPath(
- DownloadItem* item,
- const base::FilePath& suggested_path,
- const FileSelectedCallback& file_selected_callback) {
- // Deletes itself.
- DownloadFilePicker* file_picker =
-#if defined(OS_CHROMEOS)
- new DownloadFilePickerChromeOS();
-#else
- new DownloadFilePicker();
-#endif
- file_picker->Init(download_manager_, item, suggested_path,
- file_selected_callback);
-}
-
bool ChromeDownloadManagerDelegate::ShouldOpenFileBasedOnExtension(
const base::FilePath& path) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- base::FilePath::StringType extension = path.Extension();
- if (extension.empty())
+ if (path.Extension().empty())
return false;
+ // TODO(asanka): This determination is done based on |path|, while elsewhere
benjhayden 2013/04/09 15:46:32 Where else?
asanka 2013/04/16 20:34:01 Updated comment.
+ // an extension download is recognized based on characteristics of the
+ // DownloadItem other than the path. Reconcile this.
if (extensions::Extension::IsExtension(path))
return false;
- DCHECK(extension[0] == base::FilePath::kExtensionSeparator);
- extension.erase(0, 1);
- return download_prefs_->IsAutoOpenEnabledForExtension(extension);
+ return download_prefs_->IsAutoOpenEnabledBasedOnExtension(path);
}
// static
@@ -401,7 +299,7 @@ void ChromeDownloadManagerDelegate::GetSaveDir(
}
void ChromeDownloadManagerDelegate::ChooseSavePath(
- WebContents* web_contents,
+ content::WebContents* web_contents,
const base::FilePath& suggested_path,
const base::FilePath::StringType& default_extension,
bool can_save_as_complete,
@@ -457,6 +355,7 @@ void ChromeDownloadManagerDelegate::ClearLastDownloadPath() {
DownloadProtectionService*
ChromeDownloadManagerDelegate::GetDownloadProtectionService() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
#if defined(FULL_SAFE_BROWSING)
SafeBrowsingService* sb_service = g_browser_process->safe_browsing_service();
if (sb_service && sb_service->download_protection_service() &&
@@ -467,94 +366,82 @@ DownloadProtectionService*
return NULL;
}
-// TODO(phajdan.jr): This is apparently not being exercised in tests.
-bool ChromeDownloadManagerDelegate::IsDangerousFile(
- const DownloadItem& download,
+void ChromeDownloadManagerDelegate::PromptUserForDownloadPath(
+ DownloadItem* download,
const base::FilePath& suggested_path,
- bool visited_referrer_before) {
+ const DownloadTargetDeterminerDelegate::FileSelectedCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- const bool is_extension_download =
- download_crx_util::IsExtensionDownload(download);
-
- // User-initiated extension downloads from pref-whitelisted sources are not
- // considered dangerous.
- if (download.HasUserGesture() &&
- is_extension_download &&
- download_crx_util::OffStoreInstallAllowedByPrefs(profile_, download)) {
- return false;
- }
-
- // Extensions that are not from the gallery are considered dangerous.
- // When off-store install is disabled we skip this, since in this case, we
- // will not offer to install the extension.
- if (extensions::FeatureSwitch::easy_off_store_install()->IsEnabled() &&
- is_extension_download &&
- !extensions::WebstoreInstaller::GetAssociatedApproval(download)) {
- return true;
- }
+ DownloadFilePicker::ShowFilePicker(
+ download,
+ suggested_path,
+ base::Bind(&ChromeDownloadManagerDelegate::OnDownloadPathSelected,
+ this,
+ callback));
+}
- // Anything the user has marked auto-open is OK if it's user-initiated.
- if (ShouldOpenFileBasedOnExtension(suggested_path) &&
- download.HasUserGesture())
- return false;
+ExtensionDownloadsEventRouter*
+ ChromeDownloadManagerDelegate::GetExtensionEventRouter() {
+ return DownloadServiceFactory::GetForProfile(profile_)->
+ GetExtensionEventRouter();
+}
- // "Allow on user gesture" is OK when we have a user gesture and the hosting
- // page has been visited before today.
- download_util::DownloadDangerLevel danger_level =
- download_util::GetFileDangerLevel(suggested_path.BaseName());
- if (danger_level == download_util::AllowOnUserGesture) {
- if (download.GetTransitionType() &
- content::PAGE_TRANSITION_FROM_ADDRESS_BAR) {
- return false;
- }
- return !download.HasUserGesture() || !visited_referrer_before;
+void ChromeDownloadManagerDelegate::DetermineLocalPath(
+ DownloadItem* download,
+ const base::FilePath& virtual_path,
+ const DownloadTargetDeterminerDelegate::LocalPathCallback& callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+#if defined(OS_CHROMEOS)
+ drive::DriveDownloadHandler* drive_download_handler =
+ drive::DriveDownloadHandler::GetForProfile(GetProfile());
+ if (drive_download_handler) {
+ drive_download_handler->SubstituteDriveDownloadPath(
+ virtual_path_, download_,
+ base::Bind(
+ &DownloadTargetDeterminer::DetermineLocalPathDone,
+ weak_ptr_factory_.GetWeakPtr()));
+ return;
}
-
- return danger_level == download_util::Dangerous;
+#endif
+ callback.Run(virtual_path);
}
-void ChromeDownloadManagerDelegate::GetReservedPath(
- DownloadItem& download,
- const base::FilePath& target_path,
- const base::FilePath& default_download_path,
+void ChromeDownloadManagerDelegate::ReserveVirtualPath(
+ content::DownloadItem* download,
+ const base::FilePath& virtual_path,
bool should_uniquify_path,
- const DownloadPathReservationTracker::ReservedPathCallback& callback) {
+ const DownloadTargetDeterminerDelegate::ReservedPathCallback& callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(!virtual_path.empty());
+#if defined(OS_CHROMEOS)
+ // 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);
+ return;
+ }
+#endif
DownloadPathReservationTracker::GetReservedPath(
- download, target_path, default_download_path, should_uniquify_path,
- callback);
+ *download, virtual_path, download_prefs_->DownloadPath(),
+ should_uniquify_path, callback);
}
-void ChromeDownloadManagerDelegate::CheckDownloadUrlDone(
- int32 download_id,
- const content::DownloadTargetCallback& callback,
- DownloadProtectionService::DownloadCheckResult result) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- DownloadItem* download = download_manager_->GetDownload(download_id);
- if (!download || (download->GetState() != DownloadItem::IN_PROGRESS))
- return;
+void ChromeDownloadManagerDelegate::OnDownloadPathSelected(
+ const DownloadTargetDeterminerDelegate::FileSelectedCallback& callback,
+ const base::FilePath& virtual_path,
+ const base::FilePath& local_path) {
+ if (!virtual_path.empty())
+ last_download_path_ = virtual_path.DirName();
+ callback.Run(virtual_path, local_path);
+}
- VLOG(2) << __FUNCTION__ << "() download = " << download->DebugString(false)
- << " verdict = " << result;
- content::DownloadDangerType danger_type = download->GetDangerType();
- if (result != DownloadProtectionService::SAFE)
- danger_type = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL;
-
- // HistoryServiceFactory redirects incognito profiles to on-record profiles.
- HistoryService* history = HistoryServiceFactory::GetForProfile(
- profile_, Profile::EXPLICIT_ACCESS);
- if (!history || !download->GetReferrerUrl().is_valid()) {
- // If the original profile doesn't have a HistoryService or the referrer url
- // is invalid, then give up and assume the referrer has not been visited
- // before. There's no history for on-record profiles in unit_tests, for
- // example.
- CheckVisitedReferrerBeforeDone(download_id, callback, danger_type, false);
- return;
- }
- history->GetVisibleVisitCountToHost(
- download->GetReferrerUrl(), &history_consumer_,
- base::Bind(&VisitCountsToVisitedBefore, base::Bind(
- &ChromeDownloadManagerDelegate::CheckVisitedReferrerBeforeDone,
- this, download_id, callback, danger_type)));
+void ChromeDownloadManagerDelegate::OnDetermineDownloadTargetDone(
+ const content::DownloadTargetCallback& callback,
+ const base::FilePath& virtual_path,
benjhayden 2013/04/09 15:46:32 I spent a few seconds looking for where this was u
+ const base::FilePath& local_path,
+ const base::FilePath& intermediate_path,
+ content::DownloadItem::TargetDisposition target_disposition,
+ content::DownloadDangerType danger_type) {
+ callback.Run(local_path, target_disposition, danger_type, intermediate_path);
}
void ChromeDownloadManagerDelegate::CheckClientDownloadDone(
@@ -612,287 +499,3 @@ void ChromeDownloadManagerDelegate::Observe(
crx_installers_.erase(installer.get());
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,
- content::DownloadDangerType danger_type,
- bool visited_referrer_before) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- DownloadItem* download =
- download_manager_->GetDownload(download_id);
- if (!download || (download->GetState() != DownloadItem::IN_PROGRESS))
- return;
-
- 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) {
- GenerateFileNameFromRequest(
- *download,
- &generated_name,
- profile_->GetPrefs()->GetString(prefs::kDefaultCharset));
-
- // Freeze the user's preference for showing a Save As dialog. We're going
- // to bounce around a bunch of threads and we don't want to worry about race
- // conditions where the user changes this pref out from under us.
- if (download_prefs_->PromptForDownload()) {
- // But ignore the user's preference for the following scenarios:
- // 1) Extension installation. Note that we only care here about the case
- // where an extension is installed, not when one is downloaded with
- // "save as...".
- // 2) Filetypes marked "always open." If the user just wants this file
- // opened, don't bother asking where to keep it.
- if (!download_crx_util::IsExtensionDownload(*download) &&
- !ShouldOpenFileBasedOnExtension(generated_name))
- should_prompt = true;
- }
- if (download_prefs_->IsDownloadPathManaged())
- should_prompt = false;
-
- // Determine the proper path for a download, by either one of the following:
- // 1) using the default download directory.
- // 2) prompting the user.
- base::FilePath target_directory;
- if (should_prompt && !last_download_path_.empty())
- target_directory = last_download_path_;
- else
- target_directory = download_prefs_->DownloadPath();
- suggested_path = target_directory.Append(generated_name);
- } else {
- DCHECK(!should_prompt);
- 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) {
- if (!should_prompt && !is_forced_path &&
- IsDangerousFile(*download, suggested_path, visited_referrer_before)) {
- danger_type = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE;
- }
-
-#if defined(FULL_SAFE_BROWSING)
- DownloadProtectionService* service = GetDownloadProtectionService();
- // If this type of files is handled by the enhanced SafeBrowsing download
- // protection, mark it as potentially dangerous content until we are done
- // with scanning it.
- if (service && service->enabled()) {
- // TODO(noelutz): if the user changes the extension name in the UI to
- // something like .exe SafeBrowsing will currently *not* check if the
- // download is malicious.
- if (service->IsSupportedDownload(*download, suggested_path))
- danger_type = content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT;
- }
-#endif
- } else {
- // Currently we only expect this case.
- DCHECK_EQ(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, danger_type);
- }
-
-#if defined (OS_CHROMEOS)
- drive::DriveDownloadHandler* drive_download_handler =
- drive::DriveDownloadHandler::GetForProfile(profile_);
- if (drive_download_handler) {
- drive_download_handler->SubstituteDriveDownloadPath(
- suggested_path, download,
- base::Bind(
- &ChromeDownloadManagerDelegate::SubstituteDriveDownloadPathCallback,
- this, download->GetId(), callback, should_prompt, is_forced_path,
- danger_type));
- return;
- }
-#endif
- GetReservedPath(
- *download, suggested_path, download_prefs_->DownloadPath(),
- !is_forced_path,
- base::Bind(&ChromeDownloadManagerDelegate::OnPathReservationAvailable,
- this, download->GetId(), callback, should_prompt,
- danger_type));
-}
-
-#if defined (OS_CHROMEOS)
-// TODO(asanka): Merge this logic with the logic in DownloadFilePickerChromeOS.
-void ChromeDownloadManagerDelegate::SubstituteDriveDownloadPathCallback(
- int32 download_id,
- const content::DownloadTargetCallback& callback,
- bool should_prompt,
- bool is_forced_path,
- content::DownloadDangerType danger_type,
- const base::FilePath& suggested_path) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- DownloadItem* download =
- download_manager_->GetDownload(download_id);
- if (!download || (download->GetState() != DownloadItem::IN_PROGRESS))
- return;
-
- if (suggested_path.empty()) {
- // Substitution failed.
- callback.Run(base::FilePath(),
- DownloadItem::TARGET_DISPOSITION_OVERWRITE,
- danger_type,
- base::FilePath());
- return;
- }
-
- GetReservedPath(
- *download, suggested_path, download_prefs_->DownloadPath(),
- !is_forced_path,
- base::Bind(&ChromeDownloadManagerDelegate::OnPathReservationAvailable,
- this, download->GetId(), callback, should_prompt,
- danger_type));
-}
-#endif
-
-void ChromeDownloadManagerDelegate::OnPathReservationAvailable(
- int32 download_id,
- const content::DownloadTargetCallback& callback,
- bool should_prompt,
- content::DownloadDangerType danger_type,
- const base::FilePath& reserved_path,
- bool reserved_path_verified) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- DownloadItem* download =
- download_manager_->GetDownload(download_id);
- if (!download || (download->GetState() != DownloadItem::IN_PROGRESS))
- return;
- if (should_prompt || !reserved_path_verified) {
- // If the target path could not be verified then the path was non-existant,
- // non writeable or could not be uniquified. Prompt the user.
- ChooseDownloadPath(
- download, reserved_path,
- base::Bind(&ChromeDownloadManagerDelegate::OnTargetPathDetermined,
- this, download_id, callback,
- DownloadItem::TARGET_DISPOSITION_PROMPT, danger_type));
- } else {
- OnTargetPathDetermined(download_id, callback,
- DownloadItem::TARGET_DISPOSITION_OVERWRITE,
- danger_type, reserved_path);
- }
-}
-
-void ChromeDownloadManagerDelegate::OnTargetPathDetermined(
- int32 download_id,
- const content::DownloadTargetCallback& callback,
- DownloadItem::TargetDisposition disposition,
- content::DownloadDangerType danger_type,
- const base::FilePath& target_path) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- base::FilePath intermediate_path;
- DownloadItem* download =
- download_manager_->GetDownload(download_id);
- if (!download || (download->GetState() != DownloadItem::IN_PROGRESS))
- return;
-
- // If |target_path| is empty, then that means that the user wants to cancel
- // the download.
- if (!target_path.empty()) {
- intermediate_path = GetIntermediatePath(
- target_path, danger_type, !download->GetForcedFilePath().empty());
-
- // Retain the last directory. Exclude temporary downloads since the path
- // likely points at the location of a temporary file.
- // TODO(asanka): This logic is a hack. DownloadFilePicker should give us a
- // directory to persist. Or perhaps, if the Drive path
- // substitution logic is moved here, then we would have a
- // persistable path after the DownloadFilePicker is done.
- if (disposition == DownloadItem::TARGET_DISPOSITION_PROMPT &&
- !download->IsTemporary())
- last_download_path_ = target_path.DirName();
- }
- callback.Run(target_path, disposition, danger_type, intermediate_path);
-}

Powered by Google App Engine
This is Rietveld 408576698