Index: chrome/browser/download/download_item.cc |
=================================================================== |
--- chrome/browser/download/download_item.cc (revision 96793) |
+++ chrome/browser/download/download_item.cc (working copy) |
@@ -1,867 +0,0 @@ |
-// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "chrome/browser/download/download_item.h" |
- |
-#include "base/basictypes.h" |
-#include "base/file_util.h" |
-#include "base/format_macros.h" |
-#include "base/i18n/case_conversion.h" |
-#include "base/logging.h" |
-#include "base/metrics/histogram.h" |
-#include "base/stringprintf.h" |
-#include "base/timer.h" |
-#include "base/utf_string_conversions.h" |
-#include "net/base/net_util.h" |
-#include "chrome/browser/download/download_create_info.h" |
-#include "chrome/browser/download/download_crx_util.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_manager.h" |
-#include "chrome/browser/download/download_manager_delegate.h" |
-#include "chrome/browser/download/download_prefs.h" |
-#include "chrome/browser/download/download_state_info.h" |
-#include "chrome/browser/download/download_util.h" |
-#include "chrome/browser/extensions/crx_installer.h" |
-#include "chrome/browser/history/download_history_info.h" |
-#include "chrome/browser/platform_util.h" |
-#include "chrome/browser/prefs/pref_service.h" |
-#include "chrome/browser/profiles/profile.h" |
-#include "chrome/common/chrome_notification_types.h" |
-#include "chrome/common/extensions/extension.h" |
-#include "chrome/common/pref_names.h" |
-#include "content/browser/browser_thread.h" |
-#include "content/common/notification_source.h" |
-#include "ui/base/l10n/l10n_util.h" |
- |
-// A DownloadItem normally goes through the following states: |
-// * Created (when download starts) |
-// * Made visible to consumers (e.g. Javascript) after the |
-// destination file has been determined. |
-// * Entered into the history database. |
-// * Made visible in the download shelf. |
-// * All data is saved. Note that the actual data download occurs |
-// in parallel with the above steps, but until those steps are |
-// complete, completion of the data download will be ignored. |
-// * Download file is renamed to its final name, and possibly |
-// auto-opened. |
-// TODO(rdsmith): This progress should be reflected in |
-// DownloadItem::DownloadState and a state transition table/state diagram. |
-// |
-// TODO(rdsmith): This description should be updated to reflect the cancel |
-// pathways. |
- |
-namespace { |
- |
-// Update frequency (milliseconds). |
-const int kUpdateTimeMs = 1000; |
- |
-static void DeleteDownloadedFile(const FilePath& path) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
- |
- // Make sure we only delete files. |
- if (!file_util::DirectoryExists(path)) |
- file_util::Delete(path, false); |
-} |
- |
-const char* DebugSafetyStateString(DownloadItem::SafetyState state) { |
- switch (state) { |
- case DownloadItem::SAFE: |
- return "SAFE"; |
- case DownloadItem::DANGEROUS: |
- return "DANGEROUS"; |
- case DownloadItem::DANGEROUS_BUT_VALIDATED: |
- return "DANGEROUS_BUT_VALIDATED"; |
- default: |
- NOTREACHED() << "Unknown safety state " << state; |
- return "unknown"; |
- }; |
-} |
- |
-const char* DebugDownloadStateString(DownloadItem::DownloadState state) { |
- switch (state) { |
- case DownloadItem::IN_PROGRESS: |
- return "IN_PROGRESS"; |
- case DownloadItem::COMPLETE: |
- return "COMPLETE"; |
- case DownloadItem::CANCELLED: |
- return "CANCELLED"; |
- case DownloadItem::REMOVING: |
- return "REMOVING"; |
- case DownloadItem::INTERRUPTED: |
- return "INTERRUPTED"; |
- default: |
- NOTREACHED() << "Unknown download state " << state; |
- return "unknown"; |
- }; |
-} |
- |
-DownloadItem::SafetyState GetSafetyState(bool dangerous_file, |
- bool dangerous_url) { |
- return (dangerous_url || dangerous_file) ? |
- DownloadItem::DANGEROUS : DownloadItem::SAFE; |
-} |
- |
-// Note: When a download has both |dangerous_file| and |dangerous_url| set, |
-// danger type is set to DANGEROUS_URL since the risk of dangerous URL |
-// overweights that of dangerous file type. |
-DownloadItem::DangerType GetDangerType(bool dangerous_file, |
- bool dangerous_url) { |
- if (dangerous_url) { |
- // dangerous URL overweights dangerous file. We check dangerous URL first. |
- return DownloadItem::DANGEROUS_URL; |
- } |
- return dangerous_file ? |
- DownloadItem::DANGEROUS_FILE : DownloadItem::NOT_DANGEROUS; |
-} |
- |
-} // namespace |
- |
-// Constructor for reading from the history service. |
-DownloadItem::DownloadItem(DownloadManager* download_manager, |
- const DownloadHistoryInfo& info) |
- : download_id_(-1), |
- full_path_(info.path), |
- url_chain_(1, info.url), |
- referrer_url_(info.referrer_url), |
- total_bytes_(info.total_bytes), |
- received_bytes_(info.received_bytes), |
- start_tick_(base::TimeTicks()), |
- state_(static_cast<DownloadState>(info.state)), |
- start_time_(info.start_time), |
- db_handle_(info.db_handle), |
- download_manager_(download_manager), |
- is_paused_(false), |
- open_when_complete_(false), |
- file_externally_removed_(false), |
- safety_state_(SAFE), |
- auto_opened_(false), |
- is_otr_(false), |
- is_temporary_(false), |
- all_data_saved_(false), |
- opened_(false), |
- open_enabled_(true) { |
- if (IsInProgress()) |
- state_ = CANCELLED; |
- if (IsComplete()) |
- all_data_saved_ = true; |
- Init(false /* not actively downloading */); |
-} |
- |
-// Constructing for a regular download: |
-DownloadItem::DownloadItem(DownloadManager* download_manager, |
- const DownloadCreateInfo& info, |
- bool is_otr) |
- : state_info_(info.original_name, info.save_info.file_path, |
- info.has_user_gesture, info.prompt_user_for_save_location, |
- info.path_uniquifier, false, false, |
- info.is_extension_install), |
- request_handle_(info.request_handle), |
- download_id_(info.download_id), |
- full_path_(info.path), |
- url_chain_(info.url_chain), |
- referrer_url_(info.referrer_url), |
- suggested_filename_(UTF16ToUTF8(info.save_info.suggested_name)), |
- content_disposition_(info.content_disposition), |
- mime_type_(info.mime_type), |
- original_mime_type_(info.original_mime_type), |
- referrer_charset_(info.referrer_charset), |
- total_bytes_(info.total_bytes), |
- received_bytes_(0), |
- last_os_error_(0), |
- start_tick_(base::TimeTicks::Now()), |
- state_(IN_PROGRESS), |
- start_time_(info.start_time), |
- db_handle_(DownloadHistory::kUninitializedHandle), |
- download_manager_(download_manager), |
- is_paused_(false), |
- open_when_complete_(false), |
- file_externally_removed_(false), |
- safety_state_(SAFE), |
- auto_opened_(false), |
- is_otr_(is_otr), |
- is_temporary_(!info.save_info.file_path.empty()), |
- all_data_saved_(false), |
- opened_(false), |
- open_enabled_(true) { |
- Init(true /* actively downloading */); |
-} |
- |
-// Constructing for the "Save Page As..." feature: |
-DownloadItem::DownloadItem(DownloadManager* download_manager, |
- const FilePath& path, |
- const GURL& url, |
- bool is_otr) |
- : download_id_(download_manager->GetNextSavePageId()), |
- full_path_(path), |
- url_chain_(1, url), |
- referrer_url_(GURL()), |
- total_bytes_(0), |
- received_bytes_(0), |
- last_os_error_(0), |
- start_tick_(base::TimeTicks::Now()), |
- state_(IN_PROGRESS), |
- start_time_(base::Time::Now()), |
- db_handle_(DownloadHistory::kUninitializedHandle), |
- download_manager_(download_manager), |
- is_paused_(false), |
- open_when_complete_(false), |
- file_externally_removed_(false), |
- safety_state_(SAFE), |
- auto_opened_(false), |
- is_otr_(is_otr), |
- is_temporary_(false), |
- all_data_saved_(false), |
- opened_(false), |
- open_enabled_(true) { |
- Init(true /* actively downloading */); |
-} |
- |
-DownloadItem::~DownloadItem() { |
- // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- TransitionTo(REMOVING); |
- download_manager_->AssertQueueStateConsistent(this); |
-} |
- |
-void DownloadItem::AddObserver(Observer* observer) { |
- // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- observers_.AddObserver(observer); |
-} |
- |
-void DownloadItem::RemoveObserver(Observer* observer) { |
- // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- observers_.RemoveObserver(observer); |
-} |
- |
-void DownloadItem::UpdateObservers() { |
- // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- FOR_EACH_OBSERVER(Observer, observers_, OnDownloadUpdated(this)); |
-} |
- |
-bool DownloadItem::CanShowInFolder() { |
- return !IsCancelled() && !file_externally_removed_; |
-} |
- |
-bool DownloadItem::CanOpenDownload() { |
- return !Extension::IsExtension(state_info_.target_name) && |
- !file_externally_removed_; |
-} |
- |
-bool DownloadItem::ShouldOpenFileBasedOnExtension() { |
- return download_manager_->delegate()->ShouldOpenFileBasedOnExtension( |
- GetUserVerifiedFilePath()); |
-} |
- |
-void DownloadItem::OpenFilesBasedOnExtension(bool open) { |
- DownloadPrefs* prefs = download_manager_->download_prefs(); |
- if (open) |
- prefs->EnableAutoOpenBasedOnExtension(GetUserVerifiedFilePath()); |
- else |
- prefs->DisableAutoOpenBasedOnExtension(GetUserVerifiedFilePath()); |
-} |
- |
-void DownloadItem::OpenDownload() { |
- // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- if (IsPartialDownload()) { |
- open_when_complete_ = !open_when_complete_; |
- } else if (IsComplete() && !file_externally_removed_) { |
- // Ideally, we want to detect errors in opening and report them, but we |
- // don't generally have the proper interface for that to the external |
- // program that opens the file. So instead we spawn a check to update |
- // the UI if the file has been deleted in parallel with the open. |
- download_manager_->CheckForFileRemoval(this); |
- opened_ = true; |
- FOR_EACH_OBSERVER(Observer, observers_, OnDownloadOpened(this)); |
- |
- // For testing: If download opening is disabled on this item, |
- // make the rest of the routine a no-op. |
- if (!open_enabled_) |
- return; |
- |
- if (is_extension_install()) { |
- download_crx_util::OpenChromeExtension(download_manager_->profile(), |
- *this); |
- return; |
- } |
-#if defined(OS_MACOSX) |
- // Mac OS X requires opening downloads on the UI thread. |
- platform_util::OpenItem(full_path()); |
-#else |
- BrowserThread::PostTask( |
- BrowserThread::FILE, FROM_HERE, |
- NewRunnableFunction(&platform_util::OpenItem, full_path())); |
-#endif |
- } |
-} |
- |
-void DownloadItem::ShowDownloadInShell() { |
- // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
-#if defined(OS_MACOSX) |
- // Mac needs to run this operation on the UI thread. |
- platform_util::ShowItemInFolder(full_path()); |
-#else |
- BrowserThread::PostTask( |
- BrowserThread::FILE, FROM_HERE, |
- NewRunnableFunction(&platform_util::ShowItemInFolder, |
- full_path())); |
-#endif |
-} |
- |
-void DownloadItem::DangerousDownloadValidated() { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- DCHECK_EQ(DANGEROUS, safety_state()); |
- |
- UMA_HISTOGRAM_ENUMERATION("Download.DangerousDownloadValidated", |
- GetDangerType(), |
- DANGEROUS_TYPE_MAX); |
- |
- safety_state_ = DANGEROUS_BUT_VALIDATED; |
- UpdateObservers(); |
- |
- download_manager_->MaybeCompleteDownload(this); |
-} |
- |
-void DownloadItem::UpdateSize(int64 bytes_so_far) { |
- // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- received_bytes_ = bytes_so_far; |
- |
- // If we've received more data than we were expecting (bad server info?), |
- // revert to 'unknown size mode'. |
- if (received_bytes_ > total_bytes_) |
- total_bytes_ = 0; |
-} |
- |
-void DownloadItem::StartProgressTimer() { |
- // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- update_timer_.Start(base::TimeDelta::FromMilliseconds(kUpdateTimeMs), this, |
- &DownloadItem::UpdateObservers); |
-} |
- |
-void DownloadItem::StopProgressTimer() { |
- // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- update_timer_.Stop(); |
-} |
- |
-// Updates from the download thread may have been posted while this download |
-// was being cancelled in the UI thread, so we'll accept them unless we're |
-// complete. |
-void DownloadItem::Update(int64 bytes_so_far) { |
- // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- if (!IsInProgress()) { |
- NOTREACHED(); |
- return; |
- } |
- UpdateSize(bytes_so_far); |
- UpdateObservers(); |
-} |
- |
-// Triggered by a user action. |
-void DownloadItem::Cancel(bool update_history) { |
- // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- VLOG(20) << __FUNCTION__ << "() download = " << DebugString(true); |
- if (!IsPartialDownload()) { |
- // Small downloads might be complete before this method has |
- // a chance to run. |
- return; |
- } |
- |
- download_util::RecordDownloadCount(download_util::CANCELLED_COUNT); |
- |
- TransitionTo(CANCELLED); |
- StopProgressTimer(); |
- if (update_history) |
- download_manager_->DownloadCancelled(download_id_); |
-} |
- |
-void DownloadItem::MarkAsComplete() { |
- // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- DCHECK(all_data_saved_); |
- TransitionTo(COMPLETE); |
-} |
- |
-void DownloadItem::OnAllDataSaved(int64 size) { |
- // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- DCHECK(!all_data_saved_); |
- all_data_saved_ = true; |
- UpdateSize(size); |
- StopProgressTimer(); |
-} |
- |
-void DownloadItem::OnDownloadedFileRemoved() { |
- file_externally_removed_ = true; |
- UpdateObservers(); |
-} |
- |
-void DownloadItem::Completed() { |
- // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- VLOG(20) << __FUNCTION__ << "() " << DebugString(false); |
- |
- DCHECK(all_data_saved_); |
- TransitionTo(COMPLETE); |
- download_manager_->DownloadCompleted(id()); |
- download_util::RecordDownloadCompleted(start_tick_); |
- |
- if (is_extension_install()) { |
- // Extensions should already have been unpacked and opened. |
- DCHECK(auto_opened_); |
- } else if (open_when_complete() || |
- ShouldOpenFileBasedOnExtension() || |
- is_temporary()) { |
- // If the download is temporary, like in drag-and-drop, do not open it but |
- // we still need to set it auto-opened so that it can be removed from the |
- // download shelf. |
- if (!is_temporary()) |
- OpenDownload(); |
- |
- auto_opened_ = true; |
- UpdateObservers(); |
- } |
-} |
- |
-void DownloadItem::StartCrxInstall() { |
- // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- DCHECK(is_extension_install()); |
- DCHECK(all_data_saved_); |
- |
- scoped_refptr<CrxInstaller> crx_installer = |
- download_crx_util::OpenChromeExtension( |
- download_manager_->profile(), |
- *this); |
- |
- // CRX_INSTALLER_DONE will fire when the install completes. Observe() |
- // will call Completed() on this item. If this DownloadItem is not |
- // around when CRX_INSTALLER_DONE fires, Complete() will not be called. |
- registrar_.Add(this, |
- chrome::NOTIFICATION_CRX_INSTALLER_DONE, |
- Source<CrxInstaller>(crx_installer.get())); |
- |
- // The status text and percent complete indicator will change now |
- // that we are installing a CRX. Update observers so that they pick |
- // up the change. |
- UpdateObservers(); |
-} |
- |
-void DownloadItem::TransitionTo(DownloadState new_state) { |
- if (state_ == new_state) |
- return; |
- |
- state_ = new_state; |
- UpdateObservers(); |
-} |
- |
-void DownloadItem::UpdateSafetyState() { |
- SafetyState updated_value( |
- GetSafetyState(state_info_.is_dangerous_file, |
- state_info_.is_dangerous_url)); |
- if (updated_value != safety_state_) { |
- safety_state_ = updated_value; |
- UpdateObservers(); |
- } |
-} |
- |
-void DownloadItem::UpdateTarget() { |
- // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- if (state_info_.target_name.value().empty()) |
- state_info_.target_name = full_path_.BaseName(); |
-} |
- |
-// NotificationObserver implementation. |
-void DownloadItem::Observe(int type, |
- const NotificationSource& source, |
- const NotificationDetails& details) { |
- // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- DCHECK(type == chrome::NOTIFICATION_CRX_INSTALLER_DONE); |
- |
- // No need to listen for CRX_INSTALLER_DONE anymore. |
- registrar_.Remove(this, |
- chrome::NOTIFICATION_CRX_INSTALLER_DONE, |
- source); |
- |
- auto_opened_ = true; |
- DCHECK(all_data_saved_); |
- |
- Completed(); |
-} |
- |
-void DownloadItem::Interrupted(int64 size, int os_error) { |
- // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- if (!IsInProgress()) |
- return; |
- |
- last_os_error_ = os_error; |
- UpdateSize(size); |
- StopProgressTimer(); |
- download_util::RecordDownloadInterrupted(os_error, |
- received_bytes_, |
- total_bytes_); |
- TransitionTo(INTERRUPTED); |
-} |
- |
-void DownloadItem::Delete(DeleteReason reason) { |
- // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- switch (reason) { |
- case DELETE_DUE_TO_USER_DISCARD: |
- UMA_HISTOGRAM_ENUMERATION("Download.UserDiscard", GetDangerType(), |
- DANGEROUS_TYPE_MAX); |
- break; |
- case DELETE_DUE_TO_BROWSER_SHUTDOWN: |
- UMA_HISTOGRAM_ENUMERATION("Download.Discard", GetDangerType(), |
- DANGEROUS_TYPE_MAX); |
- break; |
- default: |
- NOTREACHED(); |
- } |
- |
- BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
- NewRunnableFunction(&DeleteDownloadedFile, full_path_)); |
- Remove(); |
- // We have now been deleted. |
-} |
- |
-void DownloadItem::Remove() { |
- // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- download_manager_->AssertQueueStateConsistent(this); |
- Cancel(true); |
- download_manager_->AssertQueueStateConsistent(this); |
- |
- TransitionTo(REMOVING); |
- download_manager_->RemoveDownload(db_handle_); |
- // We have now been deleted. |
-} |
- |
-bool DownloadItem::TimeRemaining(base::TimeDelta* remaining) const { |
- if (total_bytes_ <= 0) |
- return false; // We never received the content_length for this download. |
- |
- int64 speed = CurrentSpeed(); |
- if (speed == 0) |
- return false; |
- |
- *remaining = base::TimeDelta::FromSeconds( |
- (total_bytes_ - received_bytes_) / speed); |
- return true; |
-} |
- |
-int64 DownloadItem::CurrentSpeed() const { |
- if (is_paused_) |
- return 0; |
- base::TimeDelta diff = base::TimeTicks::Now() - start_tick_; |
- int64 diff_ms = diff.InMilliseconds(); |
- return diff_ms == 0 ? 0 : received_bytes_ * 1000 / diff_ms; |
-} |
- |
-int DownloadItem::PercentComplete() const { |
- // We don't have an accurate way to estimate the time to unpack a CRX. |
- // The slowest part is re-encoding images, and time to do this depends on |
- // the contents of the image. If a CRX is being unpacked, indicate that |
- // we do not know how close to completion we are. |
- if (IsCrxInstallRuning() || total_bytes_ <= 0) |
- return -1; |
- |
- return static_cast<int>(received_bytes_ * 100.0 / total_bytes_); |
-} |
- |
-void DownloadItem::OnPathDetermined(const FilePath& path) { |
- full_path_ = path; |
- UpdateTarget(); |
-} |
- |
-void DownloadItem::Rename(const FilePath& full_path) { |
- // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- VLOG(20) << __FUNCTION__ << "()" |
- << " full_path = \"" << full_path.value() << "\"" |
- << " " << DebugString(true); |
- DCHECK(!full_path.empty()); |
- full_path_ = full_path; |
-} |
- |
-void DownloadItem::TogglePause() { |
- // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- DCHECK(IsInProgress()); |
- if (is_paused_) |
- request_handle_.ResumeRequest(); |
- else |
- request_handle_.PauseRequest(); |
- is_paused_ = !is_paused_; |
- UpdateObservers(); |
-} |
- |
-void DownloadItem::OnDownloadCompleting(DownloadFileManager* file_manager) { |
- // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- VLOG(20) << __FUNCTION__ << "()" |
- << " needs rename = " << NeedsRename() |
- << " " << DebugString(true); |
- DCHECK_NE(DANGEROUS, safety_state()); |
- DCHECK(file_manager); |
- |
- if (NeedsRename()) { |
- BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
- NewRunnableMethod(file_manager, |
- &DownloadFileManager::RenameCompletingDownloadFile, id(), |
- GetTargetFilePath(), safety_state() == SAFE)); |
- return; |
- } |
- |
- DCHECK(!is_extension_install()); |
- Completed(); |
- |
- BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
- NewRunnableMethod(file_manager, &DownloadFileManager::CompleteDownload, |
- id())); |
-} |
- |
-void DownloadItem::OnDownloadRenamedToFinalName(const FilePath& full_path) { |
- // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- VLOG(20) << __FUNCTION__ << "()" |
- << " full_path = \"" << full_path.value() << "\"" |
- << " needed rename = " << NeedsRename() |
- << " " << DebugString(false); |
- DCHECK(NeedsRename()); |
- |
- Rename(full_path); |
- |
- if (is_extension_install()) { |
- StartCrxInstall(); |
- // Completed() will be called when the installer finishes. |
- return; |
- } |
- |
- Completed(); |
-} |
- |
-bool DownloadItem::MatchesQuery(const string16& query) const { |
- if (query.empty()) |
- return true; |
- |
- DCHECK_EQ(query, base::i18n::ToLower(query)); |
- |
- string16 url_raw(base::i18n::ToLower(UTF8ToUTF16(GetURL().spec()))); |
- if (url_raw.find(query) != string16::npos) |
- return true; |
- |
- // TODO(phajdan.jr): write a test case for the following code. |
- // A good test case would be: |
- // "/\xe4\xbd\xa0\xe5\xa5\xbd\xe4\xbd\xa0\xe5\xa5\xbd", |
- // L"/\x4f60\x597d\x4f60\x597d", |
- // "/%E4%BD%A0%E5%A5%BD%E4%BD%A0%E5%A5%BD" |
- PrefService* prefs = download_manager_->profile()->GetPrefs(); |
- std::string languages(prefs->GetString(prefs::kAcceptLanguages)); |
- string16 url_formatted( |
- base::i18n::ToLower(net::FormatUrl(GetURL(), languages))); |
- if (url_formatted.find(query) != string16::npos) |
- return true; |
- |
- string16 path(base::i18n::ToLower(full_path().LossyDisplayName())); |
- // This shouldn't just do a substring match; it is wrong for Unicode |
- // due to normalization and we have a fancier search-query system |
- // used elsewhere. |
- // http://code.google.com/p/chromium/issues/detail?id=71982 |
- return (path.find(query) != string16::npos); |
-} |
- |
-void DownloadItem::SetFileCheckResults(const DownloadStateInfo& state) { |
- // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- VLOG(20) << " " << __FUNCTION__ << "()" << " this = " << DebugString(true); |
- state_info_ = state; |
- VLOG(20) << " " << __FUNCTION__ << "()" << " this = " << DebugString(true); |
- |
- UpdateSafetyState(); |
-} |
- |
-DownloadItem::DangerType DownloadItem::GetDangerType() const { |
- return ::GetDangerType(state_info_.is_dangerous_file, |
- state_info_.is_dangerous_url); |
-} |
- |
-bool DownloadItem::IsDangerous() const { |
- return GetDangerType() != DownloadItem::NOT_DANGEROUS; |
-} |
- |
-void DownloadItem::MarkFileDangerous() { |
- // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- state_info_.is_dangerous_file = true; |
- UpdateSafetyState(); |
-} |
- |
-void DownloadItem::MarkUrlDangerous() { |
- // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- state_info_.is_dangerous_url = true; |
- UpdateSafetyState(); |
-} |
- |
-DownloadHistoryInfo DownloadItem::GetHistoryInfo() const { |
- return DownloadHistoryInfo(full_path(), |
- GetURL(), |
- referrer_url(), |
- start_time(), |
- received_bytes(), |
- total_bytes(), |
- state(), |
- db_handle()); |
-} |
- |
-FilePath DownloadItem::GetTargetFilePath() const { |
- return full_path_.DirName().Append(state_info_.target_name); |
-} |
- |
-FilePath DownloadItem::GetFileNameToReportUser() const { |
- if (state_info_.path_uniquifier > 0) { |
- FilePath name(state_info_.target_name); |
- download_util::AppendNumberToPath(&name, state_info_.path_uniquifier); |
- return name; |
- } |
- return state_info_.target_name; |
-} |
- |
-FilePath DownloadItem::GetUserVerifiedFilePath() const { |
- return (safety_state_ == DownloadItem::SAFE) ? |
- GetTargetFilePath() : full_path_; |
-} |
- |
-void DownloadItem::Init(bool active) { |
- // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- UpdateTarget(); |
- if (active) { |
- StartProgressTimer(); |
- download_util::RecordDownloadCount(download_util::START_COUNT); |
- } |
- VLOG(20) << __FUNCTION__ << "() " << DebugString(true); |
-} |
- |
-// TODO(ahendrickson) -- Move |INTERRUPTED| from |IsCancelled()| to |
-// |IsPartialDownload()|, when resuming interrupted downloads is implemented. |
-bool DownloadItem::IsPartialDownload() const { |
- return (state_ == IN_PROGRESS); |
-} |
- |
-bool DownloadItem::IsInProgress() const { |
- return (state_ == IN_PROGRESS); |
-} |
- |
-bool DownloadItem::IsCancelled() const { |
- return (state_ == CANCELLED) || |
- (state_ == INTERRUPTED); |
-} |
- |
-bool DownloadItem::IsInterrupted() const { |
- return (state_ == INTERRUPTED); |
-} |
- |
-bool DownloadItem::IsComplete() const { |
- return (state_ == COMPLETE); |
-} |
- |
-const GURL& DownloadItem::GetURL() const { |
- return url_chain_.empty() ? |
- GURL::EmptyGURL() : url_chain_.back(); |
-} |
- |
-std::string DownloadItem::DebugString(bool verbose) const { |
- std::string description = |
- base::StringPrintf("{ id = %d" |
- " state = %s", |
- download_id_, |
- DebugDownloadStateString(state())); |
- |
- // Construct a string of the URL chain. |
- std::string url_list("<none>"); |
- if (!url_chain_.empty()) { |
- std::vector<GURL>::const_iterator iter = url_chain_.begin(); |
- std::vector<GURL>::const_iterator last = url_chain_.end(); |
- url_list = (*iter).spec(); |
- ++iter; |
- for ( ; verbose && (iter != last); ++iter) { |
- url_list += " ->\n\t"; |
- const GURL& next_url = *iter; |
- url_list += next_url.spec(); |
- } |
- } |
- |
- if (verbose) { |
- description += base::StringPrintf( |
- " db_handle = %" PRId64 |
- " total_bytes = %" PRId64 |
- " received_bytes = %" PRId64 |
- " is_paused = %c" |
- " is_extension_install = %c" |
- " is_otr = %c" |
- " safety_state = %s" |
- " url_chain = \n\t\"%s\"\n\t" |
- " target_name = \"%" PRFilePath "\"" |
- " full_path = \"%" PRFilePath "\"", |
- db_handle(), |
- total_bytes(), |
- received_bytes(), |
- is_paused() ? 'T' : 'F', |
- is_extension_install() ? 'T' : 'F', |
- is_otr() ? 'T' : 'F', |
- DebugSafetyStateString(safety_state()), |
- url_list.c_str(), |
- state_info_.target_name.value().c_str(), |
- full_path().value().c_str()); |
- } else { |
- description += base::StringPrintf(" url = \"%s\"", url_list.c_str()); |
- } |
- |
- description += " }"; |
- |
- return description; |
-} |