| Index: chrome/browser/download/download_manager.cc
|
| ===================================================================
|
| --- chrome/browser/download/download_manager.cc (revision 96577)
|
| +++ chrome/browser/download/download_manager.cc (working copy)
|
| @@ -8,32 +8,21 @@
|
| #include "base/file_util.h"
|
| #include "base/i18n/case_conversion.h"
|
| #include "base/logging.h"
|
| -#include "base/path_service.h"
|
| -#include "base/rand_util.h"
|
| #include "base/stl_util.h"
|
| -#include "base/stringprintf.h"
|
| -#include "base/sys_string_conversions.h"
|
| #include "base/task.h"
|
| -#include "base/utf_string_conversions.h"
|
| #include "build/build_config.h"
|
| #include "chrome/browser/browser_process.h"
|
| #include "chrome/browser/download/download_create_info.h"
|
| -#include "chrome/browser/download/download_extensions.h"
|
| #include "chrome/browser/download/download_file_manager.h"
|
| #include "chrome/browser/download/download_history.h"
|
| #include "chrome/browser/download/download_item.h"
|
| #include "chrome/browser/download/download_manager_delegate.h"
|
| #include "chrome/browser/download/download_prefs.h"
|
| #include "chrome/browser/download/download_request_handle.h"
|
| -#include "chrome/browser/download/download_safe_browsing_client.h"
|
| #include "chrome/browser/download/download_status_updater.h"
|
| #include "chrome/browser/download/download_util.h"
|
| -#include "chrome/browser/extensions/extension_service.h"
|
| #include "chrome/browser/history/download_history_info.h"
|
| #include "chrome/browser/profiles/profile.h"
|
| -#include "chrome/browser/tab_contents/tab_util.h"
|
| -#include "chrome/common/chrome_paths.h"
|
| -#include "chrome/common/pref_names.h"
|
| #include "content/browser/browser_thread.h"
|
| #include "content/browser/renderer_host/render_process_host.h"
|
| #include "content/browser/renderer_host/render_view_host.h"
|
| @@ -41,13 +30,6 @@
|
| #include "content/browser/tab_contents/tab_contents.h"
|
| #include "content/common/content_notification_types.h"
|
| #include "content/common/notification_service.h"
|
| -#include "googleurl/src/gurl.h"
|
| -#include "grit/generated_resources.h"
|
| -#include "grit/theme_resources.h"
|
| -#include "net/base/mime_util.h"
|
| -#include "net/base/net_util.h"
|
| -#include "ui/base/l10n/l10n_util.h"
|
| -#include "ui/base/resource/resource_bundle.h"
|
|
|
| DownloadManager::DownloadManager(DownloadManagerDelegate* delegate,
|
| DownloadStatusUpdater* status_updater)
|
| @@ -246,32 +228,12 @@
|
| return true;
|
| }
|
|
|
| -// We have received a message from DownloadFileManager about a new download. We
|
| -// create a download item and store it in our download map, and inform the
|
| -// history system of a new download. Since this method can be called while the
|
| -// history service thread is still reading the persistent state, we do not
|
| -// insert the new DownloadItem into 'history_downloads_' or inform our
|
| -// observers at this point. OnCreateDownloadEntryComplete() handles that
|
| -// finalization of the the download creation as a callback from the
|
| -// history thread.
|
| +// We have received a message from DownloadFileManager about a new download.
|
| void DownloadManager::StartDownload(int32 download_id) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
|
|
| - DownloadItem* download = GetActiveDownloadItem(download_id);
|
| - if (!download)
|
| - return;
|
| -
|
| -#if defined(ENABLE_SAFE_BROWSING)
|
| - // Create a client to verify download URL with safebrowsing.
|
| - // It deletes itself after the callback.
|
| - scoped_refptr<DownloadSBClient> sb_client = new DownloadSBClient(
|
| - download_id, download->url_chain(), download->referrer_url(),
|
| - profile_->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled));
|
| - sb_client->CheckDownloadUrl(
|
| - NewCallback(this, &DownloadManager::CheckDownloadUrlDone));
|
| -#else
|
| - CheckDownloadUrlDone(download_id, false);
|
| -#endif
|
| + if (delegate_->ShouldStartDownload(download_id))
|
| + RestartDownload(download_id);
|
| }
|
|
|
| void DownloadManager::CheckForHistoryFilesRemoval() {
|
| @@ -316,199 +278,17 @@
|
| }
|
| }
|
|
|
| -void DownloadManager::CheckDownloadUrlDone(int32 download_id,
|
| - bool is_dangerous_url) {
|
| +void DownloadManager::RestartDownload(
|
| + int32 download_id) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
|
|
| DownloadItem* download = GetActiveDownloadItem(download_id);
|
| if (!download)
|
| return;
|
|
|
| - if (is_dangerous_url)
|
| - download->MarkUrlDangerous();
|
| -
|
| - download_history_->CheckVisitedReferrerBefore(download_id,
|
| - download->referrer_url(),
|
| - NewCallback(this, &DownloadManager::CheckVisitedReferrerBeforeDone));
|
| -}
|
| -
|
| -void DownloadManager::CheckVisitedReferrerBeforeDone(
|
| - int32 download_id,
|
| - bool visited_referrer_before) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| -
|
| - DownloadItem* download = GetActiveDownloadItem(download_id);
|
| - if (!download)
|
| - return;
|
| -
|
| - // Check whether this download is for an extension install or not.
|
| - // Allow extensions to be explicitly saved.
|
| - DownloadStateInfo state = download->state_info();
|
| - if (!state.prompt_user_for_save_location) {
|
| - if (UserScript::IsURLUserScript(download->GetURL(),
|
| - download->mime_type()) ||
|
| - (download->mime_type() == Extension::kMimeType)) {
|
| - state.is_extension_install = true;
|
| - }
|
| - }
|
| -
|
| - if (state.force_file_name.empty()) {
|
| - FilePath generated_name;
|
| - download_util::GenerateFileNameFromRequest(*download,
|
| - &generated_name);
|
| -
|
| - // 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 (!state.is_extension_install &&
|
| - !ShouldOpenFileBasedOnExtension(generated_name))
|
| - state.prompt_user_for_save_location = true;
|
| - }
|
| - if (download_prefs_->IsDownloadPathManaged()) {
|
| - state.prompt_user_for_save_location = false;
|
| - }
|
| -
|
| - // Determine the proper path for a download, by either one of the following:
|
| - // 1) using the default download directory.
|
| - // 2) prompting the user.
|
| - if (state.prompt_user_for_save_location && !last_download_path_.empty()) {
|
| - state.suggested_path = last_download_path_;
|
| - } else {
|
| - state.suggested_path = download_prefs_->download_path();
|
| - }
|
| - state.suggested_path = state.suggested_path.Append(generated_name);
|
| - } else {
|
| - state.suggested_path = state.force_file_name;
|
| - }
|
| -
|
| - if (!state.prompt_user_for_save_location && state.force_file_name.empty()) {
|
| - state.is_dangerous_file =
|
| - IsDangerousFile(*download, state, visited_referrer_before);
|
| - }
|
| -
|
| - // We need to move over to the download thread because we don't want to stat
|
| - // the suggested path on the UI thread.
|
| - // We can only access preferences on the UI thread, so check the download path
|
| - // now and pass the value to the FILE thread.
|
| - BrowserThread::PostTask(
|
| - BrowserThread::FILE, FROM_HERE,
|
| - NewRunnableMethod(
|
| - this,
|
| - &DownloadManager::CheckIfSuggestedPathExists,
|
| - download->id(),
|
| - state,
|
| - download_prefs()->download_path()));
|
| -}
|
| -
|
| -void DownloadManager::CheckIfSuggestedPathExists(int32 download_id,
|
| - DownloadStateInfo state,
|
| - const FilePath& default_path) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
|
| -
|
| - // Make sure the default download directory exists.
|
| - // TODO(phajdan.jr): only create the directory when we're sure the user
|
| - // is going to save there and not to another directory of his choice.
|
| - file_util::CreateDirectory(default_path);
|
| -
|
| - // Check writability of the suggested path. If we can't write to it, default
|
| - // to the user's "My Documents" directory. We'll prompt them in this case.
|
| - FilePath dir = state.suggested_path.DirName();
|
| - FilePath filename = state.suggested_path.BaseName();
|
| - if (!file_util::PathIsWritable(dir)) {
|
| - VLOG(1) << "Unable to write to directory \"" << dir.value() << "\"";
|
| - state.prompt_user_for_save_location = true;
|
| - PathService::Get(chrome::DIR_USER_DOCUMENTS, &state.suggested_path);
|
| - state.suggested_path = state.suggested_path.Append(filename);
|
| - }
|
| -
|
| - // If the download is deemed dangerous, we'll use a temporary name for it.
|
| - if (state.IsDangerous()) {
|
| - state.target_name = FilePath(state.suggested_path).BaseName();
|
| - // Create a temporary file to hold the file until the user approves its
|
| - // download.
|
| - FilePath::StringType file_name;
|
| - FilePath path;
|
| -#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
|
| -
|
| - while (path.empty()) {
|
| - base::SStringPrintf(
|
| - &file_name,
|
| - unconfirmed_prefix.append(
|
| - FILE_PATH_LITERAL(" %d.crdownload")).c_str(),
|
| - base::RandInt(0, 100000));
|
| - path = dir.Append(file_name);
|
| - if (file_util::PathExists(path))
|
| - path = FilePath();
|
| - }
|
| - state.suggested_path = path;
|
| - } else {
|
| - // Do not add the path uniquifier if we are saving to a specific path as in
|
| - // the drag-out case.
|
| - if (state.force_file_name.empty()) {
|
| - state.path_uniquifier = download_util::GetUniquePathNumberWithCrDownload(
|
| - state.suggested_path);
|
| - }
|
| - // We know the final path, build it if necessary.
|
| - if (state.path_uniquifier > 0) {
|
| - download_util::AppendNumberToPath(&(state.suggested_path),
|
| - state.path_uniquifier);
|
| - // Setting path_uniquifier to 0 to make sure we don't try to unique it
|
| - // later on.
|
| - state.path_uniquifier = 0;
|
| - } else if (state.path_uniquifier == -1) {
|
| - // We failed to find a unique path. We have to prompt the user.
|
| - VLOG(1) << "Unable to find a unique path for suggested path \""
|
| - << state.suggested_path.value() << "\"";
|
| - state.prompt_user_for_save_location = true;
|
| - }
|
| - }
|
| -
|
| - // Create an empty file at the suggested path so that we don't allocate the
|
| - // same "non-existant" path to multiple downloads.
|
| - // See: http://code.google.com/p/chromium/issues/detail?id=3662
|
| - if (!state.prompt_user_for_save_location &&
|
| - state.force_file_name.empty()) {
|
| - if (state.IsDangerous())
|
| - file_util::WriteFile(state.suggested_path, "", 0);
|
| - else
|
| - file_util::WriteFile(download_util::GetCrDownloadPath(
|
| - state.suggested_path), "", 0);
|
| - }
|
| -
|
| - BrowserThread::PostTask(
|
| - BrowserThread::UI, FROM_HERE,
|
| - NewRunnableMethod(this,
|
| - &DownloadManager::OnPathExistenceAvailable,
|
| - download_id,
|
| - state));
|
| -}
|
| -
|
| -void DownloadManager::OnPathExistenceAvailable(
|
| - int32 download_id, const DownloadStateInfo& new_state) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| -
|
| - DownloadItem* download = GetActiveDownloadItem(download_id);
|
| - if (!download)
|
| - return;
|
| -
|
| VLOG(20) << __FUNCTION__ << "()"
|
| << " download = " << download->DebugString(true);
|
|
|
| - download->SetFileCheckResults(new_state);
|
| -
|
| FilePath suggested_path = download->suggested_path();
|
|
|
| if (download->prompt_user_for_save_location()) {
|
| @@ -522,7 +302,7 @@
|
| *id_ptr = download_id;
|
|
|
| delegate_->ChooseDownloadPath(
|
| - this, contents, suggested_path, reinterpret_cast<void*>(id_ptr));
|
| + contents, suggested_path, reinterpret_cast<void*>(id_ptr));
|
|
|
| FOR_EACH_OBSERVER(Observer, observers_,
|
| SelectFileDialogDisplayed(download_id));
|
| @@ -641,44 +421,9 @@
|
| DownloadItem* download = active_downloads_[download_id];
|
| download->OnAllDataSaved(size);
|
|
|
| - // When hash is not available, it means either it is not calculated
|
| - // or there is error while it is calculated. We will skip the download hash
|
| - // check in that case.
|
| - if (!hash.empty()) {
|
| -#if defined(ENABLE_SAFE_BROWSING)
|
| - scoped_refptr<DownloadSBClient> sb_client =
|
| - new DownloadSBClient(download_id,
|
| - download->url_chain(),
|
| - download->referrer_url(),
|
| - profile_->GetPrefs()->GetBoolean(
|
| - prefs::kSafeBrowsingEnabled));
|
| - sb_client->CheckDownloadHash(
|
| - hash, NewCallback(this, &DownloadManager::CheckDownloadHashDone));
|
| -#else
|
| - CheckDownloadHashDone(download_id, false);
|
| -#endif
|
| - }
|
| MaybeCompleteDownload(download);
|
| }
|
|
|
| -// TODO(lzheng): This function currently works as a callback place holder.
|
| -// Once we decide the hash check is reliable, we could move the
|
| -// MaybeCompleteDownload in OnAllDataSaved to this function.
|
| -void DownloadManager::CheckDownloadHashDone(int32 download_id,
|
| - bool is_dangerous_hash) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| - DVLOG(1) << "CheckDownloadHashDone, download_id: " << download_id
|
| - << " is dangerous_hash: " << is_dangerous_hash;
|
| -
|
| - // If it's not in active_downloads_, that means it was cancelled or
|
| - // the download already finished.
|
| - if (active_downloads_.count(download_id) == 0)
|
| - return;
|
| -
|
| - DVLOG(1) << "CheckDownloadHashDone, url: "
|
| - << active_downloads_[download_id]->GetURL().spec();
|
| -}
|
| -
|
| void DownloadManager::AssertQueueStateConsistent(DownloadItem* download) {
|
| // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved.
|
| if (download->state() == DownloadItem::REMOVING) {
|
| @@ -993,18 +738,6 @@
|
| observers_.RemoveObserver(observer);
|
| }
|
|
|
| -bool DownloadManager::ShouldOpenFileBasedOnExtension(
|
| - const FilePath& path) const {
|
| - FilePath::StringType extension = path.Extension();
|
| - if (extension.empty())
|
| - return false;
|
| - if (Extension::IsExtension(path))
|
| - return false;
|
| - DCHECK(extension[0] == FilePath::kExtensionSeparator);
|
| - extension.erase(0, 1);
|
| - return download_prefs_->IsAutoOpenEnabledForExtension(extension);
|
| -}
|
| -
|
| bool DownloadManager::IsDownloadProgressKnown() {
|
| for (DownloadMap::iterator i = in_progress_.begin();
|
| i != in_progress_.end(); ++i) {
|
| @@ -1079,33 +812,6 @@
|
| DownloadCancelledInternal(download_id, download->request_handle());
|
| }
|
|
|
| -// TODO(phajdan.jr): This is apparently not being exercised in tests.
|
| -bool DownloadManager::IsDangerousFile(const DownloadItem& download,
|
| - const DownloadStateInfo& state,
|
| - bool visited_referrer_before) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| -
|
| - bool auto_open = ShouldOpenFileBasedOnExtension(state.suggested_path);
|
| - download_util::DownloadDangerLevel danger_level =
|
| - download_util::GetFileDangerLevel(state.suggested_path.BaseName());
|
| -
|
| - if (danger_level == download_util::Dangerous)
|
| - return !(auto_open && state.has_user_gesture);
|
| -
|
| - if (danger_level == download_util::AllowOnUserGesture &&
|
| - (!state.has_user_gesture || !visited_referrer_before))
|
| - return true;
|
| -
|
| - if (state.is_extension_install) {
|
| - // Extensions that are not from the gallery are considered dangerous.
|
| - ExtensionService* service = profile()->GetExtensionService();
|
| - if (!service || !service->IsDownloadFromGallery(download.GetURL(),
|
| - download.referrer_url()))
|
| - return true;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| // Operations posted to us from the history service ----------------------------
|
|
|
| // The history service has retrieved all download entries. 'entries' contains
|
| @@ -1198,7 +904,7 @@
|
| // If the contents no longer exists, we ask the embedder to suggest another
|
| // tab.
|
| if (!content)
|
| - content = delegate_->GetAlternativeTabContentsToNotifyForDownload(this);
|
| + content = delegate_->GetAlternativeTabContentsToNotifyForDownload();
|
|
|
| if (content)
|
| content->OnStartDownload(download);
|
|
|