diff options
Diffstat (limited to 'chromium/components/download/downloader')
18 files changed, 638 insertions, 19 deletions
diff --git a/chromium/components/download/downloader/in_progress/BUILD.gn b/chromium/components/download/downloader/in_progress/BUILD.gn index bd728e0ec35..fea2be16b81 100644 --- a/chromium/components/download/downloader/in_progress/BUILD.gn +++ b/chromium/components/download/downloader/in_progress/BUILD.gn @@ -9,13 +9,21 @@ if (is_android) { source_set("in_progress") { sources = [ + "download_db_entry.cc", + "download_db_entry.h", "download_entry.cc", "download_entry.h", + "download_info.cc", + "download_info.h", "in_progress_cache.h", "in_progress_cache_impl.cc", "in_progress_cache_impl.h", "in_progress_conversions.cc", "in_progress_conversions.h", + "in_progress_info.cc", + "in_progress_info.h", + "ukm_info.cc", + "ukm_info.h", ] deps = [ @@ -23,6 +31,7 @@ source_set("in_progress") { "//components/download/downloader/in_progress/proto", "//net", "//services/metrics/public/cpp:metrics_cpp", + "//services/network/public/mojom", ] } diff --git a/chromium/components/download/downloader/in_progress/download_db_entry.cc b/chromium/components/download/downloader/in_progress/download_db_entry.cc new file mode 100644 index 00000000000..b36192a39a6 --- /dev/null +++ b/chromium/components/download/downloader/in_progress/download_db_entry.cc @@ -0,0 +1,19 @@ +// Copyright 2018 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 "components/download/downloader/in_progress/download_db_entry.h" + +namespace download { + +DownloadDBEntry::DownloadDBEntry() = default; + +DownloadDBEntry::DownloadDBEntry(const DownloadDBEntry& other) = default; + +DownloadDBEntry::~DownloadDBEntry() = default; + +bool DownloadDBEntry::operator==(const DownloadDBEntry& other) const { + return id == other.id && download_info == other.download_info; +} + +} // namespace download diff --git a/chromium/components/download/downloader/in_progress/download_db_entry.h b/chromium/components/download/downloader/in_progress/download_db_entry.h new file mode 100644 index 00000000000..0aee2cf6175 --- /dev/null +++ b/chromium/components/download/downloader/in_progress/download_db_entry.h @@ -0,0 +1,33 @@ +// Copyright 2018 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. + +#ifndef COMPONENTS_DOWNLOAD_DOWNLOADER_IN_PROGRESS_DOWNLOAD_DB_ENTRY_H_ +#define COMPONENTS_DOWNLOAD_DOWNLOADER_IN_PROGRESS_DOWNLOAD_DB_ENTRY_H_ + +#include <string> + +#include "base/optional.h" +#include "components/download/downloader/in_progress/download_info.h" + +namespace download { + +// Representing one entry in the DownloadDB. +struct DownloadDBEntry { + public: + DownloadDBEntry(); + DownloadDBEntry(const DownloadDBEntry& other); + ~DownloadDBEntry(); + + bool operator==(const DownloadDBEntry& other) const; + + // ID of the entry, this should be namespace + GUID of the download. + std::string id; + + // Information about a regular download. + base::Optional<DownloadInfo> download_info; +}; + +} // namespace download + +#endif // COMPONENTS_DOWNLOAD_DOWNLOADER_IN_PROGRESS_DOWNLOAD_DB_ENTRY_H_ diff --git a/chromium/components/download/downloader/in_progress/download_entry.h b/chromium/components/download/downloader/in_progress/download_entry.h index 4881ae859a8..c06ac01e531 100644 --- a/chromium/components/download/downloader/in_progress/download_entry.h +++ b/chromium/components/download/downloader/in_progress/download_entry.h @@ -7,6 +7,7 @@ #include <string> +#include "components/download/public/common/download_item.h" #include "components/download/public/common/download_source.h" #include "components/download/public/common/download_url_parameters.h" #include "services/metrics/public/cpp/ukm_source_id.h" diff --git a/chromium/components/download/downloader/in_progress/download_info.cc b/chromium/components/download/downloader/in_progress/download_info.cc new file mode 100644 index 00000000000..80b7f6257d6 --- /dev/null +++ b/chromium/components/download/downloader/in_progress/download_info.cc @@ -0,0 +1,20 @@ +// Copyright 2018 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 "components/download/downloader/in_progress/download_info.h" + +namespace download { + +DownloadInfo::DownloadInfo() = default; + +DownloadInfo::DownloadInfo(const DownloadInfo& other) = default; + +DownloadInfo::~DownloadInfo() = default; + +bool DownloadInfo::operator==(const DownloadInfo& other) const { + return guid == other.guid && ukm_info == other.ukm_info && + in_progress_info == other.in_progress_info; +} + +} // namespace download diff --git a/chromium/components/download/downloader/in_progress/download_info.h b/chromium/components/download/downloader/in_progress/download_info.h new file mode 100644 index 00000000000..80085ee1406 --- /dev/null +++ b/chromium/components/download/downloader/in_progress/download_info.h @@ -0,0 +1,37 @@ +// Copyright 2018 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. + +#ifndef COMPONENTS_DOWNLOAD_DOWNLOADER_IN_PROGRESS_DOWNLOAD_INFO_H_ +#define COMPONENTS_DOWNLOAD_DOWNLOADER_IN_PROGRESS_DOWNLOAD_INFO_H_ + +#include <string> + +#include "base/optional.h" +#include "components/download/downloader/in_progress/in_progress_info.h" +#include "components/download/downloader/in_progress/ukm_info.h" + +namespace download { + +// Contains needed information to reconstruct a download item. +struct DownloadInfo { + public: + DownloadInfo(); + DownloadInfo(const DownloadInfo& other); + ~DownloadInfo(); + + bool operator==(const DownloadInfo& other) const; + + // Download GUID. + std::string guid; + + // UKM information for reporting. + base::Optional<UkmInfo> ukm_info; + + // In progress information for active download. + base::Optional<InProgressInfo> in_progress_info; +}; + +} // namespace download + +#endif // COMPONENTS_DOWNLOAD_DOWNLOADER_IN_PROGRESS_DOWNLOAD_INFO_H_ diff --git a/chromium/components/download/downloader/in_progress/in_progress_cache.h b/chromium/components/download/downloader/in_progress/in_progress_cache.h index af2c859929d..02459c0e026 100644 --- a/chromium/components/download/downloader/in_progress/in_progress_cache.h +++ b/chromium/components/download/downloader/in_progress/in_progress_cache.h @@ -12,6 +12,8 @@ namespace download { +extern const base::FilePath::CharType kDownloadMetadataStoreFilename[]; + // InProgressCache provides a write-through cache that persists // information related to an in-progress download such as request origin, retry // count, resumption parameters etc to the disk. The entries are written to disk @@ -21,7 +23,7 @@ class InProgressCache { virtual ~InProgressCache() = default; // Initializes the cache. - virtual void Initialize(const base::RepeatingClosure& callback) = 0; + virtual void Initialize(base::OnceClosure callback) = 0; // Adds or updates an existing entry. virtual void AddOrReplaceEntry(const DownloadEntry& entry) = 0; diff --git a/chromium/components/download/downloader/in_progress/in_progress_cache_impl.cc b/chromium/components/download/downloader/in_progress/in_progress_cache_impl.cc index 5640de21ab9..6088307f523 100644 --- a/chromium/components/download/downloader/in_progress/in_progress_cache_impl.cc +++ b/chromium/components/download/downloader/in_progress/in_progress_cache_impl.cc @@ -14,6 +14,9 @@ namespace download { +const base::FilePath::CharType kDownloadMetadataStoreFilename[] = + FILE_PATH_LITERAL("in_progress_download_metadata_store"); + namespace { // Helper functions for |entries_| related operations. @@ -57,6 +60,9 @@ void RemoveEntryFromEntries(metadata_pb::DownloadEntries& entries, // Helper functions for file read/write operations. std::vector<char> ReadEntriesFromFile(base::FilePath file_path) { + if (file_path.empty()) + return std::vector<char>(); + // Check validity of file. base::File entries_file(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ); @@ -110,7 +116,8 @@ std::string EntriesToString(const metadata_pb::DownloadEntries& entries) { } void WriteEntriesToFile(const std::string& entries, base::FilePath file_path) { - DCHECK(!file_path.empty()); + if (file_path.empty()) + return; if (!base::ImportantFileWriter::WriteFileAtomically(file_path, entries)) { LOG(ERROR) << "Could not write download entries to file: " @@ -129,26 +136,26 @@ InProgressCacheImpl::InProgressCacheImpl( InProgressCacheImpl::~InProgressCacheImpl() = default; -void InProgressCacheImpl::Initialize(const base::RepeatingClosure& callback) { +void InProgressCacheImpl::Initialize(base::OnceClosure callback) { // If it's already initialized, just run the callback. if (initialization_status_ == CACHE_INITIALIZED) { - base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback); + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, + std::move(callback)); return; } - pending_actions_.push_back(callback); - // If uninitialized, initialize |entries_| by reading from file. if (initialization_status_ == CACHE_UNINITIALIZED) { base::PostTaskAndReplyWithResult( task_runner_.get(), FROM_HERE, base::BindOnce(&ReadEntriesFromFile, file_path_), base::BindOnce(&InProgressCacheImpl::OnInitialized, - weak_ptr_factory_.GetWeakPtr())); + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } } -void InProgressCacheImpl::OnInitialized(const std::vector<char>& entries) { +void InProgressCacheImpl::OnInitialized(base::OnceClosure callback, + const std::vector<char>& entries) { if (!entries.empty()) { if (!entries_.ParseFromArray(entries.data(), entries.size())) { // TODO(crbug.com/778425): Get UMA for errors. @@ -160,11 +167,7 @@ void InProgressCacheImpl::OnInitialized(const std::vector<char>& entries) { initialization_status_ = CACHE_INITIALIZED; - while (!pending_actions_.empty()) { - base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, - pending_actions_.front()); - pending_actions_.pop_front(); - } + std::move(callback).Run(); } void InProgressCacheImpl::AddOrReplaceEntry(const DownloadEntry& entry) { diff --git a/chromium/components/download/downloader/in_progress/in_progress_cache_impl.h b/chromium/components/download/downloader/in_progress/in_progress_cache_impl.h index 6dd5fcea7f9..23687e0b7b8 100644 --- a/chromium/components/download/downloader/in_progress/in_progress_cache_impl.h +++ b/chromium/components/download/downloader/in_progress/in_progress_cache_impl.h @@ -7,7 +7,6 @@ #include <string> -#include "base/containers/circular_deque.h" #include "base/files/file_path.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" @@ -24,13 +23,13 @@ namespace download { // right away. class InProgressCacheImpl : public InProgressCache { public: - explicit InProgressCacheImpl( + InProgressCacheImpl( const base::FilePath& cache_file_path, const scoped_refptr<base::SequencedTaskRunner>& task_runner); ~InProgressCacheImpl() override; // InProgressCache implementation. - void Initialize(const base::RepeatingClosure& callback) override; + void Initialize(base::OnceClosure callback) override; void AddOrReplaceEntry(const DownloadEntry& entry) override; base::Optional<DownloadEntry> RetrieveEntry(const std::string& guid) override; void RemoveEntry(const std::string& guid) override; @@ -44,12 +43,12 @@ class InProgressCacheImpl : public InProgressCache { }; // Steps to execute after initialization is complete. - void OnInitialized(const std::vector<char>& entries); + void OnInitialized(base::OnceClosure callback, + const std::vector<char>& entries); metadata_pb::DownloadEntries entries_; base::FilePath file_path_; InitializationStatus initialization_status_; - base::circular_deque<base::RepeatingClosure> pending_actions_; scoped_refptr<base::SequencedTaskRunner> task_runner_; base::WeakPtrFactory<InProgressCacheImpl> weak_ptr_factory_; diff --git a/chromium/components/download/downloader/in_progress/in_progress_cache_impl_unittest.cc b/chromium/components/download/downloader/in_progress/in_progress_cache_impl_unittest.cc index 12012af4938..8150815bf31 100644 --- a/chromium/components/download/downloader/in_progress/in_progress_cache_impl_unittest.cc +++ b/chromium/components/download/downloader/in_progress/in_progress_cache_impl_unittest.cc @@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/run_loop.h" +#include "base/sequenced_task_runner.h" #include "base/task_runner.h" #include "base/task_scheduler/post_task.h" #include "base/test/scoped_task_environment.h" diff --git a/chromium/components/download/downloader/in_progress/in_progress_conversions.cc b/chromium/components/download/downloader/in_progress/in_progress_conversions.cc index a5e3c8d819f..5620961d2c6 100644 --- a/chromium/components/download/downloader/in_progress/in_progress_conversions.cc +++ b/chromium/components/download/downloader/in_progress/in_progress_conversions.cc @@ -6,6 +6,7 @@ #include <utility> #include "base/logging.h" +#include "base/pickle.h" namespace download { @@ -37,7 +38,6 @@ metadata_pb::DownloadEntry InProgressConversions::DownloadEntryToProto( auto* proto_header = proto.add_request_headers(); *proto_header = HttpRequestHeaderToProto(header); } - return proto; } @@ -139,4 +139,151 @@ InProgressConversions::HttpRequestHeaderFromProto( return std::make_pair(proto.key(), proto.value()); } +// static +metadata_pb::InProgressInfo InProgressConversions::InProgressInfoToProto( + const InProgressInfo& in_progress_info) { + metadata_pb::InProgressInfo proto; + for (size_t i = 0; i < in_progress_info.url_chain.size(); ++i) + proto.add_url_chain(in_progress_info.url_chain[i].spec()); + proto.set_fetch_error_body(in_progress_info.fetch_error_body); + for (const auto& header : in_progress_info.request_headers) { + auto* proto_header = proto.add_request_headers(); + *proto_header = HttpRequestHeaderToProto(header); + } + proto.set_etag(in_progress_info.etag); + proto.set_last_modified(in_progress_info.last_modified); + proto.set_total_bytes(in_progress_info.total_bytes); + base::Pickle current_path; + in_progress_info.current_path.WriteToPickle(¤t_path); + proto.set_current_path(current_path.data(), current_path.size()); + base::Pickle target_path; + in_progress_info.target_path.WriteToPickle(&target_path); + proto.set_target_path(target_path.data(), target_path.size()); + proto.set_received_bytes(in_progress_info.received_bytes); + proto.set_end_time( + in_progress_info.end_time.ToDeltaSinceWindowsEpoch().InMilliseconds()); + for (size_t i = 0; i < in_progress_info.received_slices.size(); ++i) { + metadata_pb::ReceivedSlice* slice = proto.add_received_slices(); + slice->set_received_bytes( + in_progress_info.received_slices[i].received_bytes); + slice->set_offset(in_progress_info.received_slices[i].offset); + slice->set_finished(in_progress_info.received_slices[i].finished); + } + proto.set_hash(in_progress_info.hash); + proto.set_transient(in_progress_info.transient); + proto.set_state(in_progress_info.state); + proto.set_danger_type(in_progress_info.danger_type); + proto.set_interrupt_reason(in_progress_info.interrupt_reason); + proto.set_paused(in_progress_info.paused); + proto.set_metered(in_progress_info.metered); + proto.set_request_origin(in_progress_info.request_origin); + proto.set_bytes_wasted(in_progress_info.bytes_wasted); + return proto; +} + +// static +InProgressInfo InProgressConversions::InProgressInfoFromProto( + const metadata_pb::InProgressInfo& proto) { + InProgressInfo info; + for (const auto& url : proto.url_chain()) + info.url_chain.emplace_back(url); + info.fetch_error_body = proto.fetch_error_body(); + for (const auto& header : proto.request_headers()) + info.request_headers.emplace_back(HttpRequestHeaderFromProto(header)); + info.etag = proto.etag(); + info.last_modified = proto.last_modified(); + info.total_bytes = proto.total_bytes(); + base::PickleIterator current_path( + base::Pickle(proto.current_path().data(), proto.current_path().size())); + info.current_path.ReadFromPickle(¤t_path); + base::PickleIterator target_path( + base::Pickle(proto.target_path().data(), proto.target_path().size())); + info.target_path.ReadFromPickle(&target_path); + info.received_bytes = proto.received_bytes(); + info.end_time = base::Time::FromDeltaSinceWindowsEpoch( + base::TimeDelta::FromMilliseconds(proto.end_time())); + + for (int i = 0; i < proto.received_slices_size(); ++i) { + info.received_slices.emplace_back(proto.received_slices(i).offset(), + proto.received_slices(i).received_bytes(), + proto.received_slices(i).finished()); + } + info.hash = proto.hash(); + info.transient = proto.transient(); + info.state = static_cast<DownloadItem::DownloadState>(proto.state()); + info.danger_type = static_cast<DownloadDangerType>(proto.danger_type()); + info.interrupt_reason = + static_cast<DownloadInterruptReason>(proto.interrupt_reason()); + info.paused = proto.paused(); + info.metered = proto.metered(); + info.request_origin = proto.request_origin(); + info.bytes_wasted = proto.bytes_wasted(); + return info; +} + +UkmInfo InProgressConversions::UkmInfoFromProto( + const metadata_pb::UkmInfo& proto) { + UkmInfo info; + info.download_source = DownloadSourceFromProto(proto.download_source()); + info.ukm_download_id = proto.ukm_download_id(); + return info; +} + +metadata_pb::UkmInfo InProgressConversions::UkmInfoToProto( + const UkmInfo& info) { + metadata_pb::UkmInfo proto; + proto.set_download_source(DownloadSourceToProto(info.download_source)); + proto.set_ukm_download_id(info.ukm_download_id); + return proto; +} + +DownloadInfo InProgressConversions::DownloadInfoFromProto( + const metadata_pb::DownloadInfo& proto) { + DownloadInfo info; + info.guid = proto.guid(); + if (proto.has_ukm_info()) + info.ukm_info = UkmInfoFromProto(proto.ukm_info()); + if (proto.has_in_progress_info()) + info.in_progress_info = InProgressInfoFromProto(proto.in_progress_info()); + return info; +} + +metadata_pb::DownloadInfo InProgressConversions::DownloadInfoToProto( + const DownloadInfo& info) { + metadata_pb::DownloadInfo proto; + proto.set_guid(info.guid); + if (info.ukm_info.has_value()) { + auto ukm_info = std::make_unique<metadata_pb::UkmInfo>( + UkmInfoToProto(info.ukm_info.value())); + proto.set_allocated_ukm_info(ukm_info.release()); + } + if (info.in_progress_info.has_value()) { + auto in_progress_info = std::make_unique<metadata_pb::InProgressInfo>( + InProgressInfoToProto(info.in_progress_info.value())); + proto.set_allocated_in_progress_info(in_progress_info.release()); + } + return proto; +} + +DownloadDBEntry InProgressConversions::DownloadDBEntryFromProto( + const metadata_pb::DownloadDBEntry& proto) { + DownloadDBEntry entry; + entry.id = proto.id(); + if (proto.has_download_info()) + entry.download_info = DownloadInfoFromProto(proto.download_info()); + return entry; +} + +metadata_pb::DownloadDBEntry InProgressConversions::DownloadDBEntryToProto( + const DownloadDBEntry& info) { + metadata_pb::DownloadDBEntry proto; + proto.set_id(info.id); + if (info.download_info.has_value()) { + auto download_info = std::make_unique<metadata_pb::DownloadInfo>( + DownloadInfoToProto(info.download_info.value())); + proto.set_allocated_download_info(download_info.release()); + } + return proto; +} + } // namespace download diff --git a/chromium/components/download/downloader/in_progress/in_progress_conversions.h b/chromium/components/download/downloader/in_progress/in_progress_conversions.h index d5b97cc8497..e95f6084bba 100644 --- a/chromium/components/download/downloader/in_progress/in_progress_conversions.h +++ b/chromium/components/download/downloader/in_progress/in_progress_conversions.h @@ -6,9 +6,13 @@ #define COMPONENTS_DOWNLOAD_IN_PROGRESS_IN_PROGRESS_CONVERSIONS_H_ #include "base/macros.h" +#include "components/download/downloader/in_progress/download_db_entry.h" #include "components/download/downloader/in_progress/download_entry.h" +#include "components/download/downloader/in_progress/download_info.h" +#include "components/download/downloader/in_progress/in_progress_info.h" #include "components/download/downloader/in_progress/proto/download_entry.pb.h" #include "components/download/downloader/in_progress/proto/download_source.pb.h" +#include "components/download/downloader/in_progress/ukm_info.h" namespace download { @@ -37,6 +41,28 @@ class InProgressConversions { static std::pair<std::string, std::string> HttpRequestHeaderFromProto( const metadata_pb::HttpRequestHeader& proto); + + static metadata_pb::InProgressInfo InProgressInfoToProto( + const InProgressInfo& in_progress_info); + + static InProgressInfo InProgressInfoFromProto( + const metadata_pb::InProgressInfo& proto); + + static metadata_pb::UkmInfo UkmInfoToProto(const UkmInfo& ukm_info); + + static UkmInfo UkmInfoFromProto(const metadata_pb::UkmInfo& proto); + + static metadata_pb::DownloadInfo DownloadInfoToProto( + const DownloadInfo& download_info); + + static DownloadInfo DownloadInfoFromProto( + const metadata_pb::DownloadInfo& proto); + + static metadata_pb::DownloadDBEntry DownloadDBEntryToProto( + const DownloadDBEntry& entry); + + static DownloadDBEntry DownloadDBEntryFromProto( + const metadata_pb::DownloadDBEntry& proto); }; } // namespace download diff --git a/chromium/components/download/downloader/in_progress/in_progress_conversions_unittest.cc b/chromium/components/download/downloader/in_progress/in_progress_conversions_unittest.cc index 4fcda352b45..df5fb673b1c 100644 --- a/chromium/components/download/downloader/in_progress/in_progress_conversions_unittest.cc +++ b/chromium/components/download/downloader/in_progress/in_progress_conversions_unittest.cc @@ -9,6 +9,48 @@ namespace download { +namespace { + +InProgressInfo CreateInProgressInfo() { + InProgressInfo info; + // InProgressInfo with valid fields. + info.current_path = base::FilePath(FILE_PATH_LITERAL("/tmp.crdownload")); + info.target_path = base::FilePath(FILE_PATH_LITERAL("/tmp")); + info.url_chain.emplace_back("http://foo"); + info.url_chain.emplace_back("http://foo2"); + info.end_time = base::Time::NowFromSystemTime().LocalMidnight(); + info.etag = "A"; + info.last_modified = "Wed, 1 Oct 2018 07:00:00 GMT"; + info.received_bytes = 1000; + info.total_bytes = 10000; + info.state = DownloadItem::IN_PROGRESS; + info.danger_type = DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS; + info.interrupt_reason = DOWNLOAD_INTERRUPT_REASON_NONE; + info.transient = false; + info.paused = false; + info.hash = "abcdefg"; + info.metered = true; + info.received_slices.emplace_back(0, 500, false); + info.received_slices.emplace_back(5000, 500, false); + info.request_origin = "request origin"; + info.bytes_wasted = 1234; + info.fetch_error_body = true; + info.request_headers.emplace_back( + std::make_pair<std::string, std::string>("123", "456")); + info.request_headers.emplace_back( + std::make_pair<std::string, std::string>("ABC", "def")); + return info; +} + +DownloadInfo CreateDownloadInfo() { + DownloadInfo info; + info.in_progress_info = CreateInProgressInfo(); + info.ukm_info = UkmInfo(DownloadSource::FROM_RENDERER, 100); + return info; +} + +} // namespace + class InProgressConversionsTest : public testing::Test, public InProgressConversions { public: @@ -79,4 +121,38 @@ TEST_F(InProgressConversionsTest, HttpRequestHeaders) { HttpRequestHeaderFromProto(HttpRequestHeaderToProto(header))); } +TEST_F(InProgressConversionsTest, InProgressInfo) { + // InProgressInfo with no fields. + InProgressInfo info; + EXPECT_EQ(false, info.fetch_error_body); + EXPECT_TRUE(info.request_headers.empty()); + EXPECT_EQ(info, InProgressInfoFromProto(InProgressInfoToProto(info))); + + // InProgressInfo with valid fields. + info = CreateInProgressInfo(); + EXPECT_EQ(info, InProgressInfoFromProto(InProgressInfoToProto(info))); +} + +TEST_F(InProgressConversionsTest, UkmInfo) { + UkmInfo info(DownloadSource::FROM_RENDERER, 100); + EXPECT_EQ(info, UkmInfoFromProto(UkmInfoToProto(info))); +} + +TEST_F(InProgressConversionsTest, DownloadInfo) { + DownloadInfo info; + EXPECT_EQ(info, DownloadInfoFromProto(DownloadInfoToProto(info))); + + info = CreateDownloadInfo(); + EXPECT_EQ(info, DownloadInfoFromProto(DownloadInfoToProto(info))); +} + +TEST_F(InProgressConversionsTest, DownloadDBEntry) { + DownloadDBEntry entry; + EXPECT_EQ(entry, DownloadDBEntryFromProto(DownloadDBEntryToProto(entry))); + + entry.id = "abc"; + entry.download_info = CreateDownloadInfo(); + EXPECT_EQ(entry, DownloadDBEntryFromProto(DownloadDBEntryToProto(entry))); +} + } // namespace download diff --git a/chromium/components/download/downloader/in_progress/in_progress_info.cc b/chromium/components/download/downloader/in_progress/in_progress_info.cc new file mode 100644 index 00000000000..2a622e6da5f --- /dev/null +++ b/chromium/components/download/downloader/in_progress/in_progress_info.cc @@ -0,0 +1,32 @@ +// Copyright 2018 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 "components/download/downloader/in_progress/in_progress_info.h" + +namespace download { + +InProgressInfo::InProgressInfo() = default; + +InProgressInfo::InProgressInfo(const InProgressInfo& other) = default; + +InProgressInfo::~InProgressInfo() = default; + +bool InProgressInfo::operator==(const InProgressInfo& other) const { + return url_chain == other.url_chain && + fetch_error_body == other.fetch_error_body && + request_headers == other.request_headers && etag == other.etag && + last_modified == other.last_modified && + total_bytes == other.total_bytes && + current_path == other.current_path && + target_path == other.target_path && + received_bytes == other.received_bytes && end_time == other.end_time && + received_slices == other.received_slices && hash == other.hash && + transient == other.transient && state == other.state && + danger_type == other.danger_type && + interrupt_reason == other.interrupt_reason && paused == other.paused && + metered == other.metered && request_origin == other.request_origin && + bytes_wasted == other.bytes_wasted; +} + +} // namespace download diff --git a/chromium/components/download/downloader/in_progress/in_progress_info.h b/chromium/components/download/downloader/in_progress/in_progress_info.h new file mode 100644 index 00000000000..b075e9bd336 --- /dev/null +++ b/chromium/components/download/downloader/in_progress/in_progress_info.h @@ -0,0 +1,105 @@ +// Copyright 2018 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. + +#ifndef COMPONENTS_DOWNLOAD_DOWNLOADER_IN_PROGRESS_IN_PROGRESS_INFO_H_ +#define COMPONENTS_DOWNLOAD_DOWNLOADER_IN_PROGRESS_IN_PROGRESS_INFO_H_ + +#include <string> +#include <vector> + +#include "components/download/public/common/download_danger_type.h" +#include "components/download/public/common/download_item.h" +#include "components/download/public/common/download_url_parameters.h" +#include "url/gurl.h" + +namespace download { + +// Contains information to reconstruct an interrupted download item for +// resumption. +struct InProgressInfo { + public: + InProgressInfo(); + InProgressInfo(const InProgressInfo& other); + ~InProgressInfo(); + + bool operator==(const InProgressInfo& other) const; + + // request info ------------------------------------------------------------ + + // The url chain. + std::vector<GURL> url_chain; + + // If the entity body of unsuccessful HTTP response, like HTTP 404, will be + // downloaded. + bool fetch_error_body = false; + + // Request header key/value pairs that will be added to the download HTTP + // request. + DownloadUrlParameters::RequestHeadersType request_headers; + + // response info ----------------------------------------------------------- + + // Contents of most recently seen ETag header. + std::string etag; + + // Contents of most recently seen Last-Modified header. + std::string last_modified; + + // The total number of bytes in the download. + int64_t total_bytes = 0; + + // destination info -------------------------------------------------------- + + // The current path to the download (potentially different from final if + // download is in progress or interrupted). + base::FilePath current_path; + + // The target path where the download will go when it's complete. + base::FilePath target_path; + + // The number of bytes received (so far). + int64_t received_bytes = 0; + + // The time when the download completed. + base::Time end_time; + + // Data slices that have been downloaded so far. The slices must be ordered + // by their offset. + std::vector<DownloadItem::ReceivedSlice> received_slices; + + // Hash of the downloaded content. + std::string hash; + + // state info -------------------------------------------------------------- + + // Whether this download is transient. Transient items are cleaned up after + // completion and not shown in the UI. + bool transient = false; + + // The current state of the download. + DownloadItem::DownloadState state = DownloadItem::DownloadState::IN_PROGRESS; + + // Whether and how the download is dangerous. + DownloadDangerType danger_type = + DownloadDangerType::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS; + + // The reason the download was interrupted, if state == kStateInterrupted. + DownloadInterruptReason interrupt_reason = DOWNLOAD_INTERRUPT_REASON_NONE; + + // Whether this download is paused. + bool paused = false; + + // Whether the download is initiated on a metered network + bool metered = false; + + // Represents the origin information for this download. Used by offline pages. + std::string request_origin; + + // Count for how many (extra) bytes were used (including resumption). + int64_t bytes_wasted = 0; +}; + +} // namespace download + +#endif // COMPONENTS_DOWNLOAD_DOWNLOADER_IN_PROGRESS_IN_PROGRESS_INFO_H_ diff --git a/chromium/components/download/downloader/in_progress/proto/download_entry.proto b/chromium/components/download/downloader/in_progress/proto/download_entry.proto index 776b00600a4..ddf18d4a196 100644 --- a/chromium/components/download/downloader/in_progress/proto/download_entry.proto +++ b/chromium/components/download/downloader/in_progress/proto/download_entry.proto @@ -15,6 +15,13 @@ message HttpRequestHeader { optional string value = 2; } +// Slice information for parallel downloading. +message ReceivedSlice { + optional int64 offset = 1; + optional int64 received_bytes = 2; + optional bool finished = 3; +} + // Stores various in-progress metadata related to a download. message DownloadEntry { optional string guid = 1; @@ -30,3 +37,48 @@ message DownloadEntry { message DownloadEntries { repeated DownloadEntry entries = 1; } + +// Information for ukm reporting +message UkmInfo { + optional DownloadSource download_source = 1; + optional int64 ukm_download_id = 2; +} + +// Information about an in progress download. +message InProgressInfo { + repeated string url_chain = 1; + optional bool fetch_error_body = 2; + repeated HttpRequestHeader request_headers = 3; + optional string etag = 4; + optional string last_modified = 5; + optional int64 total_bytes = 6; + optional bytes current_path = 7; // Serialized pickles to support string16 + optional bytes target_path = 8; // Serialized pickles to support string16 + optional int64 received_bytes = 9; + optional int64 end_time = 10; + repeated ReceivedSlice received_slices = 11; + optional string hash = 12; + optional bool transient = 13; + optional int32 state = 14; + optional int32 danger_type = 15; + optional int32 interrupt_reason = 16; + optional bool paused = 17; + optional bool metered = 18; + optional string request_origin = 19; + optional int64 bytes_wasted = 20; +} + +// Stores various in-progress metadata related to a download. +// WIP and will replace DownloadEntry. +message DownloadInfo { + optional string guid = 1; + optional UkmInfo ukm_info = 2; + optional InProgressInfo in_progress_info = 3; +} + +// database entry for download information. +message DownloadDBEntry { + optional string id = 1; + // Add field for offline page download. + oneof entry { DownloadInfo download_info = 2; } +}
\ No newline at end of file diff --git a/chromium/components/download/downloader/in_progress/ukm_info.cc b/chromium/components/download/downloader/in_progress/ukm_info.cc new file mode 100644 index 00000000000..a02851403ac --- /dev/null +++ b/chromium/components/download/downloader/in_progress/ukm_info.cc @@ -0,0 +1,23 @@ +// Copyright 2018 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 "components/download/downloader/in_progress/ukm_info.h" + +namespace download { + +UkmInfo::UkmInfo() = default; + +UkmInfo::UkmInfo(const UkmInfo& other) = default; + +UkmInfo::UkmInfo(DownloadSource download_source, int64_t ukm_download_id) + : download_source(download_source), ukm_download_id(ukm_download_id) {} + +UkmInfo::~UkmInfo() = default; + +bool UkmInfo::operator==(const UkmInfo& other) const { + return download_source == other.download_source && + ukm_download_id == other.ukm_download_id; +} + +} // namespace download diff --git a/chromium/components/download/downloader/in_progress/ukm_info.h b/chromium/components/download/downloader/in_progress/ukm_info.h new file mode 100644 index 00000000000..ac3c73ff17d --- /dev/null +++ b/chromium/components/download/downloader/in_progress/ukm_info.h @@ -0,0 +1,34 @@ +// Copyright 2018 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. + +#ifndef COMPONENTS_DOWNLOAD_DOWNLOADER_IN_PROGRESS_UKM_INFO_H_ +#define COMPONENTS_DOWNLOAD_DOWNLOADER_IN_PROGRESS_UKM_INFO_H_ + +#include <stdint.h> + +#include "components/download/public/common/download_source.h" + +namespace download { + +// Contains information for UKM reporting. +struct UkmInfo { + public: + UkmInfo(); + UkmInfo(DownloadSource download_source, int64_t ukm_download_id); + UkmInfo(const UkmInfo& other); + ~UkmInfo(); + + bool operator==(const UkmInfo& other) const; + + // The source that triggered the download. + DownloadSource download_source = DownloadSource::UNKNOWN; + + // Unique ID that tracks the download UKM entry, where 0 means the + // download_id is not yet initialized. + uint64_t ukm_download_id = 0; +}; + +} // namespace download + +#endif // COMPONENTS_DOWNLOAD_DOWNLOADER_IN_PROGRESS_UKM_INFO_H_ |