Chromium Code Reviews| 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); |
| -} |