#include "components/download/public/common/download_item_impl.h"
#include <memory>
#include <optional>
#include <utility>
#include <vector>
#include "base/files/file_util.h"
#include "base/format_macros.h"
#include "base/functional/bind.h"
#include "base/json/string_escape.h"
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/observer_list.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/sequenced_task_runner.h"
#include "base/trace_event/memory_usage_estimator.h"
#include "base/trace_event/trace_event.h"
#include "base/uuid.h"
#include "build/build_config.h"
#include "components/download/internal/common/download_job_impl.h"
#include "components/download/internal/common/parallel_download_utils.h"
#include "components/download/public/common/download_danger_type.h"
#include "components/download/public/common/download_features.h"
#include "components/download/public/common/download_file.h"
#include "components/download/public/common/download_interrupt_reasons.h"
#include "components/download/public/common/download_item_impl_delegate.h"
#include "components/download/public/common/download_item_rename_handler.h"
#include "components/download/public/common/download_job_factory.h"
#include "components/download/public/common/download_stats.h"
#include "components/download/public/common/download_task_runner.h"
#include "components/download/public/common/download_ukm_helper.h"
#include "components/download/public/common/download_url_parameters.h"
#include "components/download/public/common/download_utils.h"
#include "net/base/network_change_notifier.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/referrer_policy.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#if BUILDFLAG(IS_ANDROID)
#include "components/download/internal/common/android/download_collection_bridge.h"
#endif
#if BUILDFLAG(IS_MAC)
#include "base/mac/mac_util.h"
#endif
namespace download {
namespace {
void DeleteDownloadedFileDone(base::WeakPtr<DownloadItemImpl> item,
base::OnceCallback<void(bool)> callback,
bool success) { … }
base::FilePath DownloadFileDetach(std::unique_ptr<DownloadFile> download_file) { … }
base::FilePath MakeCopyOfDownloadFile(DownloadFile* download_file) { … }
void DownloadFileCancel(std::unique_ptr<DownloadFile> download_file) { … }
bool IsCancellation(DownloadInterruptReason reason) { … }
std::string GetDownloadCreationTypeNames(
DownloadItem::DownloadCreationType type) { … }
std::string GetDownloadDangerNames(DownloadDangerType type) { … }
class DownloadItemActivatedData
: public base::trace_event::ConvertableToTraceFormat { … };
}
const int DownloadItemImpl::kMaxAutoResumeAttempts = …;
DownloadItemImpl::RequestInfo::RequestInfo(
const std::vector<GURL>& url_chain,
const GURL& referrer_url,
const std::string& serialized_embedder_download_data,
const GURL& tab_url,
const GURL& tab_referrer_url,
const std::optional<url::Origin>& request_initiator,
const std::string& suggested_filename,
const base::FilePath& forced_file_path,
ui::PageTransition transition_type,
bool has_user_gesture,
const std::string& remote_address,
base::Time start_time,
::network::mojom::CredentialsMode credentials_mode,
const std::optional<net::IsolationInfo>& isolation_info,
int64_t range_request_from,
int64_t range_request_to)
: … { … }
DownloadItemImpl::RequestInfo::RequestInfo(const GURL& url)
: … { … }
DownloadItemImpl::RequestInfo::RequestInfo() = default;
DownloadItemImpl::RequestInfo::RequestInfo(
const DownloadItemImpl::RequestInfo& other) = default;
DownloadItemImpl::RequestInfo::~RequestInfo() = default;
DownloadItemImpl::DestinationInfo::DestinationInfo(
const base::FilePath& target_path,
const base::FilePath& current_path,
int64_t received_bytes,
bool all_data_saved,
const std::string& hash,
base::Time end_time)
: … { … }
DownloadItemImpl::DestinationInfo::DestinationInfo(
TargetDisposition target_disposition)
: … { … }
DownloadItemImpl::DestinationInfo::DestinationInfo() = default;
DownloadItemImpl::DestinationInfo::DestinationInfo(
const DownloadItemImpl::DestinationInfo& other) = default;
DownloadItemImpl::DestinationInfo::~DestinationInfo() = default;
DownloadItemImpl::DownloadItemImpl(
DownloadItemImplDelegate* delegate,
const std::string& guid,
uint32_t download_id,
const base::FilePath& current_path,
const base::FilePath& target_path,
const std::vector<GURL>& url_chain,
const GURL& referrer_url,
const std::string& serialized_embedder_download_data,
const GURL& tab_url,
const GURL& tab_refererr_url,
const std::optional<url::Origin>& request_initiator,
const std::string& mime_type,
const std::string& original_mime_type,
base::Time start_time,
base::Time end_time,
const std::string& etag,
const std::string& last_modified,
int64_t received_bytes,
int64_t total_bytes,
int32_t auto_resume_count,
const std::string& hash,
DownloadItem::DownloadState state,
DownloadDangerType danger_type,
DownloadInterruptReason interrupt_reason,
bool paused,
bool allow_metered,
bool opened,
base::Time last_access_time,
bool transient,
const std::vector<DownloadItem::ReceivedSlice>& received_slices,
int64_t range_request_from,
int64_t range_request_to,
std::unique_ptr<DownloadEntry> download_entry)
: … { … }
DownloadItemImpl::DownloadItemImpl(DownloadItemImplDelegate* delegate,
uint32_t download_id,
const DownloadCreateInfo& info)
: … { … }
DownloadItemImpl::DownloadItemImpl(
DownloadItemImplDelegate* delegate,
uint32_t download_id,
const base::FilePath& path,
const GURL& url,
const std::string& mime_type,
DownloadJob::CancelRequestCallback cancel_request_callback)
: … { … }
DownloadItemImpl::~DownloadItemImpl() { … }
void DownloadItemImpl::AddObserver(Observer* observer) { … }
void DownloadItemImpl::RemoveObserver(Observer* observer) { … }
void DownloadItemImpl::UpdateObservers() { … }
void DownloadItemImpl::ValidateDangerousDownload() { … }
void DownloadItemImpl::ValidateInsecureDownload() { … }
void DownloadItemImpl::StealDangerousDownload(bool delete_file_afterward,
AcquireFileCallback callback) { … }
void DownloadItemImpl::Pause() { … }
void DownloadItemImpl::Resume(bool user_resume) { … }
void DownloadItemImpl::UpdateResumptionInfo(bool user_resume) { … }
void DownloadItemImpl::Cancel(bool user_cancel) { … }
void DownloadItemImpl::Remove() { … }
void DownloadItemImpl::OpenDownload() { … }
void DownloadItemImpl::ShowDownloadInShell() { … }
void DownloadItemImpl::RenameDownloadedFileDone(
RenameDownloadCallback callback,
const base::FilePath& display_name,
DownloadRenameResult result) { … }
void DownloadItemImpl::Rename(const base::FilePath& display_name,
DownloadItem::RenameDownloadCallback callback) { … }
uint32_t DownloadItemImpl::GetId() const { … }
const std::string& DownloadItemImpl::GetGuid() const { … }
DownloadItem::DownloadState DownloadItemImpl::GetState() const { … }
DownloadInterruptReason DownloadItemImpl::GetLastReason() const { … }
bool DownloadItemImpl::IsPaused() const { … }
bool DownloadItemImpl::AllowMetered() const { … }
bool DownloadItemImpl::IsTemporary() const { … }
bool DownloadItemImpl::CanResume() const { … }
bool DownloadItemImpl::IsDone() const { … }
int64_t DownloadItemImpl::GetBytesWasted() const { … }
int32_t DownloadItemImpl::GetAutoResumeCount() const { … }
const GURL& DownloadItemImpl::GetURL() const { … }
const std::vector<GURL>& DownloadItemImpl::GetUrlChain() const { … }
const GURL& DownloadItemImpl::GetOriginalUrl() const { … }
const GURL& DownloadItemImpl::GetReferrerUrl() const { … }
const std::string& DownloadItemImpl::GetSerializedEmbedderDownloadData() const { … }
const GURL& DownloadItemImpl::GetTabUrl() const { … }
const GURL& DownloadItemImpl::GetTabReferrerUrl() const { … }
const std::optional<url::Origin>& DownloadItemImpl::GetRequestInitiator()
const { … }
std::string DownloadItemImpl::GetSuggestedFilename() const { … }
const scoped_refptr<const net::HttpResponseHeaders>&
DownloadItemImpl::GetResponseHeaders() const { … }
std::string DownloadItemImpl::GetContentDisposition() const { … }
std::string DownloadItemImpl::GetMimeType() const { … }
std::string DownloadItemImpl::GetOriginalMimeType() const { … }
std::string DownloadItemImpl::GetRemoteAddress() const { … }
bool DownloadItemImpl::HasUserGesture() const { … }
ui::PageTransition DownloadItemImpl::GetTransitionType() const { … }
const std::string& DownloadItemImpl::GetLastModifiedTime() const { … }
const std::string& DownloadItemImpl::GetETag() const { … }
bool DownloadItemImpl::IsSavePackageDownload() const { … }
DownloadSource DownloadItemImpl::GetDownloadSource() const { … }
const base::FilePath& DownloadItemImpl::GetFullPath() const { … }
const base::FilePath& DownloadItemImpl::GetTargetFilePath() const { … }
const base::FilePath& DownloadItemImpl::GetForcedFilePath() const { … }
base::FilePath DownloadItemImpl::GetTemporaryFilePath() const { … }
base::FilePath DownloadItemImpl::GetFileNameToReportUser() const { … }
DownloadItem::TargetDisposition DownloadItemImpl::GetTargetDisposition() const { … }
const std::string& DownloadItemImpl::GetHash() const { … }
bool DownloadItemImpl::GetFileExternallyRemoved() const { … }
void DownloadItemImpl::DeleteFile(base::OnceCallback<void(bool)> callback) { … }
DownloadFile* DownloadItemImpl::GetDownloadFile() { … }
DownloadItemRenameHandler* DownloadItemImpl::GetRenameHandler() { … }
#if BUILDFLAG(IS_ANDROID)
bool DownloadItemImpl::IsFromExternalApp() {
return is_from_external_app_;
}
bool DownloadItemImpl::IsMustDownload() {
return is_must_download_;
}
#endif
bool DownloadItemImpl::IsDangerous() const { … }
bool DownloadItemImpl::IsInsecure() const { … }
DownloadDangerType DownloadItemImpl::GetDangerType() const { … }
DownloadItem::InsecureDownloadStatus
DownloadItemImpl::GetInsecureDownloadStatus() const { … }
bool DownloadItemImpl::TimeRemaining(base::TimeDelta* remaining) const { … }
int64_t DownloadItemImpl::CurrentSpeed() const { … }
int DownloadItemImpl::PercentComplete() const { … }
bool DownloadItemImpl::AllDataSaved() const { … }
int64_t DownloadItemImpl::GetTotalBytes() const { … }
int64_t DownloadItemImpl::GetReceivedBytes() const { … }
const std::vector<DownloadItem::ReceivedSlice>&
DownloadItemImpl::GetReceivedSlices() const { … }
int64_t DownloadItemImpl::GetUploadedBytes() const { … }
base::Time DownloadItemImpl::GetStartTime() const { … }
base::Time DownloadItemImpl::GetEndTime() const { … }
bool DownloadItemImpl::CanShowInFolder() { … }
bool DownloadItemImpl::CanOpenDownload() { … }
bool DownloadItemImpl::ShouldOpenFileBasedOnExtension() { … }
bool DownloadItemImpl::ShouldOpenFileByPolicyBasedOnExtension() { … }
bool DownloadItemImpl::GetOpenWhenComplete() const { … }
bool DownloadItemImpl::GetAutoOpened() { … }
bool DownloadItemImpl::GetOpened() const { … }
base::Time DownloadItemImpl::GetLastAccessTime() const { … }
bool DownloadItemImpl::IsTransient() const { … }
bool DownloadItemImpl::RequireSafetyChecks() const { … }
bool DownloadItemImpl::IsParallelDownload() const { … }
DownloadItem::DownloadCreationType DownloadItemImpl::GetDownloadCreationType()
const { … }
::network::mojom::CredentialsMode DownloadItemImpl::GetCredentialsMode() const { … }
const std::optional<net::IsolationInfo>& DownloadItemImpl::GetIsolationInfo()
const { … }
void DownloadItemImpl::OnContentCheckCompleted(DownloadDangerType danger_type,
DownloadInterruptReason reason) { … }
void DownloadItemImpl::OnAsyncScanningCompleted(
DownloadDangerType danger_type) { … }
void DownloadItemImpl::SetOpenWhenComplete(bool open) { … }
void DownloadItemImpl::SetOpened(bool opened) { … }
void DownloadItemImpl::SetLastAccessTime(base::Time last_access_time) { … }
void DownloadItemImpl::SetDisplayName(const base::FilePath& name) { … }
std::string DownloadItemImpl::DebugString(bool verbose) const { … }
void DownloadItemImpl::SimulateErrorForTesting(DownloadInterruptReason reason) { … }
ResumeMode DownloadItemImpl::GetResumeMode() const { … }
bool DownloadItemImpl::HasStrongValidators() const { … }
void DownloadItemImpl::BindWakeLockProvider(
mojo::PendingReceiver<device::mojom::WakeLockProvider> receiver) { … }
void DownloadItemImpl::UpdateValidatorsOnResumption(
const DownloadCreateInfo& new_create_info) { … }
void DownloadItemImpl::NotifyRemoved() { … }
void DownloadItemImpl::OnDownloadedFileRemoved() { … }
base::WeakPtr<DownloadDestinationObserver>
DownloadItemImpl::DestinationObserverAsWeakPtr() { … }
void DownloadItemImpl::SetTotalBytes(int64_t total_bytes) { … }
void DownloadItemImpl::OnAllDataSaved(
int64_t total_bytes,
std::unique_ptr<crypto::SecureHash> hash_state) { … }
void DownloadItemImpl::MarkAsComplete() { … }
void DownloadItemImpl::DestinationUpdate(
int64_t bytes_so_far,
int64_t bytes_per_sec,
const std::vector<DownloadItem::ReceivedSlice>& received_slices) { … }
void DownloadItemImpl::DestinationError(
DownloadInterruptReason reason,
int64_t bytes_so_far,
std::unique_ptr<crypto::SecureHash> secure_hash) { … }
void DownloadItemImpl::DestinationCompleted(
int64_t total_bytes,
std::unique_ptr<crypto::SecureHash> secure_hash) { … }
void DownloadItemImpl::SetDelegate(DownloadItemImplDelegate* delegate) { … }
void DownloadItemImpl::SetDownloadId(uint32_t download_id) { … }
void DownloadItemImpl::SetAutoResumeCountForTesting(int32_t auto_resume_count) { … }
void DownloadItemImpl::Init(bool active,
DownloadItem::DownloadCreationType download_type) { … }
void DownloadItemImpl::Start(
std::unique_ptr<DownloadFile> file,
DownloadJob::CancelRequestCallback cancel_request_callback,
const DownloadCreateInfo& new_create_info,
URLLoaderFactoryProvider::URLLoaderFactoryProviderPtr
url_loader_factory_provider) { … }
void DownloadItemImpl::OnDownloadFileInitialized(DownloadInterruptReason result,
int64_t bytes_wasted) { … }
void DownloadItemImpl::DetermineDownloadTarget() { … }
void DownloadItemImpl::OnDownloadTargetDetermined(
DownloadTargetInfo target_info) { … }
void DownloadItemImpl::OnDownloadRenamedToIntermediateName(
DownloadInterruptReason reason,
const base::FilePath& full_path) { … }
void DownloadItemImpl::OnTargetResolved() { … }
void DownloadItemImpl::MaybeCompleteDownload() { … }
void DownloadItemImpl::OnDownloadCompleting() { … }
void DownloadItemImpl::OnRenameAndAnnotateDone(
DownloadInterruptReason reason,
const base::FilePath& full_path) { … }
void DownloadItemImpl::OnDownloadRenamedToFinalName(
DownloadInterruptReason reason,
const base::FilePath& full_path) { … }
void DownloadItemImpl::DelayedDownloadOpened(bool auto_opened) { … }
void DownloadItemImpl::Completed() { … }
void DownloadItemImpl::InterruptAndDiscardPartialState(
DownloadInterruptReason reason) { … }
void DownloadItemImpl::InterruptWithPartialState(
int64_t bytes_so_far,
std::unique_ptr<crypto::SecureHash> hash_state,
DownloadInterruptReason reason) { … }
void DownloadItemImpl::UpdateProgress(int64_t bytes_so_far,
int64_t bytes_per_sec) { … }
void DownloadItemImpl::SetHashState(
std::unique_ptr<crypto::SecureHash> hash_state) { … }
void DownloadItemImpl::ReleaseDownloadFile(bool destroy_file) { … }
void DownloadItemImpl::DeleteDownloadFile() { … }
bool DownloadItemImpl::IsDownloadReadyForCompletion(
base::OnceClosure state_change_notification) { … }
void DownloadItemImpl::TransitionTo(DownloadInternalState new_state) { … }
void DownloadItemImpl::SetDangerType(DownloadDangerType danger_type) { … }
void DownloadItemImpl::SetFullPath(const base::FilePath& new_path) { … }
void DownloadItemImpl::AutoResumeIfValid() { … }
void DownloadItemImpl::ResumeInterruptedDownload(
ResumptionRequestSource source) { … }
DownloadItem::DownloadState DownloadItemImpl::InternalToExternalState(
DownloadInternalState internal_state) { … }
DownloadItemImpl::DownloadInternalState
DownloadItemImpl::ExternalToInternalState(DownloadState external_state) { … }
bool DownloadItemImpl::IsValidSavePackageStateTransition(
DownloadInternalState from,
DownloadInternalState to) { … }
bool DownloadItemImpl::IsValidStateTransition(DownloadInternalState from,
DownloadInternalState to) { … }
const char* DownloadItemImpl::DebugDownloadStateString(
DownloadInternalState state) { … }
const char* DownloadItemImpl::DebugResumeModeString(ResumeMode mode) { … }
std::pair<int64_t, int64_t> DownloadItemImpl::GetRangeRequestOffset() const { … }
void DownloadItemImpl::UpdateRenameProgress(int64_t bytes_so_far,
int64_t bytes_per_sec) { … }
}